...

Source file src/runtime/sys_darwin_arm64.go

Documentation: runtime

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

View as plain text