...

Source file src/sync/atomic/type.go

Documentation: sync/atomic

     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{}
   201  

View as plain text