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  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  // And atomically performs a bitwise AND operation on x using the bitmask
    91  // provided as mask and returns the old value.
    92  func (x *Int32) And(mask int32) (old int32) { return AndInt32(&x.v, mask) }
    93  
    94  // Or atomically performs a bitwise OR operation on x using the bitmask
    95  // provided as mask and returns the old value.
    96  func (x *Int32) Or(mask int32) (old int32) { return OrInt32(&x.v, mask) }
    97  
    98  // An Int64 is an atomic int64. The zero value is zero.
    99  type Int64 struct {
   100  	_ noCopy
   101  	_ align64
   102  	v int64
   103  }
   104  
   105  // Load atomically loads and returns the value stored in x.
   106  func (x *Int64) Load() int64 { return LoadInt64(&x.v) }
   107  
   108  // Store atomically stores val into x.
   109  func (x *Int64) Store(val int64) { StoreInt64(&x.v, val) }
   110  
   111  // Swap atomically stores new into x and returns the previous value.
   112  func (x *Int64) Swap(new int64) (old int64) { return SwapInt64(&x.v, new) }
   113  
   114  // CompareAndSwap executes the compare-and-swap operation for x.
   115  func (x *Int64) CompareAndSwap(old, new int64) (swapped bool) {
   116  	return CompareAndSwapInt64(&x.v, old, new)
   117  }
   118  
   119  // Add atomically adds delta to x and returns the new value.
   120  func (x *Int64) Add(delta int64) (new int64) { return AddInt64(&x.v, delta) }
   121  
   122  // And atomically performs a bitwise AND operation on x using the bitmask
   123  // provided as mask and returns the old value.
   124  func (x *Int64) And(mask int64) (old int64) { return AndInt64(&x.v, mask) }
   125  
   126  // Or atomically performs a bitwise OR operation on x using the bitmask
   127  // provided as mask and returns the old value.
   128  func (x *Int64) Or(mask int64) (old int64) { return OrInt64(&x.v, mask) }
   129  
   130  // A Uint32 is an atomic uint32. The zero value is zero.
   131  type Uint32 struct {
   132  	_ noCopy
   133  	v uint32
   134  }
   135  
   136  // Load atomically loads and returns the value stored in x.
   137  func (x *Uint32) Load() uint32 { return LoadUint32(&x.v) }
   138  
   139  // Store atomically stores val into x.
   140  func (x *Uint32) Store(val uint32) { StoreUint32(&x.v, val) }
   141  
   142  // Swap atomically stores new into x and returns the previous value.
   143  func (x *Uint32) Swap(new uint32) (old uint32) { return SwapUint32(&x.v, new) }
   144  
   145  // CompareAndSwap executes the compare-and-swap operation for x.
   146  func (x *Uint32) CompareAndSwap(old, new uint32) (swapped bool) {
   147  	return CompareAndSwapUint32(&x.v, old, new)
   148  }
   149  
   150  // Add atomically adds delta to x and returns the new value.
   151  func (x *Uint32) Add(delta uint32) (new uint32) { return AddUint32(&x.v, delta) }
   152  
   153  // And atomically performs a bitwise AND operation on x using the bitmask
   154  // provided as mask and returns the old value.
   155  func (x *Uint32) And(mask uint32) (old uint32) { return AndUint32(&x.v, mask) }
   156  
   157  // Or atomically performs a bitwise OR operation on x using the bitmask
   158  // provided as mask and returns the old value.
   159  func (x *Uint32) Or(mask uint32) (old uint32) { return OrUint32(&x.v, mask) }
   160  
   161  // A Uint64 is an atomic uint64. The zero value is zero.
   162  type Uint64 struct {
   163  	_ noCopy
   164  	_ align64
   165  	v uint64
   166  }
   167  
   168  // Load atomically loads and returns the value stored in x.
   169  func (x *Uint64) Load() uint64 { return LoadUint64(&x.v) }
   170  
   171  // Store atomically stores val into x.
   172  func (x *Uint64) Store(val uint64) { StoreUint64(&x.v, val) }
   173  
   174  // Swap atomically stores new into x and returns the previous value.
   175  func (x *Uint64) Swap(new uint64) (old uint64) { return SwapUint64(&x.v, new) }
   176  
   177  // CompareAndSwap executes the compare-and-swap operation for x.
   178  func (x *Uint64) CompareAndSwap(old, new uint64) (swapped bool) {
   179  	return CompareAndSwapUint64(&x.v, old, new)
   180  }
   181  
   182  // Add atomically adds delta to x and returns the new value.
   183  func (x *Uint64) Add(delta uint64) (new uint64) { return AddUint64(&x.v, delta) }
   184  
   185  // And atomically performs a bitwise AND operation on x using the bitmask
   186  // provided as mask and returns the old value.
   187  func (x *Uint64) And(mask uint64) (old uint64) { return AndUint64(&x.v, mask) }
   188  
   189  // Or atomically performs a bitwise OR operation on x using the bitmask
   190  // provided as mask and returns the old value.
   191  func (x *Uint64) Or(mask uint64) (old uint64) { return OrUint64(&x.v, mask) }
   192  
   193  // A Uintptr is an atomic uintptr. The zero value is zero.
   194  type Uintptr struct {
   195  	_ noCopy
   196  	v uintptr
   197  }
   198  
   199  // Load atomically loads and returns the value stored in x.
   200  func (x *Uintptr) Load() uintptr { return LoadUintptr(&x.v) }
   201  
   202  // Store atomically stores val into x.
   203  func (x *Uintptr) Store(val uintptr) { StoreUintptr(&x.v, val) }
   204  
   205  // Swap atomically stores new into x and returns the previous value.
   206  func (x *Uintptr) Swap(new uintptr) (old uintptr) { return SwapUintptr(&x.v, new) }
   207  
   208  // CompareAndSwap executes the compare-and-swap operation for x.
   209  func (x *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) {
   210  	return CompareAndSwapUintptr(&x.v, old, new)
   211  }
   212  
   213  // Add atomically adds delta to x and returns the new value.
   214  func (x *Uintptr) Add(delta uintptr) (new uintptr) { return AddUintptr(&x.v, delta) }
   215  
   216  // And atomically performs a bitwise AND operation on x using the bitmask
   217  // provided as mask and returns the old value.
   218  func (x *Uintptr) And(mask uintptr) (old uintptr) { return AndUintptr(&x.v, mask) }
   219  
   220  // Or atomically performs a bitwise OR operation on x using the bitmask
   221  // provided as mask and returns the updated value after the OR operation.
   222  func (x *Uintptr) Or(mask uintptr) (old uintptr) { return OrUintptr(&x.v, mask) }
   223  
   224  // noCopy may be added to structs which must not be copied
   225  // after the first use.
   226  //
   227  // See https://golang.org/issues/8005#issuecomment-190753527
   228  // for details.
   229  //
   230  // Note that it must not be embedded, due to the Lock and Unlock methods.
   231  type noCopy struct{}
   232  
   233  // Lock is a no-op used by -copylocks checker from `go vet`.
   234  func (*noCopy) Lock()   {}
   235  func (*noCopy) Unlock() {}
   236  
   237  // align64 may be added to structs that must be 64-bit aligned.
   238  // This struct is recognized by a special case in the compiler
   239  // and will not work if copied to any other package.
   240  type align64 struct{}
   241  

View as plain text