]> Cypherpunks repositories - gostls13.git/commitdiff
all: make more use of the new atomic integer types
authorDaniel Martí <mvdan@mvdan.cc>
Sun, 12 Nov 2023 10:04:15 +0000 (10:04 +0000)
committerDaniel Martí <mvdan@mvdan.cc>
Fri, 17 Nov 2023 16:39:52 +0000 (16:39 +0000)
Slightly simplifies the code and avoids human error.

Change-Id: Ib76575e8bc5b3a699ba6cc3870d63cd7a55e6416
Reviewed-on: https://go-review.googlesource.com/c/go/+/541476
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
src/cmd/compile/internal/types2/typeparam.go
src/cmd/go/internal/trace/trace.go
src/expvar/expvar.go
src/go/types/typeparam.go
src/internal/fuzz/pcg.go
src/sync/export_test.go
src/sync/poolqueue.go
src/testing/benchmark.go

index 42b1a63915330be8b2e562f06e63360f1473fb71..5c6030b3fbb57fdd123d71e0232467688fbf0516 100644 (file)
@@ -9,11 +9,11 @@ import "sync/atomic"
 // Note: This is a uint32 rather than a uint64 because the
 // respective 64 bit atomic instructions are not available
 // on all platforms.
-var lastID uint32
+var lastID atomic.Uint32
 
 // nextID returns a value increasing monotonically by 1 with
 // each call, starting with 1. It may be called concurrently.
