github.com/ebitengine/purego@v0.8.0-alpha.2.0.20240512170805-6cd12240d332/internal/fakecgo/go_util.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors 3 4 //go:build !cgo && (darwin || freebsd || linux) 5 6 package fakecgo 7 8 import "unsafe" 9 10 // _cgo_thread_start is split into three parts in cgo since only one part is system dependent (keep it here for easier handling) 11 12 // _cgo_thread_start(ThreadStart *arg) (runtime/cgo/gcc_util.c) 13 // This get's called instead of the go code for creating new threads 14 // -> pthread_* stuff is used, so threads are setup correctly for C 15 // If this is missing, TLS is only setup correctly on thread 1! 16 // This function should be go:systemstack instead of go:nosplit (but that requires runtime) 17 // 18 //go:nosplit 19 //go:norace 20 func x_cgo_thread_start(arg *ThreadStart) { 21 var ts *ThreadStart 22 // Make our own copy that can persist after we return. 23 // _cgo_tsan_acquire(); 24 ts = (*ThreadStart)(malloc(unsafe.Sizeof(*ts))) 25 // _cgo_tsan_release(); 26 if ts == nil { 27 println("fakecgo: out of memory in thread_start") 28 abort() 29 } 30 // *ts = *arg would cause a writebarrier so use memmove instead 31 memmove(unsafe.Pointer(ts), unsafe.Pointer(arg), unsafe.Sizeof(*ts)) 32 _cgo_sys_thread_start(ts) // OS-dependent half 33 }