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  }