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