aboutsummaryrefslogtreecommitdiff
path: root/src/sync
diff options
context:
space:
mode:
authorapocelipes <seve3r@outlook.com>2024-02-26 04:24:44 +0000
committerGopher Robot <gobot@golang.org>2024-02-26 18:12:29 +0000
commit5bce5362da7b0fa565c88cf4c12d554a7d6b4c9d (patch)
treeb70540af46d484e68a5c3ed95e2972aa442b169c /src/sync
parente596e8831885ad057a7f1db1391fddfd53f06431 (diff)
downloadgo-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.go29
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
}