github.com/sitano/gsysint@v0.0.0-20190607084937-69a4f3233e4e/gopark.go (about)

     1  package gsysint
     2  
     3  import (
     4  	"sync/atomic"
     5  	"unsafe"
     6  
     7  	"github.com/sitano/gsysint/trace"
     8  	"github.com/sitano/gsysint/g"
     9  )
    10  
    11  type Park struct {
    12  	g unsafe.Pointer
    13  }
    14  
    15  func NewPark() Park {
    16  	return Park{}
    17  }
    18  
    19  func (p *Park) Set() {
    20  	atomic.StorePointer(&p.g, g.GetG())
    21  }
    22  
    23  func (p *Park) Ptr() unsafe.Pointer {
    24  	return atomic.LoadPointer(&p.g)
    25  }
    26  
    27  // GoPark puts the current goroutine into a waiting state and calls unlockf.
    28  func (p *Park) Park(m *g.Mutex) {
    29  	GoPark(func(g *g.G, p unsafe.Pointer) bool { return true }, unsafe.Pointer(m), g.WaitReasonZero, trace.TraceEvNone, 1)
    30  }
    31  
    32  // GoParkUnlock puts the current goroutine into a waiting state and unlocks the lock.
    33  // The goroutine can be made runnable again by calling goready(gp).
    34  func (p *Park) ParkUnlock(m *g.Mutex) {
    35  	GoParkUnlock(m, g.WaitReasonZero, trace.TraceEvNone, 1)
    36  }
    37  
    38  // GoReady marks gp is ready to run.
    39  func (p *Park) Ready() {
    40  	GoReady((*g.G)(p.g), 1)
    41  }
    42  
    43  // GoPark puts the current goroutine into a waiting state and calls unlockf.
    44  // If unlockf returns false, the goroutine is resumed.
    45  // unlockf must not access this G's stack, as it may be moved between
    46  // the call to gopark and the call to unlockf.
    47  // Reason explains why the goroutine has been parked.
    48  // It is displayed in stack traces and heap dumps.
    49  // Reasons should be unique and descriptive.
    50  // Do not re-use reasons, add new ones.
    51  // Lock is g.Mutex spin mutex.
    52  //go:linkname GoPark runtime.gopark
    53  func GoPark(unlockf func(*g.G, unsafe.Pointer) bool, lock unsafe.Pointer, reason g.WaitReason, traceEv byte, traceskip int)
    54  
    55  // ParkUnlock_c puts the current goroutine into a waiting state and unlocks the lock.
    56  // The goroutine can be made runnable again by calling goready(gp).
    57  
    58  //go:linkname ParkUnlock_c runtime.parkunlock_c
    59  func ParkUnlock_c(gp *g.G, lock unsafe.Pointer) bool
    60  
    61  // GoParkUnlock puts the current goroutine into a waiting state and unlocks the lock.
    62  // The goroutine can be made runnable again by calling goready(gp).
    63  //
    64  // Implementation:
    65  // - gopark(parkunlock_c, unsafe.Pointer(lock), reason, traceEv, traceskip)
    66  //
    67  //go:linkname GoParkUnlock runtime.goparkunlock
    68  func GoParkUnlock(lock *g.Mutex, reason g.WaitReason, traceEv byte, traceskip int)
    69  
    70  // GoReady marks gp is ready to run.
    71  // Implementation:
    72  // systemstack(func() {
    73  //   ready(gp, traceskip, true)
    74  // })
    75  //go:linkname GoReady runtime.goready
    76  func GoReady(gp *g.G, traceskip int)