// Copyright 2026 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build 386 || amd64 || arm || arm64 || loong64 || ppc64 || ppc64le || riscv64 || s390x package runtime import ( "internal/abi" "unsafe" ) // rt0LibGoFn holds the function pointer to rt0_lib_go suitable for thread // creation. On most platforms it is zero, meaning the raw code address should // be used. On AIX it is set by libpreinit to a function descriptor pointer, // because pthread_create on AIX expects a function descriptor, not a raw // code address. var rt0LibGoFn uintptr // libInit is common startup code for most architectures when // using -buildmode=c-archive or -buildmode=c-shared. // // May run with m.p==nil, so write barriers are not allowed. // //go:nowritebarrierrec //go:nosplit func libInit() { // Synchronous initialization. libpreinit() // Use the platform-specific function pointer if set (e.g. AIX // function descriptor), otherwise fall back to the raw code address. fn := unsafe.Pointer(rt0LibGoFn) if fn == nil { fn = unsafe.Pointer(abi.FuncPCABIInternal(rt0_lib_go)) } // Asynchronous initialization. // Prefer creating a thread via cgo if it is available. if _cgo_sys_thread_create != nil { // No g because the TLS is not set up until later in rt0_go. asmcgocall_no_g(_cgo_sys_thread_create, fn) } else { const stackSize = 0x800000 // 8192KB newosproc0(stackSize, fn) } }