aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/sync
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-09-12 23:22:53 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-09-12 23:22:53 +0000
commit656297e1fec9a127ff742df16958ee279ccacec5 (patch)
tree24347a35dacea36ce742c32c17420f3e31f17e3d /libgo/go/sync
parentd6ecb707cc5a58816d27908a7aa324c4b0bc67bb (diff)
downloadgcc-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.go6
-rw-r--r--libgo/go/sync/once.go14
-rw-r--r--libgo/go/sync/pool_test.go27
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")
}
}