diff options
author | Ian Lance Taylor <iant@golang.org> | 2022-02-18 13:10:34 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2022-02-18 13:12:08 -0800 |
commit | 20a33efdf32bf0aedcb0c9813ddc7572bb1ab8c7 (patch) | |
tree | 94aec72c2092a11fa49f0b45da8e036f13416209 /libgo/go/runtime/pprof | |
parent | 1931cbad498e625b1e24452dcfffe02539b12224 (diff) | |
download | gcc-20a33efdf32bf0aedcb0c9813ddc7572bb1ab8c7.zip gcc-20a33efdf32bf0aedcb0c9813ddc7572bb1ab8c7.tar.gz gcc-20a33efdf32bf0aedcb0c9813ddc7572bb1ab8c7.tar.bz2 |
libgo: update to Go1.18rc1 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/386594
Diffstat (limited to 'libgo/go/runtime/pprof')
-rw-r--r-- | libgo/go/runtime/pprof/pprof_test.go | 67 |
1 files changed, 49 insertions, 18 deletions
diff --git a/libgo/go/runtime/pprof/pprof_test.go b/libgo/go/runtime/pprof/pprof_test.go index def49c1..983d4d4 100644 --- a/libgo/go/runtime/pprof/pprof_test.go +++ b/libgo/go/runtime/pprof/pprof_test.go @@ -798,7 +798,7 @@ func TestBlockProfile(t *testing.T) { t.Skip("lots of details are different for gccgo; FIXME") type TestCase struct { name string - f func() + f func(*testing.T) stk []string re string } @@ -907,7 +907,7 @@ func TestBlockProfile(t *testing.T) { runtime.SetBlockProfileRate(1) defer runtime.SetBlockProfileRate(0) for _, test := range tests { - test.f() + test.f(t) } t.Run("debug=1", func(t *testing.T) { @@ -983,42 +983,73 @@ func containsStack(got [][]string, want []string) bool { return false } -const blockDelay = 10 * time.Millisecond +// awaitBlockedGoroutine spins on runtime.Gosched until a runtime stack dump +// shows a goroutine in the given state with a stack frame in +// runtime/pprof.<fName>. +func awaitBlockedGoroutine(t *testing.T, state, fName string) { + re := fmt.Sprintf(`(?m)^goroutine \d+ \[%s\]:\n(?:.+\n\t.+\n)*runtime/pprof\.%s`, regexp.QuoteMeta(state), fName) + r := regexp.MustCompile(re) -func blockChanRecv() { + if deadline, ok := t.Deadline(); ok { + if d := time.Until(deadline); d > 1*time.Second { + timer := time.AfterFunc(d-1*time.Second, func() { + debug.SetTraceback("all") + panic(fmt.Sprintf("timed out waiting for %#q", re)) + }) + defer timer.Stop() + } + } + + buf := make([]byte, 64<<10) + for { + runtime.Gosched() + n := runtime.Stack(buf, true) + if n == len(buf) { + // Buffer wasn't large enough for a full goroutine dump. + // Resize it and try again. + buf = make([]byte, 2*len(buf)) + continue + } + if r.Match(buf[:n]) { + return + } + } +} + +func blockChanRecv(t *testing.T) { c := make(chan bool) go func() { - time.Sleep(blockDelay) + awaitBlockedGoroutine(t, "chan receive", "blockChanRecv") c <- true }() <-c } -func blockChanSend() { +func blockChanSend(t *testing.T) { c := make(chan bool) go func() { - time.Sleep(blockDelay) + awaitBlockedGoroutine(t, "chan send", "blockChanSend") <-c }() c <- true } -func blockChanClose() { +func blockChanClose(t *testing.T) { c := make(chan bool) go func() { - time.Sleep(blockDelay) + awaitBlockedGoroutine(t, "chan receive", "blockChanClose") close(c) }() <-c } -func blockSelectRecvAsync() { +func blockSelectRecvAsync(t *testing.T) { const numTries = 3 c := make(chan bool, 1) c2 := make(chan bool, 1) go func() { for i := 0; i < numTries; i++ { - time.Sleep(blockDelay) + awaitBlockedGoroutine(t, "select", "blockSelectRecvAsync") c <- true } }() @@ -1030,11 +1061,11 @@ func blockSelectRecvAsync() { } } -func blockSelectSendSync() { +func blockSelectSendSync(t *testing.T) { c := make(chan bool) c2 := make(chan bool) go func() { - time.Sleep(blockDelay) + awaitBlockedGoroutine(t, "select", "blockSelectSendSync") <-c }() select { @@ -1043,11 +1074,11 @@ func blockSelectSendSync() { } } -func blockMutex() { +func blockMutex(t *testing.T) { var mu sync.Mutex mu.Lock() go func() { - time.Sleep(blockDelay) + awaitBlockedGoroutine(t, "semacquire", "blockMutex") mu.Unlock() }() // Note: Unlock releases mu before recording the mutex event, @@ -1057,12 +1088,12 @@ func blockMutex() { mu.Lock() } -func blockCond() { +func blockCond(t *testing.T) { var mu sync.Mutex c := sync.NewCond(&mu) mu.Lock() go func() { - time.Sleep(blockDelay) + awaitBlockedGoroutine(t, "sync.Cond.Wait", "blockCond") mu.Lock() c.Signal() mu.Unlock() @@ -1148,7 +1179,7 @@ func TestMutexProfile(t *testing.T) { t.Fatalf("need MutexProfileRate 0, got %d", old) } - blockMutex() + blockMutex(t) t.Run("debug=1", func(t *testing.T) { var w bytes.Buffer |