github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/sync/atomic/type.go (about) 1 // Copyright 2022 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package atomic 6 7 import "unsafe" 8 9 // A Bool is an atomic boolean value. 10 // The zero value is false. 11 type Bool struct { 12 _ noCopy 13 v uint32 14 } 15 16 // Load atomically loads and returns the value stored in x. 17 func (x *Bool) Load() bool { return LoadUint32(&x.v) != 0 } 18 19 // Store atomically stores val into x. 20 func (x *Bool) Store(val bool) { StoreUint32(&x.v, b32(val)) } 21 22 // Swap atomically stores new into x and returns the previous value. 23 func (x *Bool) Swap(new bool) (old bool) { return SwapUint32(&x.v, b32(new)) != 0 } 24 25 // CompareAndSwap executes the compare-and-swap operation for the boolean value x. 26 func (x *Bool) CompareAndSwap(old, new bool) (swapped bool) { 27 return CompareAndSwapUint32(&x.v, b32(old), b32(new)) 28 } 29 30 // b32 returns a uint32 0 or 1 representing b. 31 func b32(b bool) uint32 { 32 if b { 33 return 1 34 } 35 return 0 36 } 37 38 // For testing *Pointer[T]'s methods can be inlined. 39 // Keep in sync with cmd/compile/internal/test/inl_test.go:TestIntendedInlining. 40 var _ = &Pointer[int]{} 41 42 // A Pointer is an atomic pointer of type *T. The zero value is a nil *T. 43 type Pointer[T any] struct { 44 // Mention *T in a field to disallow conversion between Pointer types. 45 // See go.dev/issue/56603 for more details. 46 // Use *T, not T, to avoid spurious recursive type definition errors. 47 _ [0]*T 48 49 _ noCopy 50 v unsafe.Pointer 51 } 52 53 // Load atomically loads and returns the value stored in x. 54 func (x *Pointer[T]) Load() *T { return (*T)(LoadPointer(&x.v)) } 55 56 // Store atomically stores val into x. 57 func (x *Pointer[T]) Store(val *T) { StorePointer(&x.v, unsafe.Pointer(val)) } 58 59 // Swap atomically stores new into x and returns the previous value. 60 func (x *Pointer[T]) Swap(new *T) (old *T) { return (*T)(SwapPointer(&x.v, unsafe.Pointer(new))) } 61 62 // CompareAndSwap executes the compare-and-swap operation for x. 63 func (x *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) { 64 return CompareAndSwapPointer(&x.v, unsafe.Pointer(old), unsafe.Pointer(new)) 65 } 66 67 // An Int32 is an atomic int32. The zero value is zero. 68 type Int32 struct { 69 _ noCopy 70 v int32 71 } 72 73 // Load atomically loads and returns the value stored in x. 74 func (x *Int32) Load() int32 { return LoadInt32(&x.v) } 75 76 // Store atomically stores val into x. 77 func (x *Int32) Store(val int32) { StoreInt32(&x.v, val) } 78 79 // Swap atomically stores new into x and returns the previous value. 80 func (x *Int32) Swap(new int32) (old int32) { return SwapInt32(&x.v, new) } 81 82 // CompareAndSwap executes the compare-and-swap operation for x. 83 func (x *Int32) CompareAndSwap(old, new int32) (swapped bool) { 84 return CompareAndSwapInt32(&x.v, old, new) 85 } 86 87 // Add atomically adds delta to x and returns the new value. 88 func (x *Int32) Add(delta int32) (new int32) { return AddInt32(&x.v, delta) } 89 90 // An Int64 is an atomic int64. The zero value is zero. 91 type Int64 struct { 92 _ noCopy 93 _ align64 94 v int64 95 } 96 97 // Load atomically loads and returns the value stored in x. 98 func (x *Int64) Load() int64 { return LoadInt64(&x.v) } 99 100 // Store atomically stores val into x. 101 func (x *Int64) Store(val int64) { StoreInt64(&x.v, val) } 102 103 // Swap atomically stores new into x and returns the previous value. 104 func (x *Int64) Swap(new int64) (old int64) { return SwapInt64(&x.v, new) } 105 106 // CompareAndSwap executes the compare-and-swap operation for x. 107 func (x *Int64) CompareAndSwap(old, new int64) (swapped bool) { 108 return CompareAndSwapInt64(&x.v, old, new) 109 } 110 111 // Add atomically adds delta to x and returns the new value. 112 func (x *Int64) Add(delta int64) (new int64) { return AddInt64(&x.v, delta) } 113 114 // A Uint32 is an atomic uint32. The zero value is zero. 115 type Uint32 struct { 116 _ noCopy 117 v uint32 118 } 119 120 // Load atomically loads and returns the value stored in x. 121 func (x *Uint32) Load() uint32 { return LoadUint32(&x.v) } 122 123 // Store atomically stores val into x. 124 func (x *Uint32) Store(val uint32) { StoreUint32(&x.v, val) } 125 126 // Swap atomically stores new into x and returns the previous value. 127 func (x *Uint32) Swap(new uint32) (old uint32) { return SwapUint32(&x.v, new) } 128 129 // CompareAndSwap executes the compare-and-swap operation for x. 130 func (x *Uint32) CompareAndSwap(old, new uint32) (swapped bool) { 131 return CompareAndSwapUint32(&x.v, old, new) 132 } 133 134 // Add atomically adds delta to x and returns the new value. 135 func (x *Uint32) Add(delta uint32) (new uint32) { return AddUint32(&x.v, delta) } 136 137 // A Uint64 is an atomic uint64. The zero value is zero. 138 type Uint64 struct { 139 _ noCopy 140 _ align64 141 v uint64 142 } 143 144 // Load atomically loads and returns the value stored in x. 145 func (x *Uint64) Load() uint64 { return LoadUint64(&x.v) } 146 147 // Store atomically stores val into x. 148 func (x *Uint64) Store(val uint64) { StoreUint64(&x.v, val) } 149 150 // Swap atomically stores new into x and returns the previous value. 151 func (x *Uint64) Swap(new uint64) (old uint64) { return SwapUint64(&x.v, new) } 152 153 // CompareAndSwap executes the compare-and-swap operation for x. 154 func (x *Uint64) CompareAndSwap(old, new uint64) (swapped bool) { 155 return CompareAndSwapUint64(&x.v, old, new) 156 } 157 158 // Add atomically adds delta to x and returns the new value. 159 func (x *Uint64) Add(delta uint64) (new uint64) { return AddUint64(&x.v, delta) } 160 161 // A Uintptr is an atomic uintptr. The zero value is zero. 162 type Uintptr struct { 163 _ noCopy 164 v uintptr 165 } 166 167 // Load atomically loads and returns the value stored in x. 168 func (x *Uintptr) Load() uintptr { return LoadUintptr(&x.v) } 169 170 // Store atomically stores val into x. 171 func (x *Uintptr) Store(val uintptr) { StoreUintptr(&x.v, val) } 172 173 // Swap atomically stores new into x and returns the previous value. 174 func (x *Uintptr) Swap(new uintptr) (old uintptr) { return SwapUintptr(&x.v, new) } 175 176 // CompareAndSwap executes the compare-and-swap operation for x. 177 func (x *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) { 178 return CompareAndSwapUintptr(&x.v, old, new) 179 } 180 181 // Add atomically adds delta to x and returns the new value. 182 func (x *Uintptr) Add(delta uintptr) (new uintptr) { return AddUintptr(&x.v, delta) } 183 184 // noCopy may be added to structs which must not be copied 185 // after the first use. 186 // 187 // See https://golang.org/issues/8005#issuecomment-190753527 188 // for details. 189 // 190 // Note that it must not be embedded, due to the Lock and Unlock methods. 191 type noCopy struct{} 192 193 // Lock is a no-op used by -copylocks checker from `go vet`. 194 func (*noCopy) Lock() {} 195 func (*noCopy) Unlock() {} 196 197 // align64 may be added to structs that must be 64-bit aligned. 198 // This struct is recognized by a special case in the compiler 199 // and will not work if copied to any other package. 200 type align64 struct{}