diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-09-12 23:22:53 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-09-12 23:22:53 +0000 |
commit | 656297e1fec9a127ff742df16958ee279ccacec5 (patch) | |
tree | 24347a35dacea36ce742c32c17420f3e31f17e3d /libgo/go/sync | |
parent | d6ecb707cc5a58816d27908a7aa324c4b0bc67bb (diff) | |
download | gcc-656297e1fec9a127ff742df16958ee279ccacec5.zip gcc-656297e1fec9a127ff742df16958ee279ccacec5.tar.gz gcc-656297e1fec9a127ff742df16958ee279ccacec5.tar.bz2 |
libgo: update to Go1.13
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194698
From-SVN: r275691
Diffstat (limited to 'libgo/go/sync')
-rw-r--r-- | libgo/go/sync/export_test.go | 6 | ||||
-rw-r--r-- | libgo/go/sync/once.go | 14 | ||||
-rw-r--r-- | libgo/go/sync/pool_test.go | 27 |
3 files changed, 34 insertions, 13 deletions
diff --git a/libgo/go/sync/export_test.go b/libgo/go/sync/export_test.go index 10d3599..ffbe567 100644 --- a/libgo/go/sync/export_test.go +++ b/libgo/go/sync/export_test.go @@ -18,9 +18,13 @@ type PoolDequeue interface { } func NewPoolDequeue(n int) PoolDequeue { - return &poolDequeue{ + d := &poolDequeue{ vals: make([]eface, n), } + // For testing purposes, set the head and tail indexes close + // to wrapping around. + d.headTail = d.pack(1<<dequeueBits-500, 1<<dequeueBits-500) + return d } func (d *poolDequeue) PushHead(val interface{}) bool { diff --git a/libgo/go/sync/once.go b/libgo/go/sync/once.go index 8476197..ca04408 100644 --- a/libgo/go/sync/once.go +++ b/libgo/go/sync/once.go @@ -38,6 +38,20 @@ type Once struct { // without calling f. // func (o *Once) Do(f func()) { + // Note: Here is an incorrect implementation of Do: + // + // if atomic.CompareAndSwapUint32(&o.done, 0, 1) { + // f() + // } + // + // Do guarantees that when it returns, f has finished. + // This implementation would not implement that guarantee: + // given two simultaneous calls, the winner of the cas would + // call f, and the second would return immediately, without + // waiting for the first's call to f to complete. + // This is why the slow path falls back to a mutex, and why + // the atomic.StoreUint32 must be delayed until after f returns. + if atomic.LoadUint32(&o.done) == 0 { // Outlined slow-path to allow inlining of the fast-path. o.doSlow(f) diff --git a/libgo/go/sync/pool_test.go b/libgo/go/sync/pool_test.go index 7e175a9..c67bd8c 100644 --- a/libgo/go/sync/pool_test.go +++ b/libgo/go/sync/pool_test.go @@ -174,15 +174,19 @@ func TestPoolChain(t *testing.T) { func testPoolDequeue(t *testing.T, d PoolDequeue) { const P = 10 - // In long mode, do enough pushes to wrap around the 21-bit - // indexes. - N := 1<<21 + 1000 + var N int = 2e6 if testing.Short() { N = 1e3 } have := make([]int32, N) var stop int32 var wg WaitGroup + record := func(val int) { + atomic.AddInt32(&have[val], 1) + if val == N-1 { + atomic.StoreInt32(&stop, 1) + } + } // Start P-1 consumers. for i := 1; i < P; i++ { @@ -193,10 +197,7 @@ func testPoolDequeue(t *testing.T, d PoolDequeue) { val, ok := d.PopTail() if ok { fail = 0 - atomic.AddInt32(&have[val.(int)], 1) - if val.(int) == N-1 { - atomic.StoreInt32(&stop, 1) - } + record(val.(int)) } else { // Speed up the test by // allowing the pusher to run. @@ -222,7 +223,7 @@ func testPoolDequeue(t *testing.T, d PoolDequeue) { val, ok := d.PopHead() if ok { nPopHead++ - atomic.AddInt32(&have[val.(int)], 1) + record(val.(int)) } } } @@ -236,10 +237,12 @@ func testPoolDequeue(t *testing.T, d PoolDequeue) { t.Errorf("expected have[%d] = 1, got %d", i, count) } } - if nPopHead == 0 { - // In theory it's possible in a valid schedule for - // popHead to never succeed, but in practice it almost - // always succeeds, so this is unlikely to flake. + // Check that at least some PopHeads succeeded. We skip this + // check in short mode because it's common enough that the + // queue will stay nearly empty all the time and a PopTail + // will happen during the window between every PushHead and + // PopHead. + if !testing.Short() && nPopHead == 0 { t.Errorf("popHead never succeeded") } } |