]> Cypherpunks repositories - gostls13.git/commitdiff
sync: simplify the code with atomic.Pointer
authorapocelipes <seve3r@outlook.com>
Mon, 26 Feb 2024 04:24:44 +0000 (04:24 +0000)
committerGopher Robot <gobot@golang.org>
Mon, 26 Feb 2024 18:12:29 +0000 (18:12 +0000)
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>
src/sync/poolqueue.go

index 5c640f988a39218457a6701dd2582eb7bc91c316..e9593f8c44427b907512ec0e404b127232e4a550 100644 (file)
@@ -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
        }