github.com/comwrg/go/src@v0.0.0-20220319063731-c238d0440370/runtime/sys_darwin_arm64.go (about)

     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  package runtime
     6  
     7  import (
     8  	"runtime/internal/sys"
     9  	"unsafe"
    10  )
    11  
    12  // libc function wrappers. Must run on system stack.
    13  
    14  //go:nosplit
    15  //go:cgo_unsafe_args
    16  func g0_pthread_key_create(k *pthreadkey, destructor uintptr) int32 {
    17  	ret := asmcgocall(unsafe.Pointer(funcPC(pthread_key_create_trampoline)), unsafe.Pointer(&k))
    18  	KeepAlive(k)
    19  	return ret
    20  }
    21  func pthread_key_create_trampoline()
    22  
    23  //go:nosplit
    24  //go:cgo_unsafe_args
    25  func g0_pthread_setspecific(k pthreadkey, value uintptr) int32 {
    26  	return asmcgocall(unsafe.Pointer(funcPC(pthread_setspecific_trampoline)), unsafe.Pointer(&k))
    27  }
    28  func pthread_setspecific_trampoline()
    29  
    30  //go:cgo_import_dynamic libc_pthread_key_create pthread_key_create "/usr/lib/libSystem.B.dylib"
    31  //go:cgo_import_dynamic libc_pthread_setspecific pthread_setspecific "/usr/lib/libSystem.B.dylib"
    32  
    33  // tlsinit allocates a thread-local storage slot for g.
    34  //
    35  // It finds the first available slot using pthread_key_create and uses
    36  // it as the offset value for runtime.tlsg.
    37  //
    38  // This runs at startup on g0 stack, but before g is set, so it must
    39  // not split stack (transitively). g is expected to be nil, so things
    40  // (e.g. asmcgocall) will skip saving or reading g.
    41  //
    42  //go:nosplit
    43  func tlsinit(tlsg *uintptr, tlsbase *[_PTHREAD_KEYS_MAX]uintptr) {
    44  	var k pthreadkey
    45  	err := g0_pthread_key_create(&k, 0)
    46  	if err != 0 {
    47  		abort()
    48  	}
    49  
    50  	const magic = 0xc476c475c47957
    51  	err = g0_pthread_setspecific(k, magic)
    52  	if err != 0 {
    53  		abort()
    54  	}
    55  
    56  	for i, x := range tlsbase {
    57  		if x == magic {
    58  			*tlsg = uintptr(i * sys.PtrSize)
    59  			g0_pthread_setspecific(k, 0)
    60  			return
    61  		}
    62  	}
    63  	abort()
    64  }