diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
commit | 73df946d56c74384511a194dd01dbe099584fd1a (patch) | |
tree | fd0bcea490dd81327ddfbb31e215439672c9a068 /src/runtime/sys_darwin_arm64.go | |
parent | Initial commit. (diff) | |
download | golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.tar.xz golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.zip |
Adding upstream version 1.16.10.upstream/1.16.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/runtime/sys_darwin_arm64.go')
-rw-r--r-- | src/runtime/sys_darwin_arm64.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/runtime/sys_darwin_arm64.go b/src/runtime/sys_darwin_arm64.go new file mode 100644 index 0000000..9c14f33 --- /dev/null +++ b/src/runtime/sys_darwin_arm64.go @@ -0,0 +1,62 @@ +// Copyright 2020 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. + +package runtime + +import ( + "runtime/internal/sys" + "unsafe" +) + +// libc function wrappers. Must run on system stack. + +//go:nosplit +//go:cgo_unsafe_args +func g0_pthread_key_create(k *pthreadkey, destructor uintptr) int32 { + return asmcgocall(unsafe.Pointer(funcPC(pthread_key_create_trampoline)), unsafe.Pointer(&k)) +} +func pthread_key_create_trampoline() + +//go:nosplit +//go:cgo_unsafe_args +func g0_pthread_setspecific(k pthreadkey, value uintptr) int32 { + return asmcgocall(unsafe.Pointer(funcPC(pthread_setspecific_trampoline)), unsafe.Pointer(&k)) +} +func pthread_setspecific_trampoline() + +//go:cgo_import_dynamic libc_pthread_key_create pthread_key_create "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic libc_pthread_setspecific pthread_setspecific "/usr/lib/libSystem.B.dylib" + +// tlsinit allocates a thread-local storage slot for g. +// +// It finds the first available slot using pthread_key_create and uses +// it as the offset value for runtime.tlsg. +// +// This runs at startup on g0 stack, but before g is set, so it must +// not split stack (transitively). g is expected to be nil, so things +// (e.g. asmcgocall) will skip saving or reading g. +// +//go:nosplit +func tlsinit(tlsg *uintptr, tlsbase *[_PTHREAD_KEYS_MAX]uintptr) { + var k pthreadkey + err := g0_pthread_key_create(&k, 0) + if err != 0 { + abort() + } + + const magic = 0xc476c475c47957 + err = g0_pthread_setspecific(k, magic) + if err != 0 { + abort() + } + + for i, x := range tlsbase { + if x == magic { + *tlsg = uintptr(i * sys.PtrSize) + g0_pthread_setspecific(k, 0) + return + } + } + abort() +} |