github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/internal/runtime/atomic/types.go (about) 1 // Copyright 2021 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 "github.com/shogo82148/std/unsafe" 8 9 // Int32 is an atomically accessed int32 value. 10 // 11 // An Int32 must not be copied. 12 type Int32 struct { 13 noCopy noCopy 14 value int32 15 } 16 17 // Load accesses and returns the value atomically. 18 // 19 //go:nosplit 20 func (i *Int32) Load() int32 21 22 // Store updates the value atomically. 23 // 24 //go:nosplit 25 func (i *Int32) Store(value int32) 26 27 // CompareAndSwap atomically compares i's value with old, 28 // and if they're equal, swaps i's value with new. 29 // It reports whether the swap ran. 30 // 31 //go:nosplit 32 func (i *Int32) CompareAndSwap(old, new int32) bool 33 34 // Swap replaces i's value with new, returning 35 // i's value before the replacement. 36 // 37 //go:nosplit 38 func (i *Int32) Swap(new int32) int32 39 40 // Add adds delta to i atomically, returning 41 // the new updated value. 42 // 43 // This operation wraps around in the usual 44 // two's-complement way. 45 // 46 //go:nosplit 47 func (i *Int32) Add(delta int32) int32 48 49 // Int64 is an atomically accessed int64 value. 50 // 51 // 8-byte aligned on all platforms, unlike a regular int64. 52 // 53 // An Int64 must not be copied. 54 type Int64 struct { 55 noCopy noCopy 56 _ align64 57 value int64 58 } 59 60 // Load accesses and returns the value atomically. 61 // 62 //go:nosplit 63 func (i *Int64) Load() int64 64 65 // Store updates the value atomically. 66 // 67 //go:nosplit 68 func (i *Int64) Store(value int64) 69 70 // CompareAndSwap atomically compares i's value with old, 71 // and if they're equal, swaps i's value with new. 72 // It reports whether the swap ran. 73 // 74 //go:nosplit 75 func (i *Int64) CompareAndSwap(old, new int64) bool 76 77 // Swap replaces i's value with new, returning 78 // i's value before the replacement. 79 // 80 //go:nosplit 81 func (i *Int64) Swap(new int64) int64 82 83 // Add adds delta to i atomically, returning 84 // the new updated value. 85 // 86 // This operation wraps around in the usual 87 // two's-complement way. 88 // 89 //go:nosplit 90 func (i *Int64) Add(delta int64) int64 91 92 // Uint8 is an atomically accessed uint8 value. 93 // 94 // A Uint8 must not be copied. 95 type Uint8 struct { 96 noCopy noCopy 97 value uint8 98 } 99 100 // Load accesses and returns the value atomically. 101 // 102 //go:nosplit 103 func (u *Uint8) Load() uint8 104 105 // Store updates the value atomically. 106 // 107 //go:nosplit 108 func (u *Uint8) Store(value uint8) 109 110 // And takes value and performs a bit-wise 111 // "and" operation with the value of u, storing 112 // the result into u. 113 // 114 // The full process is performed atomically. 115 // 116 //go:nosplit 117 func (u *Uint8) And(value uint8) 118 119 // Or takes value and performs a bit-wise 120 // "or" operation with the value of u, storing 121 // the result into u. 122 // 123 // The full process is performed atomically. 124 // 125 //go:nosplit 126 func (u *Uint8) Or(value uint8) 127 128 // Bool is an atomically accessed bool value. 129 // 130 // A Bool must not be copied. 131 type Bool struct { 132 // Inherits noCopy from Uint8. 133 u Uint8 134 } 135 136 // Load accesses and returns the value atomically. 137 // 138 //go:nosplit 139 func (b *Bool) Load() bool 140 141 // Store updates the value atomically. 142 // 143 //go:nosplit 144 func (b *Bool) Store(value bool) 145 146 // Uint32 is an atomically accessed uint32 value. 147 // 148 // A Uint32 must not be copied. 149 type Uint32 struct { 150 noCopy noCopy 151 value uint32 152 } 153 154 // Load accesses and returns the value atomically. 155 // 156 //go:nosplit 157 func (u *Uint32) Load() uint32 158 159 // LoadAcquire is a partially unsynchronized version 160 // of Load that relaxes ordering constraints. Other threads 161 // may observe operations that precede this operation to 162 // occur after it, but no operation that occurs after it 163 // on this thread can be observed to occur before it. 164 // 165 // WARNING: Use sparingly and with great care. 166 // 167 //go:nosplit 168 func (u *Uint32) LoadAcquire() uint32 169 170 // Store updates the value atomically. 171 // 172 //go:nosplit 173 func (u *Uint32) Store(value uint32) 174 175 // StoreRelease is a partially unsynchronized version 176 // of Store that relaxes ordering constraints. Other threads 177 // may observe operations that occur after this operation to 178 // precede it, but no operation that precedes it 179 // on this thread can be observed to occur after it. 180 // 181 // WARNING: Use sparingly and with great care. 182 // 183 //go:nosplit 184 func (u *Uint32) StoreRelease(value uint32) 185 186 // CompareAndSwap atomically compares u's value with old, 187 // and if they're equal, swaps u's value with new. 188 // It reports whether the swap ran. 189 // 190 //go:nosplit 191 func (u *Uint32) CompareAndSwap(old, new uint32) bool 192 193 // CompareAndSwapRelease is a partially unsynchronized version 194 // of Cas that relaxes ordering constraints. Other threads 195 // may observe operations that occur after this operation to 196 // precede it, but no operation that precedes it 197 // on this thread can be observed to occur after it. 198 // It reports whether the swap ran. 199 // 200 // WARNING: Use sparingly and with great care. 201 // 202 //go:nosplit 203 func (u *Uint32) CompareAndSwapRelease(old, new uint32) bool 204 205 // Swap replaces u's value with new, returning 206 // u's value before the replacement. 207 // 208 //go:nosplit 209 func (u *Uint32) Swap(value uint32) uint32 210 211 // And takes value and performs a bit-wise 212 // "and" operation with the value of u, storing 213 // the result into u. 214 // 215 // The full process is performed atomically. 216 // 217 //go:nosplit 218 func (u *Uint32) And(value uint32) 219 220 // Or takes value and performs a bit-wise 221 // "or" operation with the value of u, storing 222 // the result into u. 223 // 224 // The full process is performed atomically. 225 // 226 //go:nosplit 227 func (u *Uint32) Or(value uint32) 228 229 // Add adds delta to u atomically, returning 230 // the new updated value. 231 // 232 // This operation wraps around in the usual 233 // two's-complement way. 234 // 235 //go:nosplit 236 func (u *Uint32) Add(delta int32) uint32 237 238 // Uint64 is an atomically accessed uint64 value. 239 // 240 // 8-byte aligned on all platforms, unlike a regular uint64. 241 // 242 // A Uint64 must not be copied. 243 type Uint64 struct { 244 noCopy noCopy 245 _ align64 246 value uint64 247 } 248 249 // Load accesses and returns the value atomically. 250 // 251 //go:nosplit 252 func (u *Uint64) Load() uint64 253 254 // Store updates the value atomically. 255 // 256 //go:nosplit 257 func (u *Uint64) Store(value uint64) 258 259 // CompareAndSwap atomically compares u's value with old, 260 // and if they're equal, swaps u's value with new. 261 // It reports whether the swap ran. 262 // 263 //go:nosplit 264 func (u *Uint64) CompareAndSwap(old, new uint64) bool 265 266 // Swap replaces u's value with new, returning 267 // u's value before the replacement. 268 // 269 //go:nosplit 270 func (u *Uint64) Swap(value uint64) uint64 271 272 // Add adds delta to u atomically, returning 273 // the new updated value. 274 // 275 // This operation wraps around in the usual 276 // two's-complement way. 277 // 278 //go:nosplit 279 func (u *Uint64) Add(delta int64) uint64 280 281 // Uintptr is an atomically accessed uintptr value. 282 // 283 // A Uintptr must not be copied. 284 type Uintptr struct { 285 noCopy noCopy 286 value uintptr 287 } 288 289 // Load accesses and returns the value atomically. 290 // 291 //go:nosplit 292 func (u *Uintptr) Load() uintptr 293 294 // LoadAcquire is a partially unsynchronized version 295 // of Load that relaxes ordering constraints. Other threads 296 // may observe operations that precede this operation to 297 // occur after it, but no operation that occurs after it 298 // on this thread can be observed to occur before it. 299 // 300 // WARNING: Use sparingly and with great care. 301 // 302 //go:nosplit 303 func (u *Uintptr) LoadAcquire() uintptr 304 305 // Store updates the value atomically. 306 // 307 //go:nosplit 308 func (u *Uintptr) Store(value uintptr) 309 310 // StoreRelease is a partially unsynchronized version 311 // of Store that relaxes ordering constraints. Other threads 312 // may observe operations that occur after this operation to 313 // precede it, but no operation that precedes it 314 // on this thread can be observed to occur after it. 315 // 316 // WARNING: Use sparingly and with great care. 317 // 318 //go:nosplit 319 func (u *Uintptr) StoreRelease(value uintptr) 320 321 // CompareAndSwap atomically compares u's value with old, 322 // and if they're equal, swaps u's value with new. 323 // It reports whether the swap ran. 324 // 325 //go:nosplit 326 func (u *Uintptr) CompareAndSwap(old, new uintptr) bool 327 328 // Swap replaces u's value with new, returning 329 // u's value before the replacement. 330 // 331 //go:nosplit 332 func (u *Uintptr) Swap(value uintptr) uintptr 333 334 // Add adds delta to u atomically, returning 335 // the new updated value. 336 // 337 // This operation wraps around in the usual 338 // two's-complement way. 339 // 340 //go:nosplit 341 func (u *Uintptr) Add(delta uintptr) uintptr 342 343 // Float64 is an atomically accessed float64 value. 344 // 345 // 8-byte aligned on all platforms, unlike a regular float64. 346 // 347 // A Float64 must not be copied. 348 type Float64 struct { 349 // Inherits noCopy and align64 from Uint64. 350 u Uint64 351 } 352 353 // Load accesses and returns the value atomically. 354 // 355 //go:nosplit 356 func (f *Float64) Load() float64 357 358 // Store updates the value atomically. 359 // 360 //go:nosplit 361 func (f *Float64) Store(value float64) 362 363 // UnsafePointer is an atomically accessed unsafe.Pointer value. 364 // 365 // Note that because of the atomicity guarantees, stores to values 366 // of this type never trigger a write barrier, and the relevant 367 // methods are suffixed with "NoWB" to indicate that explicitly. 368 // As a result, this type should be used carefully, and sparingly, 369 // mostly with values that do not live in the Go heap anyway. 370 // 371 // An UnsafePointer must not be copied. 372 type UnsafePointer struct { 373 noCopy noCopy 374 value unsafe.Pointer 375 } 376 377 // Load accesses and returns the value atomically. 378 // 379 //go:nosplit 380 func (u *UnsafePointer) Load() unsafe.Pointer 381 382 // StoreNoWB updates the value atomically. 383 // 384 // WARNING: As the name implies this operation does *not* 385 // perform a write barrier on value, and so this operation may 386 // hide pointers from the GC. Use with care and sparingly. 387 // It is safe to use with values not found in the Go heap. 388 // Prefer Store instead. 389 // 390 //go:nosplit 391 func (u *UnsafePointer) StoreNoWB(value unsafe.Pointer) 392 393 // Store updates the value atomically. 394 func (u *UnsafePointer) Store(value unsafe.Pointer) 395 396 // CompareAndSwapNoWB atomically (with respect to other methods) 397 // compares u's value with old, and if they're equal, 398 // swaps u's value with new. 399 // It reports whether the swap ran. 400 // 401 // WARNING: As the name implies this operation does *not* 402 // perform a write barrier on value, and so this operation may 403 // hide pointers from the GC. Use with care and sparingly. 404 // It is safe to use with values not found in the Go heap. 405 // Prefer CompareAndSwap instead. 406 // 407 //go:nosplit 408 func (u *UnsafePointer) CompareAndSwapNoWB(old, new unsafe.Pointer) bool 409 410 // CompareAndSwap atomically compares u's value with old, 411 // and if they're equal, swaps u's value with new. 412 // It reports whether the swap ran. 413 func (u *UnsafePointer) CompareAndSwap(old, new unsafe.Pointer) bool 414 415 // Pointer is an atomic pointer of type *T. 416 type Pointer[T any] struct { 417 u UnsafePointer 418 } 419 420 // Load accesses and returns the value atomically. 421 // 422 //go:nosplit 423 func (p *Pointer[T]) Load() *T 424 425 // StoreNoWB updates the value atomically. 426 // 427 // WARNING: As the name implies this operation does *not* 428 // perform a write barrier on value, and so this operation may 429 // hide pointers from the GC. Use with care and sparingly. 430 // It is safe to use with values not found in the Go heap. 431 // Prefer Store instead. 432 // 433 //go:nosplit 434 func (p *Pointer[T]) StoreNoWB(value *T) 435 436 // Store updates the value atomically. 437 // 438 //go:nosplit 439 func (p *Pointer[T]) Store(value *T) 440 441 // CompareAndSwapNoWB atomically (with respect to other methods) 442 // compares u's value with old, and if they're equal, 443 // swaps u's value with new. 444 // It reports whether the swap ran. 445 // 446 // WARNING: As the name implies this operation does *not* 447 // perform a write barrier on value, and so this operation may 448 // hide pointers from the GC. Use with care and sparingly. 449 // It is safe to use with values not found in the Go heap. 450 // Prefer CompareAndSwap instead. 451 // 452 //go:nosplit 453 func (p *Pointer[T]) CompareAndSwapNoWB(old, new *T) bool 454 455 // CompareAndSwap atomically (with respect to other methods) 456 // compares u's value with old, and if they're equal, 457 // swaps u's value with new. 458 // It reports whether the swap ran. 459 func (p *Pointer[T]) CompareAndSwap(old, new *T) bool