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
|
// 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.
// +build go1.13
// +build !go1.18
// Check go:linkname function signatures, type definitions, and constants when
// updating Go version.
package sync
import (
"fmt"
"reflect"
"unsafe"
)
// Note that go:linkname silently doesn't work if the local name is exported,
// necessitating an indirection for exported functions.
// Memmove is runtime.memmove, exported for SeqAtomicLoad/SeqAtomicTryLoad<T>.
//
//go:nosplit
func Memmove(to, from unsafe.Pointer, n uintptr) {
memmove(to, from, n)
}
//go:linkname memmove runtime.memmove
//go:noescape
func memmove(to, from unsafe.Pointer, n uintptr)
// 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)
// Goready is runtime.goready.
//
//go:nosplit
func Goready(gp uintptr, traceskip int) {
goready(gp, traceskip)
}
//go:linkname goready runtime.goready
func goready(gp uintptr, traceskip int)
// 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 interface{}) 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(s *uint32)
//go:linkname semrelease sync.runtime_Semrelease
func semrelease(s *uint32, handoff bool, skipframes int)
//go:linkname canSpin sync.runtime_canSpin
func canSpin(i int) bool
//go:linkname doSpin sync.runtime_doSpin
func doSpin()
|