diff options
author | Michael Munday <mike.munday@ibm.com> | 2018-05-13 08:13:56 +0100 |
---|---|---|
committer | Brad Fitzpatrick <bradfitz@golang.org> | 2018-05-14 04:42:45 +0000 |
commit | b7f3c178a337b41c78a38dc3223304d69ec592f7 (patch) | |
tree | 0e7650479dd19a259b1e070c757f72e34a143501 /src/sync | |
parent | 91f07c57d891e3ac1450bd4295de462c23bffb69 (diff) | |
download | go-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')
-rw-r--r-- | src/sync/waitgroup_test.go | 27 |
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 { |