github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/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 // +build go1.13 7 // +build !go1.18 8 9 // Check go:linkname function signatures, type definitions, and constants when 10 // updating Go version. 11 12 package sync 13 14 import ( 15 "fmt" 16 "reflect" 17 "unsafe" 18 ) 19 20 // Gopark is runtime.gopark. Gopark calls unlockf(pointer to runtime.g, lock); 21 // if unlockf returns true, Gopark blocks until Goready(pointer to runtime.g) 22 // is called. unlockf and its callees must be nosplit and norace, since stack 23 // splitting and race context are not available where it is called. 24 // 25 //go:nosplit 26 func Gopark(unlockf func(uintptr, unsafe.Pointer) bool, lock unsafe.Pointer, reason uint8, traceEv byte, traceskip int) { 27 gopark(unlockf, lock, reason, traceEv, traceskip) 28 } 29 30 //go:linkname gopark runtime.gopark 31 func gopark(unlockf func(uintptr, unsafe.Pointer) bool, lock unsafe.Pointer, reason uint8, traceEv byte, traceskip int) 32 33 // Goready is runtime.goready. 34 // 35 //go:nosplit 36 func Goready(gp uintptr, traceskip int) { 37 goready(gp, traceskip) 38 } 39 40 //go:linkname goready runtime.goready 41 func goready(gp uintptr, traceskip int) 42 43 // Values for the reason argument to gopark, from Go's src/runtime/runtime2.go. 44 const ( 45 WaitReasonSelect uint8 = 9 46 WaitReasonChanReceive uint8 = 14 47 WaitReasonSemacquire uint8 = 18 48 ) 49 50 // Values for the traceEv argument to gopark, from Go's src/runtime/trace.go. 51 const ( 52 TraceEvGoBlockRecv byte = 23 53 TraceEvGoBlockSelect byte = 24 54 TraceEvGoBlockSync byte = 25 55 ) 56 57 // Rand32 returns a non-cryptographically-secure random uint32. 58 func Rand32() uint32 { 59 return fastrand() 60 } 61 62 // Rand64 returns a non-cryptographically-secure random uint64. 63 func Rand64() uint64 { 64 return uint64(fastrand())<<32 | uint64(fastrand()) 65 } 66 67 //go:linkname fastrand runtime.fastrand 68 func fastrand() uint32 69 70 // RandUintptr returns a non-cryptographically-secure random uintptr. 71 func RandUintptr() uintptr { 72 if unsafe.Sizeof(uintptr(0)) == 4 { 73 return uintptr(Rand32()) 74 } 75 return uintptr(Rand64()) 76 } 77 78 // MapKeyHasher returns a hash function for pointers of m's key type. 79 // 80 // Preconditions: m must be a map. 81 func MapKeyHasher(m interface{}) func(unsafe.Pointer, uintptr) uintptr { 82 if rtyp := reflect.TypeOf(m); rtyp.Kind() != reflect.Map { 83 panic(fmt.Sprintf("sync.MapKeyHasher: m is %v, not map", rtyp)) 84 } 85 mtyp := *(**maptype)(unsafe.Pointer(&m)) 86 return mtyp.hasher 87 } 88 89 // maptype is equivalent to the beginning of runtime.maptype. 90 type maptype struct { 91 size uintptr 92 ptrdata uintptr 93 hash uint32 94 tflag uint8 95 align uint8 96 fieldAlign uint8 97 kind uint8 98 equal func(unsafe.Pointer, unsafe.Pointer) bool 99 gcdata *byte 100 str int32 101 ptrToThis int32 102 key unsafe.Pointer 103 elem unsafe.Pointer 104 bucket unsafe.Pointer 105 hasher func(unsafe.Pointer, uintptr) uintptr 106 // more fields 107 } 108 109 // These functions are only used within the sync package. 110 111 //go:linkname semacquire sync.runtime_Semacquire 112 func semacquire(s *uint32) 113 114 //go:linkname semrelease sync.runtime_Semrelease 115 func semrelease(s *uint32, handoff bool, skipframes int) 116 117 //go:linkname canSpin sync.runtime_canSpin 118 func canSpin(i int) bool 119 120 //go:linkname doSpin sync.runtime_doSpin 121 func doSpin()