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 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
// 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:build go1.13 && !go1.21
// +build go1.13,!go1.21
// //go:linkname directives type-checked by checklinkname. Any other
// non-linkname assumptions outside the Go 1 compatibility guarantee should
// have an accompanied vet check or version guard build tag.
// Check type definitions and constants when updating Go version.
//
// TODO(b/165820485): add these checks to checklinkname.
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, traceEv byte, traceskip int) {
gopark(unlockf, lock, reason, traceEv, traceskip)
}
//go:linkname gopark runtime.gopark
func gopark(unlockf func(uintptr, unsafe.Pointer) bool, lock unsafe.Pointer, reason uint8, traceEv byte, traceskip int)
//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()
}
}
// Values for the reason argument to gopark, from Go's src/runtime/runtime2.go.
const (
WaitReasonSelect uint8 = 9
WaitReasonChanReceive uint8 = 14
WaitReasonSemacquire uint8 = 18
)
// Values for the traceEv argument to gopark, from Go's src/runtime/trace.go.
const (
TraceEvGoBlockRecv byte = 23
TraceEvGoBlockSelect byte = 24
TraceEvGoBlockSync byte = 25
)
// 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 runtime.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()
|