From: Michael Munday Date: Sun, 13 May 2018 07:13:56 +0000 (+0100) Subject: sync: deflake TestWaitGroupMisuse2 X-Git-Tag: go1.11beta1~428 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=b7f3c178a337b41c78a38dc3223304d69ec592f7;p=gostls13.git 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 TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- 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 {