github.com/searKing/golang/go@v1.2.74/sync/atomic/atomic.go (about)

     1  // Copyright 2020 The searKing Author. 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 (
     8  	"math"
     9  	"sync/atomic"
    10  	"time"
    11  )
    12  
    13  // Int32 is an atomic wrapper around an int32.
    14  type Int32 int32
    15  
    16  // NewInt32 creates an Int32.
    17  func NewInt32(i int32) *Int32 {
    18  	return (*Int32)(&i)
    19  }
    20  
    21  // Load atomically loads the wrapped value.
    22  func (i *Int32) Load() int32 {
    23  	return atomic.LoadInt32((*int32)(i))
    24  }
    25  
    26  // Add atomically adds to the wrapped int32 and returns the new value.
    27  func (i *Int32) Add(n int32) int32 {
    28  	return atomic.AddInt32((*int32)(i), n)
    29  }
    30  
    31  // Sub atomically subtracts from the wrapped int32 and returns the new value.
    32  func (i *Int32) Sub(n int32) int32 {
    33  	return atomic.AddInt32((*int32)(i), -n)
    34  }
    35  
    36  // Inc atomically increments the wrapped int32 and returns the new value.
    37  func (i *Int32) Inc() int32 {
    38  	return i.Add(1)
    39  }
    40  
    41  // Dec atomically decrements the wrapped int32 and returns the new value.
    42  func (i *Int32) Dec() int32 {
    43  	return i.Sub(1)
    44  }
    45  
    46  // CAS is an atomic compare-and-swap.
    47  func (i *Int32) CAS(old, new int32) bool {
    48  	return atomic.CompareAndSwapInt32((*int32)(i), old, new)
    49  }
    50  
    51  // Store atomically stores the passed value.
    52  func (i *Int32) Store(n int32) {
    53  	atomic.StoreInt32((*int32)(i), n)
    54  }
    55  
    56  // Swap atomically swaps the wrapped int32 and returns the old value.
    57  func (i *Int32) Swap(n int32) int32 {
    58  	return atomic.SwapInt32((*int32)(i), n)
    59  }
    60  
    61  // Int64 is an atomic wrapper around an int64.
    62  type Int64 int64
    63  
    64  // NewInt64 creates an Int64.
    65  func NewInt64(i int64) *Int64 {
    66  	return (*Int64)(&i)
    67  }
    68  
    69  // Load atomically loads the wrapped value.
    70  func (i *Int64) Load() int64 {
    71  	return atomic.LoadInt64((*int64)(i))
    72  }
    73  
    74  // Add atomically adds to the wrapped int64 and returns the new value.
    75  func (i *Int64) Add(n int64) int64 {
    76  	return atomic.AddInt64((*int64)(i), n)
    77  }
    78  
    79  // Sub atomically subtracts from the wrapped int64 and returns the new value.
    80  func (i *Int64) Sub(n int64) int64 {
    81  	return atomic.AddInt64((*int64)(i), -n)
    82  }
    83  
    84  // Inc atomically increments the wrapped int64 and returns the new value.
    85  func (i *Int64) Inc() int64 {
    86  	return i.Add(1)
    87  }
    88  
    89  // Dec atomically decrements the wrapped int64 and returns the new value.
    90  func (i *Int64) Dec() int64 {
    91  	return i.Sub(1)
    92  }
    93  
    94  // CAS is an atomic compare-and-swap.
    95  func (i *Int64) CAS(old, new int64) bool {
    96  	return atomic.CompareAndSwapInt64((*int64)(i), old, new)
    97  }
    98  
    99  // Store atomically stores the passed value.
   100  func (i *Int64) Store(n int64) {
   101  	atomic.StoreInt64((*int64)(i), n)
   102  }
   103  
   104  // Swap atomically swaps the wrapped int64 and returns the old value.
   105  func (i *Int64) Swap(n int64) int64 {
   106  	return atomic.SwapInt64((*int64)(i), n)
   107  }
   108  
   109  // Uint32 is an atomic wrapper around an uint32.
   110  type Uint32 uint32
   111  
   112  // NewUint32 creates a Uint32.
   113  func NewUint32(i uint32) *Uint32 {
   114  	return (*Uint32)(&i)
   115  }
   116  
   117  // Load atomically loads the wrapped value.
   118  func (i *Uint32) Load() uint32 {
   119  	return atomic.LoadUint32((*uint32)(i))
   120  }
   121  
   122  // Add atomically adds to the wrapped uint32 and returns the new value.
   123  func (i *Uint32) Add(n uint32) uint32 {
   124  	return atomic.AddUint32((*uint32)(i), n)
   125  }
   126  
   127  // Sub atomically subtracts from the wrapped uint32 and returns the new value.
   128  func (i *Uint32) Sub(n uint32) uint32 {
   129  	return atomic.AddUint32((*uint32)(i), ^(n - 1))
   130  }
   131  
   132  // Inc atomically increments the wrapped uint32 and returns the new value.
   133  func (i *Uint32) Inc() uint32 {
   134  	return i.Add(1)
   135  }
   136  
   137  // Dec atomically decrements the wrapped int32 and returns the new value.
   138  func (i *Uint32) Dec() uint32 {
   139  	return i.Sub(1)
   140  }
   141  
   142  // CAS is an atomic compare-and-swap.
   143  func (i *Uint32) CAS(old, new uint32) bool {
   144  	return atomic.CompareAndSwapUint32((*uint32)(i), old, new)
   145  }
   146  
   147  // Store atomically stores the passed value.
   148  func (i *Uint32) Store(n uint32) {
   149  	atomic.StoreUint32((*uint32)(i), n)
   150  }
   151  
   152  // Swap atomically swaps the wrapped uint32 and returns the old value.
   153  func (i *Uint32) Swap(n uint32) uint32 {
   154  	return atomic.SwapUint32((*uint32)(i), n)
   155  }
   156  
   157  // Uint64 is an atomic wrapper around a uint64.
   158  type Uint64 uint64
   159  
   160  // NewUint64 creates a Uint64.
   161  func NewUint64(i uint64) *Uint64 {
   162  	return (*Uint64)(&i)
   163  }
   164  
   165  // Load atomically loads the wrapped value.
   166  func (i *Uint64) Load() uint64 {
   167  	return atomic.LoadUint64((*uint64)(i))
   168  }
   169  
   170  // Add atomically adds to the wrapped uint64 and returns the new value.
   171  func (i *Uint64) Add(n uint64) uint64 {
   172  	return atomic.AddUint64((*uint64)(i), n)
   173  }
   174  
   175  // Sub atomically subtracts from the wrapped uint64 and returns the new value.
   176  func (i *Uint64) Sub(n uint64) uint64 {
   177  	return atomic.AddUint64((*uint64)(i), ^(n - 1))
   178  }
   179  
   180  // Inc atomically increments the wrapped uint64 and returns the new value.
   181  func (i *Uint64) Inc() uint64 {
   182  	return i.Add(1)
   183  }
   184  
   185  // Dec atomically decrements the wrapped uint64 and returns the new value.
   186  func (i *Uint64) Dec() uint64 {
   187  	return i.Sub(1)
   188  }
   189  
   190  // CAS is an atomic compare-and-swap.
   191  func (i *Uint64) CAS(old, new uint64) bool {
   192  	return atomic.CompareAndSwapUint64((*uint64)(i), old, new)
   193  }
   194  
   195  // Store atomically stores the passed value.
   196  func (i *Uint64) Store(n uint64) {
   197  	atomic.StoreUint64((*uint64)(i), n)
   198  }
   199  
   200  // Swap atomically swaps the wrapped uint64 and returns the old value.
   201  func (i *Uint64) Swap(n uint64) uint64 {
   202  	return atomic.SwapUint64((*uint64)(i), n)
   203  }
   204  
   205  // Bool is an atomic Boolean.
   206  type Bool Uint32
   207  
   208  // NewBool creates a Bool.
   209  func NewBool(initial bool) *Bool {
   210  	b := boolToUint32(initial)
   211  	return (*Bool)(&b)
   212  }
   213  
   214  // Load atomically loads the Boolean.
   215  func (b *Bool) Load() bool {
   216  
   217  	return truthy((*Uint32)(b).Load())
   218  }
   219  
   220  // CAS is an atomic compare-and-swap.
   221  func (b *Bool) CAS(old, new bool) bool {
   222  	return (*Uint32)(b).CAS(boolToUint32(old), boolToUint32(new))
   223  }
   224  
   225  // Store atomically stores the passed value.
   226  func (b *Bool) Store(new bool) {
   227  	(*Uint32)(b).Store(boolToUint32(new))
   228  }
   229  
   230  // Swap sets the given value and returns the previous value.
   231  func (b *Bool) Swap(new bool) bool {
   232  	return truthy((*Uint32)(b).Swap(boolToUint32(new)))
   233  }
   234  
   235  // Toggle atomically negates the Boolean and returns the previous value.
   236  func (b *Bool) Toggle() bool {
   237  	return truthy(atomic.AddUint32((*uint32)(b), 1) - 1)
   238  }
   239  
   240  func truthy(n uint32) bool {
   241  	return n&1 == 1
   242  }
   243  
   244  func boolToUint32(b bool) uint32 {
   245  	if b {
   246  		return 1
   247  	}
   248  	return 0
   249  }
   250  
   251  // Float64 is an atomic wrapper around float64.
   252  type Float64 uint64
   253  
   254  // NewFloat64 creates a Float64.
   255  func NewFloat64(f float64) *Float64 {
   256  	u := math.Float64bits(f)
   257  	return (*Float64)(&u)
   258  
   259  }
   260  
   261  // Load atomically loads the wrapped value.
   262  func (f *Float64) Load() float64 {
   263  	return math.Float64frombits(atomic.LoadUint64((*uint64)(f)))
   264  }
   265  
   266  // Store atomically stores the passed value.
   267  func (f *Float64) Store(s float64) {
   268  	atomic.StoreUint64((*uint64)(f), math.Float64bits(s))
   269  }
   270  
   271  // Add atomically adds to the wrapped float64 and returns the new value.
   272  func (f *Float64) Add(s float64) float64 {
   273  	for {
   274  		old := f.Load()
   275  		new := old + s
   276  		if f.CAS(old, new) {
   277  			return new
   278  		}
   279  	}
   280  }
   281  
   282  // Sub atomically subtracts from the wrapped float64 and returns the new value.
   283  func (f *Float64) Sub(s float64) float64 {
   284  	return f.Add(-s)
   285  }
   286  
   287  // CAS is an atomic compare-and-swap.
   288  func (f *Float64) CAS(old, new float64) bool {
   289  	return atomic.CompareAndSwapUint64((*uint64)(f), math.Float64bits(old), math.Float64bits(new))
   290  }
   291  
   292  // Duration is an atomic wrapper around time.Duration
   293  // https://godoc.org/time#Duration
   294  type Duration Int64
   295  
   296  // NewDuration creates a Duration.
   297  func NewDuration(d time.Duration) *Duration {
   298  	return (*Duration)(NewInt64(int64(d)))
   299  }
   300  
   301  // Load atomically loads the wrapped value.
   302  func (d *Duration) Load() time.Duration {
   303  	return time.Duration((*Int64)(d).Load())
   304  }
   305  
   306  // Store atomically stores the passed value.
   307  func (d *Duration) Store(n time.Duration) {
   308  	(*Int64)(d).Store(int64(n))
   309  }
   310  
   311  // Add atomically adds to the wrapped time.Duration and returns the new value.
   312  func (d *Duration) Add(n time.Duration) time.Duration {
   313  	return time.Duration((*Int64)(d).Add(int64(n)))
   314  }
   315  
   316  // Sub atomically subtracts from the wrapped time.Duration and returns the new value.
   317  func (d *Duration) Sub(n time.Duration) time.Duration {
   318  	return time.Duration((*Int64)(d).Sub(int64(n)))
   319  }
   320  
   321  // Swap atomically swaps the wrapped time.Duration and returns the old value.
   322  func (d *Duration) Swap(n time.Duration) time.Duration {
   323  	return time.Duration((*Int64)(d).Swap(int64(n)))
   324  }
   325  
   326  // CAS is an atomic compare-and-swap.
   327  func (d *Duration) CAS(old, new time.Duration) bool {
   328  	return (*Int64)(d).CAS(int64(old), int64(new))
   329  }
   330  
   331  // Value shadows the type of the same name from sync/atomic
   332  // https://godoc.org/sync/atomic#Value
   333  type Value atomic.Value