1// Copyright 2020 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build openbsd && !mips64
6
7package runtime
8
9import (
10	"internal/abi"
11	"unsafe"
12)
13
14// mstart_stub provides glue code to call mstart from pthread_create.
15func mstart_stub()
16
17// May run with m.p==nil, so write barriers are not allowed.
18//
19//go:nowritebarrierrec
20func newosproc(mp *m) {
21	if false {
22		print("newosproc m=", mp, " g=", mp.g0, " id=", mp.id, " ostk=", &mp, "\n")
23	}
24
25	// Initialize an attribute object.
26	var attr pthreadattr
27	if err := pthread_attr_init(&attr); err != 0 {
28		writeErrStr(failthreadcreate)
29		exit(1)
30	}
31
32	// Find out OS stack size for our own stack guard.
33	var stacksize uintptr
34	if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
35		writeErrStr(failthreadcreate)
36		exit(1)
37	}
38	mp.g0.stack.hi = stacksize // for mstart
39
40	// Tell the pthread library we won't join with this thread.
41	if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
42		writeErrStr(failthreadcreate)
43		exit(1)
44	}
45
46	// Finally, create the thread. It starts at mstart_stub, which does some low-level
47	// setup and then calls mstart.
48	var oset sigset
49	sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
50	err := retryOnEAGAIN(func() int32 {
51		return pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
52	})
53	sigprocmask(_SIG_SETMASK, &oset, nil)
54	if err != 0 {
55		writeErrStr(failthreadcreate)
56		exit(1)
57	}
58
59	pthread_attr_destroy(&attr)
60}
61