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