diff options
author | apocelipes <seve3r@outlook.com> | 2024-02-26 04:24:44 +0000 |
---|---|---|
committer | Gopher Robot <gobot@golang.org> | 2024-02-26 18:12:29 +0000 |
commit | 5bce5362da7b0fa565c88cf4c12d554a7d6b4c9d (patch) | |
tree | b70540af46d484e68a5c3ed95e2972aa442b169c /src/sync | |
parent | e596e8831885ad057a7f1db1391fddfd53f06431 (diff) | |
download | go-5bce5362da7b0fa565c88cf4c12d554a7d6b4c9d.tar.gz go-5bce5362da7b0fa565c88cf4c12d554a7d6b4c9d.zip |
sync: simplify the code with atomic.Pointer
Change-Id: I79797be6b385c9927d68350334d7f7387007085f
GitHub-Last-Rev: 3daa3b144f55f527d183d4ff35475ca4af3ee143
GitHub-Pull-Request: golang/go#65937
Reviewed-on: https://go-review.googlesource.com/c/go/+/566815
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Commit-Queue: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Diffstat (limited to 'src/sync')
-rw-r--r-- | src/sync/poolqueue.go | 29 |
1 files changed, 11 insertions, 18 deletions
diff --git a/src/sync/poolqueue.go b/src/sync/poolqueue.go index 5c640f988a..e9593f8c44 100644 --- a/src/sync/poolqueue.go +++ b/src/sync/poolqueue.go @@ -198,7 +198,7 @@ type poolChain struct { // tail is the poolDequeue to popTail from. This is accessed // by consumers, so reads and writes must be atomic. - tail *poolChainElt + tail atomic.Pointer[poolChainElt] } type poolChainElt struct { @@ -214,15 +214,7 @@ type poolChainElt struct { // prev is written atomically by the consumer and read // atomically by the producer. It only transitions from // non-nil to nil. - next, prev *poolChainElt -} - -func storePoolChainElt(pp **poolChainElt, v *poolChainElt) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(pp)), unsafe.Pointer(v)) -} - -func loadPoolChainElt(pp **poolChainElt) *poolChainElt { - return (*poolChainElt)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(pp)))) + next, prev atomic.Pointer[poolChainElt] } func (c *poolChain) pushHead(val any) { @@ -233,7 +225,7 @@ func (c *poolChain) pushHead(val any) { d = new(poolChainElt) d.vals = make([]eface, initSize) c.head = d - storePoolChainElt(&c.tail, d) + c.tail.Store(d) } if d.pushHead(val) { @@ -248,10 +240,11 @@ func (c *poolChain) pushHead(val any) { newSize = dequeueLimit } - d2 := &poolChainElt{prev: d} + d2 := &poolChainElt{} + d2.prev.Store(d) d2.vals = make([]eface, newSize) c.head = d2 - storePoolChainElt(&d.next, d2) + d.next.Store(d2) d2.pushHead(val) } @@ -263,13 +256,13 @@ func (c *poolChain) popHead() (any, bool) { } // There may still be unconsumed elements in the // previous dequeue, so try backing up. - d = loadPoolChainElt(&d.prev) + d = d.prev.Load() } return nil, false } func (c *poolChain) popTail() (any, bool) { - d := loadPoolChainElt(&c.tail) + d := c.tail.Load() if d == nil { return nil, false } @@ -281,7 +274,7 @@ func (c *poolChain) popTail() (any, bool) { // the pop and the pop fails, then d is permanently // empty, which is the only condition under which it's // safe to drop d from the chain. - d2 := loadPoolChainElt(&d.next) + d2 := d.next.Load() if val, ok := d.popTail(); ok { return val, ok @@ -297,12 +290,12 @@ func (c *poolChain) popTail() (any, bool) { // to the next dequeue. Try to drop it from the chain // so the next pop doesn't have to look at the empty // dequeue again. - if atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(&c.tail)), unsafe.Pointer(d), unsafe.Pointer(d2)) { + if c.tail.CompareAndSwap(d, d2) { // We won the race. Clear the prev pointer so // the garbage collector can collect the empty // dequeue and so popHead doesn't back up // further than necessary. - storePoolChainElt(&d2.prev, nil) + d2.prev.Store(nil) } d = d2 } |