aboutsummaryrefslogtreecommitdiff
path: root/src/sync/waitgroup_test.go
diff options
context:
space:
mode:
authorMichael Munday <mike.munday@ibm.com>2018-05-13 08:13:56 +0100
committerBrad Fitzpatrick <bradfitz@golang.org>2018-05-14 04:42:45 +0000
commitb7f3c178a337b41c78a38dc3223304d69ec592f7 (patch)
tree0e7650479dd19a259b1e070c757f72e34a143501 /src/sync/waitgroup_test.go
parent91f07c57d891e3ac1450bd4295de462c23bffb69 (diff)
downloadgo-b7f3c178a337b41c78a38dc3223304d69ec592f7.tar.gz
go-b7f3c178a337b41c78a38dc3223304d69ec592f7.zip
sync: deflake TestWaitGroupMisuse2
We need to yield to the runtime every now and again to avoid deadlock. This doesn't show up on most machines because the test only runs when you have 5 or more CPUs. Fixes #20072. Change-Id: Ibf5ed370e919943395f3418487188df0b2be160b Reviewed-on: https://go-review.googlesource.com/112978 Run-TryBot: Michael Munday <mike.munday@ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/sync/waitgroup_test.go')
-rw-r--r--src/sync/waitgroup_test.go27
1 files changed, 18 insertions, 9 deletions
diff --git a/src/sync/waitgroup_test.go b/src/sync/waitgroup_test.go
index e3e3096645..4ab438cbab 100644
--- a/src/sync/waitgroup_test.go
+++ b/src/sync/waitgroup_test.go
@@ -68,6 +68,21 @@ func TestWaitGroupMisuse(t *testing.T) {
t.Fatal("Should panic")
}
+// pollUntilEqual blocks until v, loaded atomically, is
+// equal to the target.
+func pollUntilEqual(v *uint32, target uint32) {
+ for {
+ for i := 0; i < 1e3; i++ {
+ if atomic.LoadUint32(v) == target {
+ return
+ }
+ }
+ // yield to avoid deadlock with the garbage collector
+ // see issue #20072
+ runtime.Gosched()
+ }
+}
+
func TestWaitGroupMisuse2(t *testing.T) {
knownRacy(t)
if runtime.NumCPU() <= 4 {
@@ -94,9 +109,7 @@ func TestWaitGroupMisuse2(t *testing.T) {
done <- recover()
}()
atomic.AddUint32(&here, 1)
- for atomic.LoadUint32(&here) != 3 {
- // spin
- }
+ pollUntilEqual(&here, 3)
wg.Wait()
}()
go func() {
@@ -104,16 +117,12 @@ func TestWaitGroupMisuse2(t *testing.T) {
done <- recover()
}()
atomic.AddUint32(&here, 1)
- for atomic.LoadUint32(&here) != 3 {
- // spin
- }
+ pollUntilEqual(&here, 3)
wg.Add(1) // This is the bad guy.
wg.Done()
}()
atomic.AddUint32(&here, 1)
- for atomic.LoadUint32(&here) != 3 {
- // spin
- }
+ pollUntilEqual(&here, 3)
wg.Done()
for j := 0; j < 2; j++ {
if err := <-done; err != nil {