github.com/sitano/gsysint@v0.0.0-20190607084937-69a4f3233e4e/gopark_test.go (about) 1 package gsysint 2 3 import ( 4 "bytes" 5 "runtime" 6 "runtime/pprof" 7 "sync" 8 "sync/atomic" 9 "testing" 10 "unsafe" 11 12 "github.com/sitano/gsysint/g" 13 "github.com/sitano/gsysint/trace" 14 ) 15 16 func TestPark(t *testing.T) { 17 t.Run("raw api park with unlock", func(t *testing.T) { 18 var gp unsafe.Pointer 19 20 w := sync.WaitGroup{} 21 w.Add(1) 22 23 l := &g.Mutex{} 24 go func() { 25 atomic.StorePointer(&gp, g.GetG()) 26 Lock(l) 27 // park 28 GoParkUnlock(l, g.WaitReasonZero, trace.TraceEvNone, 1) // actual park 29 w.Done() 30 }() 31 32 runtime.Gosched() 33 34 if gp == nil { 35 t.Fatalf("GetG() returned nil pointer to the g structure") 36 } 37 38 Lock(l) 39 // unpark goroutine and mark as ready 40 GoReady((*g.G)(gp), 1) 41 Unlock(l) 42 43 w.Wait() 44 }) 45 46 t.Run("simple api park with unlock", func(t *testing.T) { 47 var p Park 48 var m g.Mutex 49 var w sync.WaitGroup 50 51 w.Add(1) 52 go func() { 53 p.Set() 54 Lock(&m) 55 // park 56 p.ParkUnlock(&m) 57 w.Done() 58 }() 59 60 runtime.Gosched() 61 62 Lock(&m) 63 // unpark goroutine and mark as ready 64 p.Ready() 65 Unlock(&m) 66 67 w.Wait() 68 }) 69 } 70 71 func TestParkLock(t *testing.T) { 72 var gp unsafe.Pointer 73 74 go func() { 75 atomic.StorePointer(&gp, g.GetG()) 76 GoPark(func(g *g.G, p unsafe.Pointer) bool { 77 return true 78 }, nil, g.WaitReasonZero, trace.TraceEvNone, 1) 79 }() 80 81 runtime.Gosched() 82 83 stack := &bytes.Buffer{} 84 _ = pprof.Lookup("goroutine").WriteTo(stack, 1) 85 t.Log(stack.String()) 86 87 GoReady((*g.G)(gp), 1) 88 }