...

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  // A Pointer is an atomic pointer of type *T. The zero value is a nil *T.
    39  type Pointer[T any] struct {
    40  	// Mention T in a field to disallow conversion between Pointer types.
    41  	// See go.dev/issue/56603 for more details.
    42  	_ [0]T
    43  
    44  	_ noCopy
    45  	v unsafe.Pointer
    46  }
    47  
    48  // Load atomically loads and returns the value stored in x.
    49  func (x *Pointer[T]) Load() *T { return (*T)(LoadPointer(&x.v)) }
    50  
    51  // Store atomically stores val into x.
    52  func (x *Pointer[T]) Store(val *T) { StorePointer(&x.v, unsafe.Pointer(val)) }
    53  
    54  // Swap atomically stores new into x and returns the previous value.
    55  func (x *Pointer[T]) Swap(new *T) (old *T) { return (*T)(SwapPointer(&x.v, unsafe.Pointer(new))) }
    56  
    57  // CompareAndSwap executes the compare-and-swap operation for x.
    58  func (x *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) {
    59  	return CompareAndSwapPointer(&x.v, unsafe.Pointer(old), unsafe.Pointer(new))
    60  }
    61  
    62  // An Int32 is an atomic int32. The zero value is zero.
    63  type Int32 struct {
    64  	_ noCopy
    65  	v int32
    66  }
    67  
    68  // Load atomically loads and returns the value stored in x.
    69  func (x *Int32) Load() int32 { return LoadInt32(&x.v) }
    70  
    71  // Store atomically stores val into x.
    72  func (x *Int32) Store(val int32) { StoreInt32(&x.v, val) }
    73  
    74  // Swap atomically stores new into x and returns the previous value.
    75  func (x *Int32) Swap(new int32) (old int32) { return SwapInt32(&x.v, new) }
    76  
    77  // CompareAndSwap executes the compare-and-swap operation for x.
    78  func (x *Int32) CompareAndSwap(old, new int32) (swapped bool) {
    79  	return CompareAndSwapInt32(&x.v, old, new)
    80  }
    81  
    82  // Add atomically adds delta to x and returns the new value.
    83  func (x *Int32) Add(delta int32) (new int32) { return AddInt32(&x.v, delta) }
    84  
    85  // An Int64 is an atomic int64. The zero value is zero.
    86  type Int64 struct {
    87  	_ noCopy
    88  	_ align64
    89  	v int64
    90  }
    91  
    92  // Load atomically loads and returns the value stored in x.
    93  func (x *Int64) Load() int64 { return LoadInt64(&x.v) }
    94  
    95  // Store atomically stores val into x.
    96  func (x *Int64) Store(val int64) { StoreInt64(&x.v, val) }
    97  
    98  // Swap atomically stores new into x and returns the previous value.
    99  func (x *Int64) Swap(new int64) (old int64) { return SwapInt64(&x.v, new) }
   100  
   101  // CompareAndSwap executes the compare-and-swap operation for x.
   102  func (x *Int64) CompareAndSwap(old, new int64) (swapped bool) {
   103  	return CompareAndSwapInt64(&x.v, old, new)
   104  }
   105  
   106  // Add atomically adds delta to x and returns the new value.
   107  func (x *Int64) Add(delta int64) (new int64) { return AddInt64(&x.v, delta) }
   108  
   109  // An Uint32 is an atomic uint32. The zero value is zero.
   110  type Uint32 struct {
   111  	_ noCopy
   112  	v uint32
   113  }
   114  
   115  // Load atomically loads and returns the value stored in x.
   116  func (x *Uint32) Load() uint32 { return LoadUint32(&x.v) }
   117  
   118  // Store atomically stores val into x.
   119  func (x *Uint32) Store(val uint32) { StoreUint32(&x.v, val) }
   120  
   121  // Swap atomically stores new into x and returns the previous value.
   122  func (x *Uint32) Swap(new uint32) (old uint32) { return SwapUint32(&x.v, new) }
   123  
   124  // CompareAndSwap executes the compare-and-swap operation for x.
   125  func (x *Uint32) CompareAndSwap(old, new uint32) (swapped bool) {
   126  	return CompareAndSwapUint32(&x.v, old, new)
   127  }
   128  
   129  // Add atomically adds delta to x and returns the new value.
   130  func (x *Uint32) Add(delta uint32) (new uint32) { return AddUint32(&x.v, delta) }
   131  
   132  // An Uint64 is an atomic uint64. The zero value is zero.
   133  type Uint64 struct {
   134  	_ noCopy
   135  	_ align64
   136  	v uint64
   137  }
   138  
   139  // Load atomically loads and returns the value stored in x.
   140  func (x *Uint64) Load() uint64 { return LoadUint64(&x.v) }
   141  
   142  // Store atomically stores val into x.
   143  func (x *Uint64) Store(val uint64) { StoreUint64(&x.v, val) }
   144  
   145  // Swap atomically stores new into x and returns the previous value.
   146  func (x *Uint64) Swap(new uint64) (old uint64) { return SwapUint64(&x.v, new) }
   147  
   148  // CompareAndSwap executes the compare-and-swap operation for x.
   149  func (x *Uint64) CompareAndSwap(old, new uint64) (swapped bool) {
   150  	return CompareAndSwapUint64(&x.v, old, new)
   151  }
   152  
   153  // Add atomically adds delta to x and returns the new value.
   154  func (x *Uint64) Add(delta uint64) (new uint64) { return AddUint64(&x.v, delta) }
   155  
   156  // An Uintptr is an atomic uintptr. The zero value is zero.
   157  type Uintptr struct {
   158  	_ noCopy
   159  	v uintptr
   160  }
   161  
   162  // Load atomically loads and returns the value stored in x.
   163  func (x *Uintptr) Load() uintptr { return LoadUintptr(&x.v) }
   164  
   165  // Store atomically stores val into x.
   166  func (x *Uintptr) Store(val uintptr) { StoreUintptr(&x.v, val) }
   167  
   168  // Swap atomically stores new into x and returns the previous value.
   169  func (x *Uintptr) Swap(new uintptr) (old uintptr) { return SwapUintptr(&x.v, new) }
   170  
   171  // CompareAndSwap executes the compare-and-swap operation for x.
   172  func (x *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) {
   173  	return CompareAndSwapUintptr(&x.v, old, new)
   174  }
   175  
   176  // Add atomically adds delta to x and returns the new value.
   177  func (x *Uintptr) Add(delta uintptr) (new uintptr) { return AddUintptr(&x.v, delta) }
   178  
   179  // noCopy may be added to structs which must not be copied
   180  // after the first use.
   181  //
   182  // See https://golang.org/issues/8005#issuecomment-190753527
   183  // for details.
   184  //
   185  // Note that it must not be embedded, due to the Lock and Unlock methods.
   186  type noCopy struct{}
   187  
   188  // Lock is a no-op used by -copylocks checker from `go vet`.
   189  func (*noCopy) Lock()   {}
   190  func (*noCopy) Unlock() {}
   191  
   192  // align64 may be added to structs that must be 64-bit aligned.
   193  // This struct is recognized by a special case in the compiler
   194  // and will not work if copied to any other package.
   195  type align64 struct{}
   196  

View as plain text