1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
// Copyright 2020 The gVisor Authors.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// //go:linkname directives type-checked by checklinkname.
// Runtime type copies checked by checkoffset.
package sync
import (
"fmt"
"reflect"
"unsafe"
)
// Goyield is runtime.goyield, which is similar to runtime.Gosched but only
// yields the processor to other goroutines already on the processor's
// runqueue.
//
//go:nosplit
func Goyield() {
goyield()
}
// Gopark is runtime.gopark. Gopark calls unlockf(pointer to runtime.g, lock);
// if unlockf returns true, Gopark blocks until Goready(pointer to runtime.g)
// is called. unlockf and its callees must be nosplit and norace, since stack
// splitting and race context are not available where it is called.
//
//go:nosplit
func Gopark(unlockf func(uintptr, unsafe.Pointer) bool, lock unsafe.Pointer, reason uint8, traceReason TraceBlockReason, traceskip int) {
gopark(unlockf, lock, reason, traceReason, traceskip)
}
//go:linkname gopark runtime.gopark
func gopark(unlockf func(uintptr, unsafe.Pointer) bool, lock unsafe.Pointer, reason uint8, traceReason TraceBlockReason, traceskip int)
// TraceBlockReason is equivalent to runtime.traceBlockReason.
type TraceBlockReason uint8
//go:linkname wakep runtime.wakep
func wakep()
// Wakep is runtime.wakep.
//
//go:nosplit
func Wakep() {
// This is only supported if we can suppress the wakep called
// from Goready below, which is in certain architectures only.
if supportsWakeSuppression {
wakep()
}
}
//go:linkname goready runtime.goready
func goready(gp uintptr, traceskip int)
// Goready is runtime.goready.
//
// The additional wakep argument controls whether a new thread will be kicked to
// execute the P. This should be true in most circumstances. However, if the
// current thread is about to sleep, then this can be false for efficiency.
//
//go:nosplit
func Goready(gp uintptr, traceskip int, wakep bool) {
if supportsWakeSuppression && !wakep {
preGoReadyWakeSuppression()
}
goready(gp, traceskip)
if supportsWakeSuppression && !wakep {
postGoReadyWakeSuppression()
}
}
// Rand32 returns a non-cryptographically-secure random uint32.
func Rand32() uint32 {
return fastrand()
}
// Rand64 returns a non-cryptographically-secure random uint64.
func Rand64() uint64 {
return uint64(fastrand())<<32 | uint64(fastrand())
}
//go:linkname fastrand runtime.fastrand
func fastrand() uint32
// RandUintptr returns a non-cryptographically-secure random uintptr.
func RandUintptr() uintptr {
if unsafe.Sizeof(uintptr(0)) == 4 {
return uintptr(Rand32())
}
return uintptr(Rand64())
}
// MapKeyHasher returns a hash function for pointers of m's key type.
//
// Preconditions: m must be a map.
func MapKeyHasher(m any) func(unsafe.Pointer, uintptr) uintptr {
if rtyp := reflect.TypeOf(m); rtyp.Kind() != reflect.Map {
panic(fmt.Sprintf("sync.MapKeyHasher: m is %v, not map", rtyp))
}
mtyp := *(**maptype)(unsafe.Pointer(&m))
return mtyp.Hasher
}
// maptype is equivalent to the beginning of internal/abi.MapType.
type maptype struct {
size uintptr
ptrdata uintptr
hash uint32
tflag uint8
align uint8
fieldAlign uint8
kind uint8
equal func(unsafe.Pointer, unsafe.Pointer) bool
gcdata *byte
str int32
ptrToThis int32
key unsafe.Pointer
elem unsafe.Pointer
bucket unsafe.Pointer
Hasher func(unsafe.Pointer, uintptr) uintptr
// more fields
}
// These functions are only used within the sync package.
//go:linkname semacquire sync.runtime_Semacquire
func semacquire(addr *uint32)
//go:linkname semrelease sync.runtime_Semrelease
func semrelease(addr *uint32, handoff bool, skipframes int)
//go:linkname canSpin sync.runtime_canSpin
func canSpin(i int) bool
//go:linkname doSpin sync.runtime_doSpin
func doSpin()
|