Black Lives Matter. Support the Equal Justice Initiative.

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

View as plain text