-func nextID() uint64 { return uint64(atomic.AddUint32(&lastID, 1)) }
+func nextID() uint64 { return uint64(lastID.Add(1)) }
 
 // A TypeParam represents a type parameter type.
 type TypeParam struct {
index d69dc4feac2b40893bb0eb4063deaab28e578f99..17d3ee9e7fda99c2c244dbc46361e3857dedbbb2 100644 (file)
@@ -121,8 +121,8 @@ func (s *Span) Done() {
 type tracer struct {
        file chan traceFile // 1-buffered
 
-       nextTID    uint64
-       nextFlowID uint64
+       nextTID    atomic.Uint64
+       nextFlowID atomic.Uint64
 }
 
 func (t *tracer) writeEvent(ev *traceviewer.Event) error {
@@ -161,11 +161,11 @@ func (t *tracer) Close() error {
 }
 
 func (t *tracer) getNextTID() uint64 {
-       return atomic.AddUint64(&t.nextTID, 1)
+       return t.nextTID.Add(1)
 }
 
 func (t *tracer) getNextFlowID() uint64 {
-       return atomic.AddUint64(&t.nextFlowID, 1)
+       return t.nextFlowID.Add(1)
 }
 
 // traceKey is the context key for tracing information. It is unexported to prevent collisions with context keys defined in
index 32e855f6c50bc5cc5679b7fd82f2f25cf13b6b79..954d63d17f52b10ec1de8a6cb227c5993b981b26 100644 (file)
@@ -50,11 +50,11 @@ type jsonVar interface {
 
 // Int is a 64-bit integer variable that satisfies the [Var] interface.
 type Int struct {
-       i int64
+       i atomic.Int64
 }
 
 func (v *Int) Value() int64 {
-       return atomic.LoadInt64(&v.i)
+       return v.i.Load()
 }
 
 func (v *Int) String() string {
@@ -62,15 +62,15 @@ func (v *Int) String() string {
 }
 
 func (v *Int) appendJSON(b []byte) []byte {
-       return strconv.AppendInt(b, atomic.LoadInt64(&v.i), 10)
+       return strconv.AppendInt(b, v.i.Load(), 10)
 }
 
 func (v *Int) Add(delta int64) {
-       atomic.AddInt64(&v.i, delta)
+       v.i.Add(delta)
 }
 
 func (v *Int) Set(value int64) {
-       atomic.StoreInt64(&v.i, value)
+       v.i.Store(value)
 }
 
 // Float is a 64-bit float variable that satisfies the [Var] interface.
index b23601dc3ff57f93118d69f228dc6db1b8aa9b45..a13f86c213c4da54aa9a09d4a5036bf07a459cf3 100644 (file)
@@ -11,11 +11,11 @@ import "sync/atomic"
 // Note: This is a uint32 rather than a uint64 because the
 // respective 64 bit atomic instructions are not available
 // on all platforms.
-var lastID uint32
+var lastID atomic.Uint32
 
 // nextID returns a value increasing monotonically by 1 with
 // each call, starting with 1. It may be called concurrently.
-func nextID() uint64 { return uint64(atomic.AddUint32(&lastID, 1)) }
+func nextID() uint64 { return uint64(lastID.Add(1)) }
 
 // A TypeParam represents a type parameter type.
 type TypeParam struct {
index c9ea0afcf8c3286141ce54735a796a3fd7d5dfb5..4fe8aeb50cc83eefbb2db9ff17a96a79669d255a 100644 (file)
@@ -30,7 +30,7 @@ type mutatorRand interface {
 // creation and use, no reproducibility, no concurrency safety, just the
 // necessary methods, optimized for speed.
 
-var globalInc uint64 // PCG stream
+var globalInc atomic.Uint64 // PCG stream
 
 const multiplier uint64 = 6364136223846793005
 
@@ -63,7 +63,7 @@ func newPcgRand() *pcgRand {
        if seed := godebugSeed(); seed != nil {
                now = uint64(*seed)
        }
-       inc := atomic.AddUint64(&globalInc, 1)
+       inc := globalInc.Add(1)
        r.state = now
        r.inc = (inc << 1) | 1
        r.step()
index c020ef737da4025ede3ada3cc07f05892aafc597..b55cecd987dd07436accfaa4866d210cd0ef001f 100644 (file)
@@ -23,7 +23,7 @@ func NewPoolDequeue(n int) PoolDequeue {
        }
        // For testing purposes, set the head and tail indexes close
        // to wrapping around.
-       d.headTail = d.pack(1<<dequeueBits-500, 1<<dequeueBits-500)
+       d.headTail.Store(d.pack(1<<dequeueBits-500, 1<<dequeueBits-500))
        return d
 }
 
index 631f2c15fda267d470e7ac90b88e9125cc071edc..5c640f988a39218457a6701dd2582eb7bc91c316 100644 (file)
@@ -31,7 +31,7 @@ type poolDequeue struct {
        // The head index is stored in the most-significant bits so
        // that we can atomically add to it and the overflow is
        // harmless.
-       headTail uint64
+       headTail atomic.Uint64
 
        // vals is a ring buffer of interface{} values stored in this
        // dequeue. The size of this must be a power of 2.
@@ -78,7 +78,7 @@ func (d *poolDequeue) pack(head, tail uint32) uint64 {
 // pushHead adds val at the head of the queue. It returns false if the
 // queue is full. It must only be called by a single producer.
 func (d *poolDequeue) pushHead(val any) bool {
-       ptrs := atomic.LoadUint64(&d.headTail)
+       ptrs := d.headTail.Load()
        head, tail := d.unpack(ptrs)
        if (tail+uint32(len(d.vals)))&(1<<dequeueBits-1) == head {
                // Queue is full.
@@ -102,7 +102,7 @@ func (d *poolDequeue) pushHead(val any) bool {
 
        // Increment head. This passes ownership of slot to popTail
        // and acts as a store barrier for writing the slot.
-       atomic.AddUint64(&d.headTail, 1<<dequeueBits)
+       d.headTail.Add(1 << dequeueBits)
        return true
 }
 
@@ -112,7 +112,7 @@ func (d *poolDequeue) pushHead(val any) bool {
 func (d *poolDequeue) popHead() (any, bool) {
        var slot *eface
        for {
-               ptrs := atomic.LoadUint64(&d.headTail)
+               ptrs := d.headTail.Load()
                head, tail := d.unpack(ptrs)
                if tail == head {
                        // Queue is empty.
@@ -124,7 +124,7 @@ func (d *poolDequeue) popHead() (any, bool) {
                // slot.
                head--
                ptrs2 := d.pack(head, tail)
-               if atomic.CompareAndSwapUint64(&d.headTail, ptrs, ptrs2) {
+               if d.headTail.CompareAndSwap(ptrs, ptrs2) {
                        // We successfully took back slot.
                        slot = &d.vals[head&uint32(len(d.vals)-1)]
                        break
@@ -147,7 +147,7 @@ func (d *poolDequeue) popHead() (any, bool) {
 func (d *poolDequeue) popTail() (any, bool) {
        var slot *eface
        for {
-               ptrs := atomic.LoadUint64(&d.headTail)
+               ptrs := d.headTail.Load()
                head, tail := d.unpack(ptrs)
                if tail == head {
                        // Queue is empty.
@@ -158,7 +158,7 @@ func (d *poolDequeue) popTail() (any, bool) {
                // above) and increment tail. If this succeeds, then
                // we own the slot at tail.
                ptrs2 := d.pack(head, tail+1)
-               if atomic.CompareAndSwapUint64(&d.headTail, ptrs, ptrs2) {
+               if d.headTail.CompareAndSwap(ptrs, ptrs2) {
                        // Success.
                        slot = &d.vals[tail&uint32(len(d.vals)-1)]
                        break
index b197ea37bc8da2fae38a676a35975e9b9050142a..9491213ef1564b4cc5ab801cdbb7493fde8cba05 100644 (file)
@@ -727,16 +727,16 @@ func (b *B) trimOutput() {
 
 // A PB is used by RunParallel for running parallel benchmarks.
 type PB struct {
-       globalN *uint64 // shared between all worker goroutines iteration counter
-       grain   uint64  // acquire that many iterations from globalN at once
-       cache   uint64  // local cache of acquired iterations
-       bN      uint64  // total number of iterations to execute (b.N)
+       globalN *atomic.Uint64 // shared between all worker goroutines iteration counter
+       grain   uint64         // acquire that many iterations from globalN at once
+       cache   uint64         // local cache of acquired iterations
+       bN      uint64         // total number of iterations to execute (b.N)
 }
 
 // Next reports whether there are more iterations to execute.
 func (pb *PB) Next() bool {
        if pb.cache == 0 {
-               n := atomic.AddUint64(pb.globalN, pb.grain)
+               n := pb.globalN.Add(pb.grain)
                if n <= pb.bN {
                        pb.cache = pb.grain
                } else if n < pb.bN+pb.grain {
@@ -782,7 +782,7 @@ func (b *B) RunParallel(body func(*PB)) {
                grain = 1e4
        }
 
-       n := uint64(0)
+       var n atomic.Uint64
        numProcs := b.parallelism * runtime.GOMAXPROCS(0)
        var wg sync.WaitGroup
        wg.Add(numProcs)
@@ -798,7 +798,7 @@ func (b *B) RunParallel(body func(*PB)) {
                }()
        }
        wg.Wait()
-       if n <= uint64(b.N) && !b.Failed() {
+       if n.Load() <= uint64(b.N) && !b.Failed() {
                b.Fatal("RunParallel: body exited without pb.Next() == false")
        }
 }