Source file src/sync/atomic/type.go
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 // 12 // Bool must not be copied after first use. 13 type Bool struct { 14 _ noCopy 15 v uint32 16 } 17 18 // Load atomically loads and returns the value stored in x. 19 func (x *Bool) Load() bool { return LoadUint32(&x.v) != 0 } 20 21 // Store atomically stores val into x. 22 func (x *Bool) Store(val bool) { StoreUint32(&x.v, b32(val)) } 23 24 // Swap atomically stores new into x and returns the previous value. 25 func (x *Bool) Swap(new bool) (old bool) { return SwapUint32(&x.v, b32(new)) != 0 } 26 27 // CompareAndSwap executes the compare-and-swap operation for the boolean value x. 28 func (x *Bool) CompareAndSwap(old, new bool) (swapped bool) { 29 return CompareAndSwapUint32(&x.v, b32(old), b32(new)) 30 } 31 32 // b32 returns a uint32 0 or 1 representing b. 33 func b32(b bool) uint32 { 34 if b { 35 return 1 36 } 37 return 0 38 } 39 40 // For testing *Pointer[T]'s methods can be inlined. 41 // Keep in sync with cmd/compile/internal/test/inl_test.go:TestIntendedInlining. 42 var _ = &Pointer[int]{} 43 44 // A Pointer is an atomic pointer of type *T. The zero value is a nil *T. 45 // 46 // Pointer must not be copied after first use. 47 type Pointer[T any] struct { 48 // Mention *T in a field to disallow conversion between Pointer types. 49 // See go.dev/issue/56603 for more details. 50 // Use *T, not T, to avoid spurious recursive type definition errors. 51 _ [0]*T 52 53 _ noCopy 54 v unsafe.Pointer 55 } 56 57 // Load atomically loads and returns the value stored in x. 58 func (x *Pointer[T]) Load() *T { return (*T)(LoadPointer(&x.v)) } 59 60 // Store atomically stores val into x. 61 func (x *Pointer[T]) Store(val *T) { StorePointer(&x.v, unsafe.Pointer(val)) } 62 63 // Swap atomically stores new into x and returns the previous value. 64 func (x *Pointer[T]) Swap(new *T) (old *T) { return (*T)(SwapPointer(&x.v, unsafe.Pointer(new))) } 65 66 // CompareAndSwap executes the compare-and-swap operation for x. 67 func (x *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) { 68 return CompareAndSwapPointer(&x.v, unsafe.Pointer(old), unsafe.Pointer(new)) 69 } 70 71 // An Int32 is an atomic int32. The zero value is zero. 72 // 73 // Int32 must not be copied after first use. 74 type Int32 struct { 75 _ noCopy 76 v int32 77 } 78 79 // Load atomically loads and returns the value stored in x. 80 func (x *Int32) Load() int32 { return LoadInt32(&x.v) } 81 82 // Store atomically stores val into x. 83 func (x *Int32) Store(val int32) { StoreInt32(&x.v, val) } 84 85 // Swap atomically stores new into x and returns the previous value. 86 func (x *Int32) Swap(new int32) (old int32) { return SwapInt32(&x.v, new) } 87 88 // CompareAndSwap executes the compare-and-swap operation for x. 89 func (x *Int32) CompareAndSwap(old, new int32) (swapped bool) { 90 return CompareAndSwapInt32(&x.v, old, new) 91 } 92 93 // Add atomically adds delta to x and returns the new value. 94 func (x *Int32) Add(delta int32) (new int32) { return AddInt32(&x.v, delta) } 95 96 // And atomically performs a bitwise AND operation on x using the bitmask 97 // provided as mask and returns the old value. 98 func (x *Int32) And(mask int32) (old int32) { return AndInt32(&x.v, mask) } 99 100 // Or atomically performs a bitwise OR operation on x using the bitmask 101 // provided as mask and returns the old value. 102 func (x *Int32) Or(mask int32) (old int32) { return OrInt32(&x.v, mask) } 103 104 // An Int64 is an atomic int64. The zero value is zero. 105 // 106 // Int64 must not be copied after first use. 107 type Int64 struct { 108 _ noCopy 109 _ align64 110 v int64 111 } 112 113 // Load atomically loads and returns the value stored in x. 114 func (x *Int64) Load() int64 { return LoadInt64(&x.v) } 115 116 // Store atomically stores val into x. 117 func (x *Int64) Store(val int64) { StoreInt64(&x.v, val) } 118 119 // Swap atomically stores new into x and returns the previous value. 120 func (x *Int64) Swap(new int64) (old int64) { return SwapInt64(&x.v, new) } 121 122 // CompareAndSwap executes the compare-and-swap operation for x. 123 func (x *Int64) CompareAndSwap(old, new int64) (swapped bool) { 124 return CompareAndSwapInt64(&x.v, old, new) 125 } 126 127 // Add atomically adds delta to x and returns the new value. 128 func (x *Int64) Add(delta int64) (new int64) { return AddInt64(&x.v, delta) } 129 130 // And atomically performs a bitwise AND operation on x using the bitmask 131 // provided as mask and returns the old value. 132 func (x *Int64) And(mask int64) (old int64) { return AndInt64(&x.v, mask) } 133 134 // Or atomically performs a bitwise OR operation on x using the bitmask 135 // provided as mask and returns the old value. 136 func (x *Int64) Or(mask int64) (old int64) { return OrInt64(&x.v, mask) } 137 138 // A Uint32 is an atomic uint32. The zero value is zero. 139 // 140 // Uint32 must not be copied after first use. 141 type Uint32 struct { 142 _ noCopy 143 v uint32 144 } 145 146 // Load atomically loads and returns the value stored in x. 147 func (x *Uint32) Load() uint32 { return LoadUint32(&x.v) } 148 149 // Store atomically stores val into x. 150 func (x *Uint32) Store(val uint32) { StoreUint32(&x.v, val) } 151 152 // Swap atomically stores new into x and returns the previous value. 153 func (x *Uint32) Swap(new uint32) (old uint32) { return SwapUint32(&x.v, new) } 154 155 // CompareAndSwap executes the compare-and-swap operation for x. 156 func (x *Uint32) CompareAndSwap(old, new uint32) (swapped bool) { 157 return CompareAndSwapUint32(&x.v, old, new) 158 } 159 160 // Add atomically adds delta to x and returns the new value. 161 func (x *Uint32) Add(delta uint32) (new uint32) { return AddUint32(&x.v, delta) } 162 163 // And atomically performs a bitwise AND operation on x using the bitmask 164 // provided as mask and returns the old value. 165 func (x *Uint32) And(mask uint32) (old uint32) { return AndUint32(&x.v, mask) } 166 167 // Or atomically performs a bitwise OR operation on x using the bitmask 168 // provided as mask and returns the old value. 169 func (x *Uint32) Or(mask uint32) (old uint32) { return OrUint32(&x.v, mask) } 170 171 // A Uint64 is an atomic uint64. The zero value is zero. 172 // 173 // Uint64 must not be copied after first use. 174 type Uint64 struct { 175 _ noCopy 176 _ align64 177 v uint64 178 } 179 180 // Load atomically loads and returns the value stored in x. 181 func (x *Uint64) Load() uint64 { return LoadUint64(&x.v) } 182 183 // Store atomically stores val into x. 184 func (x *Uint64) Store(val uint64) { StoreUint64(&x.v, val) } 185 186 // Swap atomically stores new into x and returns the previous value. 187 func (x *Uint64) Swap(new uint64) (old uint64) { return SwapUint64(&x.v, new) } 188 189 // CompareAndSwap executes the compare-and-swap operation for x. 190 func (x *Uint64) CompareAndSwap(old, new uint64) (swapped bool) { 191 return CompareAndSwapUint64(&x.v, old, new) 192 } 193 194 // Add atomically adds delta to x and returns the new value. 195 func (x *Uint64) Add(delta uint64) (new uint64) { return AddUint64(&x.v, delta) } 196 197 // And atomically performs a bitwise AND operation on x using the bitmask 198 // provided as mask and returns the old value. 199 func (x *Uint64) And(mask uint64) (old uint64) { return AndUint64(&x.v, mask) } 200 201 // Or atomically performs a bitwise OR operation on x using the bitmask 202 // provided as mask and returns the old value. 203 func (x *Uint64) Or(mask uint64) (old uint64) { return OrUint64(&x.v, mask) } 204 205 // A Uintptr is an atomic uintptr. The zero value is zero. 206 // 207 // Uintptr must not be copied after first use. 208 type Uintptr struct { 209 _ noCopy 210 v uintptr 211 } 212 213 // Load atomically loads and returns the value stored in x. 214 func (x *Uintptr) Load() uintptr { return LoadUintptr(&x.v) } 215 216 // Store atomically stores val into x. 217 func (x *Uintptr) Store(val uintptr) { StoreUintptr(&x.v, val) } 218 219 // Swap atomically stores new into x and returns the previous value. 220 func (x *Uintptr) Swap(new uintptr) (old uintptr) { return SwapUintptr(&x.v, new) } 221 222 // CompareAndSwap executes the compare-and-swap operation for x. 223 func (x *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) { 224 return CompareAndSwapUintptr(&x.v, old, new) 225 } 226 227 // Add atomically adds delta to x and returns the new value. 228 func (x *Uintptr) Add(delta uintptr) (new uintptr) { return AddUintptr(&x.v, delta) } 229 230 // And atomically performs a bitwise AND operation on x using the bitmask 231 // provided as mask and returns the old value. 232 func (x *Uintptr) And(mask uintptr) (old uintptr) { return AndUintptr(&x.v, mask) } 233 234 // Or atomically performs a bitwise OR operation on x using the bitmask 235 // provided as mask and returns the updated value after the OR operation. 236 func (x *Uintptr) Or(mask uintptr) (old uintptr) { return OrUintptr(&x.v, mask) } 237 238 // noCopy may be added to structs which must not be copied 239 // after the first use. 240 // 241 // See https://golang.org/issues/8005#issuecomment-190753527 242 // for details. 243 // 244 // Note that it must not be embedded, due to the Lock and Unlock methods. 245 type noCopy struct{} 246 247 // Lock is a no-op used by -copylocks checker from `go vet`. 248 func (*noCopy) Lock() {} 249 func (*noCopy) Unlock() {} 250 251 // align64 may be added to structs that must be 64-bit aligned. 252 // This struct is recognized by a special case in the compiler 253 // and will not work if copied to any other package. 254 type align64 struct{} 255