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  }