github.com/lyft/flytestdlib@v0.3.12-0.20210213045714-8cdd111ecda1/atomic/atomic.go (about)

     1  package atomic
     2  
     3  import "sync/atomic"
     4  
     5  // This file contains some simplified atomics primitives that Golang default library does not offer
     6  // like, Boolean
     7  
     8  // Takes in a uint32 and converts to bool by checking whether the last bit is set to 1
     9  func toBool(n uint32) bool {
    10  	return n&1 == 1
    11  }
    12  
    13  // Takes in a bool and returns a uint32 representation
    14  func toInt(b bool) uint32 {
    15  	if b {
    16  		return 1
    17  	}
    18  	return 0
    19  }
    20  
    21  // Bool is an atomic Boolean.
    22  // It stores the bool as a uint32 internally. This is to use the uint32 atomic functions available in golang
    23  type Bool struct{ v uint32 }
    24  
    25  // NewBool creates a Bool.
    26  func NewBool(initial bool) Bool {
    27  	return Bool{v: toInt(initial)}
    28  }
    29  
    30  // Load atomically loads the Boolean.
    31  func (b *Bool) Load() bool {
    32  	return toBool(atomic.LoadUint32(&b.v))
    33  }
    34  
    35  // CAS is an atomic compare-and-swap.
    36  func (b *Bool) CompareAndSwap(old, new bool) bool {
    37  	return atomic.CompareAndSwapUint32(&b.v, toInt(old), toInt(new))
    38  }
    39  
    40  // Store atomically stores the passed value.
    41  func (b *Bool) Store(new bool) {
    42  	atomic.StoreUint32(&b.v, toInt(new))
    43  }
    44  
    45  // Swap sets the given value and returns the previous value.
    46  func (b *Bool) Swap(new bool) bool {
    47  	return toBool(atomic.SwapUint32(&b.v, toInt(new)))
    48  }
    49  
    50  // Toggle atomically negates the Boolean and returns the previous value.
    51  func (b *Bool) Toggle() bool {
    52  	return toBool(atomic.AddUint32(&b.v, 1) - 1)
    53  }
    54  
    55  type Uint32 struct {
    56  	v uint32
    57  }
    58  
    59  // Returns a loaded uint32 value
    60  func (u *Uint32) Load() uint32 {
    61  	return atomic.LoadUint32(&u.v)
    62  }
    63  
    64  // CAS is an atomic compare-and-swap.
    65  func (u *Uint32) CompareAndSwap(old, new uint32) bool {
    66  	return atomic.CompareAndSwapUint32(&u.v, old, new)
    67  }
    68  
    69  // Add a delta to the number
    70  func (u *Uint32) Add(delta uint32) uint32 {
    71  	return atomic.AddUint32(&u.v, delta)
    72  }
    73  
    74  // Increment the value
    75  func (u *Uint32) Inc() uint32 {
    76  	return atomic.AddUint32(&u.v, 1)
    77  }
    78  
    79  // Set the value
    80  func (u *Uint32) Store(v uint32) {
    81  	atomic.StoreUint32(&u.v, v)
    82  }
    83  
    84  func NewUint32(v uint32) Uint32 {
    85  	return Uint32{v: v}
    86  }
    87  
    88  type Int32 struct {
    89  	v int32
    90  }
    91  
    92  // Returns a loaded uint32 value
    93  func (i *Int32) Load() int32 {
    94  	return atomic.LoadInt32(&i.v)
    95  }
    96  
    97  // CAS is an atomic compare-and-swap.
    98  func (i *Int32) CompareAndSwap(old, new int32) bool {
    99  	return atomic.CompareAndSwapInt32(&i.v, old, new)
   100  }
   101  
   102  // Add a delta to the number
   103  func (i *Int32) Add(delta int32) int32 {
   104  	return atomic.AddInt32(&i.v, delta)
   105  }
   106  
   107  // Subtract a delta from the number
   108  func (i *Int32) Sub(delta int32) int32 {
   109  	return atomic.AddInt32(&i.v, -delta)
   110  }
   111  
   112  // Increment the value
   113  func (i *Int32) Inc() int32 {
   114  	return atomic.AddInt32(&i.v, 1)
   115  }
   116  
   117  // Decrement the value
   118  func (i *Int32) Dec() int32 {
   119  	return atomic.AddInt32(&i.v, -1)
   120  }
   121  
   122  // Set the value
   123  func (i *Int32) Store(v int32) {
   124  	atomic.StoreInt32(&i.v, v)
   125  }
   126  
   127  func NewInt32(v int32) Int32 {
   128  	return Int32{v: v}
   129  }