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