inet.af/netstack@v0.0.0-20220214151720-7585b01ddccf/sync/runtime_unsafe.go (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 //go:build go1.13 && !go1.19 7 // +build go1.13,!go1.19 8 9 // //go:linkname directives type-checked by checklinkname. Any other 10 // non-linkname assumptions outside the Go 1 compatibility guarantee should 11 // have an accompanied vet check or version guard build tag. 12 13 // Check type definitions and constants when updating Go version. 14 // 15 // TODO(b/165820485): add these checks to checklinkname. 16 17 package sync 18 19 import ( 20 "fmt" 21 "reflect" 22 "unsafe" 23 ) 24 25 // Gopark is runtime.gopark. Gopark calls unlockf(pointer to runtime.g, lock); 26 // if unlockf returns true, Gopark blocks until Goready(pointer to runtime.g) 27 // is called. unlockf and its callees must be nosplit and norace, since stack 28 // splitting and race context are not available where it is called. 29 // 30 //go:nosplit 31 func Gopark(unlockf func(uintptr, unsafe.Pointer) bool, lock unsafe.Pointer, reason uint8, traceEv byte, traceskip int) { 32 gopark(unlockf, lock, reason, traceEv, traceskip) 33 } 34 35 //go:linkname gopark runtime.gopark 36 func gopark(unlockf func(uintptr, unsafe.Pointer) bool, lock unsafe.Pointer, reason uint8, traceEv byte, traceskip int) 37 38 // Goready is runtime.goready. 39 // 40 //go:nosplit 41 func Goready(gp uintptr, traceskip int) { 42 goready(gp, traceskip) 43 } 44 45 //go:linkname goready runtime.goready 46 func goready(gp uintptr, traceskip int) 47 48 // Values for the reason argument to gopark, from Go's src/runtime/runtime2.go. 49 const ( 50 WaitReasonSelect uint8 = 9 51 WaitReasonChanReceive uint8 = 14 52 WaitReasonSemacquire uint8 = 18 53 ) 54 55 // Values for the traceEv argument to gopark, from Go's src/runtime/trace.go. 56 const ( 57 TraceEvGoBlockRecv byte = 23 58 TraceEvGoBlockSelect byte = 24 59 TraceEvGoBlockSync byte = 25 60 ) 61 62 // Rand32 returns a non-cryptographically-secure random uint32. 63 func Rand32() uint32 { 64 return fastrand() 65 } 66 67 // Rand64 returns a non-cryptographically-secure random uint64. 68 func Rand64() uint64 { 69 return uint64(fastrand())<<32 | uint64(fastrand()) 70 } 71 72 //go:linkname fastrand runtime.fastrand 73 func fastrand() uint32 74 75 // RandUintptr returns a non-cryptographically-secure random uintptr. 76 func RandUintptr() uintptr { 77 if unsafe.Sizeof(uintptr(0)) == 4 { 78 return uintptr(Rand32()) 79 } 80 return uintptr(Rand64()) 81 } 82 83 // MapKeyHasher returns a hash function for pointers of m's key type. 84 // 85 // Preconditions: m must be a map. 86 func MapKeyHasher(m interface{}) func(unsafe.Pointer, uintptr) uintptr { 87 if rtyp := reflect.TypeOf(m); rtyp.Kind() != reflect.Map { 88 panic(fmt.Sprintf("sync.MapKeyHasher: m is %v, not map", rtyp)) 89 } 90 mtyp := *(**maptype)(unsafe.Pointer(&m)) 91 return mtyp.hasher 92 } 93 94 // maptype is equivalent to the beginning of runtime.maptype. 95 type maptype struct { 96 size uintptr 97 ptrdata uintptr 98 hash uint32 99 tflag uint8 100 align uint8 101 fieldAlign uint8 102 kind uint8 103 equal func(unsafe.Pointer, unsafe.Pointer) bool 104 gcdata *byte 105 str int32 106 ptrToThis int32 107 key unsafe.Pointer 108 elem unsafe.Pointer 109 bucket unsafe.Pointer 110 hasher func(unsafe.Pointer, uintptr) uintptr 111 // more fields 112 } 113 114 // These functions are only used within the sync package. 115 116 //go:linkname semacquire sync.runtime_Semacquire 117 func semacquire(addr *uint32) 118 119 //go:linkname semrelease sync.runtime_Semrelease 120 func semrelease(addr *uint32, handoff bool, skipframes int) 121 122 //go:linkname canSpin sync.runtime_canSpin 123 func canSpin(i int) bool 124 125 //go:linkname doSpin sync.runtime_doSpin 126 func doSpin()