github.com/jwijenbergh/purego@v0.0.0-20240126093400-70ff3a61df13/internal/fakecgo/go_darwin_amd64.go (about) 1 // Copyright 2011 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 package fakecgo 6 7 import "unsafe" 8 9 //go:nosplit 10 //go:norace 11 func _cgo_sys_thread_start(ts *ThreadStart) { 12 var attr pthread_attr_t 13 var ign, oset sigset_t 14 var p pthread_t 15 var size size_t 16 var err int 17 18 sigfillset(&ign) 19 pthread_sigmask(SIG_SETMASK, &ign, &oset) 20 21 size = pthread_get_stacksize_np(pthread_self()) 22 pthread_attr_init(&attr) 23 pthread_attr_setstacksize(&attr, size) 24 // Leave stacklo=0 and set stackhi=size; mstart will do the rest. 25 ts.g.stackhi = uintptr(size) 26 27 err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts) 28 29 pthread_sigmask(SIG_SETMASK, &oset, nil) 30 31 if err != 0 { 32 print("fakecgo: pthread_create failed: ") 33 println(err) 34 abort() 35 } 36 } 37 38 // threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function 39 // 40 //go:linkname x_threadentry_trampoline threadentry_trampoline 41 var x_threadentry_trampoline byte 42 var threadentry_trampolineABI0 = &x_threadentry_trampoline 43 44 //go:nosplit 45 //go:norace 46 func threadentry(v unsafe.Pointer) unsafe.Pointer { 47 ts := *(*ThreadStart)(v) 48 free(v) 49 50 setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g))) 51 52 // faking funcs in go is a bit a... involved - but the following works :) 53 fn := uintptr(unsafe.Pointer(&ts.fn)) 54 (*(*func())(unsafe.Pointer(&fn)))() 55 56 return nil 57 } 58 59 // here we will store a pointer to the provided setg func 60 var setg_func uintptr 61 62 //go:nosplit 63 //go:norace 64 func x_cgo_init(g *G, setg uintptr) { 65 var size size_t 66 67 setg_func = setg 68 69 size = pthread_get_stacksize_np(pthread_self()) 70 g.stacklo = uintptr(unsafe.Add(unsafe.Pointer(&size), -size+4096)) 71 }