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  

View as plain text