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)