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