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>
 // 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 {
 
 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 {
 }
 
 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
 
 
 // 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 {
 }
 
 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.
 
 // 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 {
 
 // 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
 
        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()
 
        }
        // 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
 }
 
 
        // 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.
 // 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.
 
        // 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
 }
 
 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.
                // 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
 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.
                // 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
 
 
 // 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 {
                grain = 1e4
        }
 
-       n := uint64(0)
+       var n atomic.Uint64
        numProcs := b.parallelism * runtime.GOMAXPROCS(0)
        var wg sync.WaitGroup
        wg.Add(numProcs)
                }()
        }
        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")
        }
 }