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 }