forked from Netflix/spectator-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatomicnum.go
54 lines (45 loc) · 1.22 KB
/
atomicnum.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package spectator
import (
"math"
"sync/atomic"
)
/*
From the Go sync/atomic docs:
> On ARM, x86-32, and 32-bit MIPS, it is the caller's responsibility to arrange
> for 64-bit alignment of 64-bit words accessed atomically. The first word in a
> variable or in an allocated struct, array, or slice can be relied upon to be
> 64-bit aligned.
So to avoid SIGSEGVs on these platforms, make sure the pointers passed into
these methods come from variables that are properly aligned.
*/
func addFloat64(addr *uint64, delta float64) {
for {
old := loadFloat64(addr)
newVal := old + delta
if atomic.CompareAndSwapUint64(
addr,
math.Float64bits(old),
math.Float64bits(newVal),
) {
break
}
}
}
func updateMax(addr *int64, v int64) {
m := atomic.LoadInt64(addr)
for v > m {
if atomic.CompareAndSwapInt64(addr, m, v) {
break
}
m = atomic.LoadInt64(addr)
}
}
func swapFloat64(addr *uint64, newVal float64) float64 {
return math.Float64frombits(atomic.SwapUint64(addr, math.Float64bits(newVal)))
}
func loadFloat64(addr *uint64) float64 {
return math.Float64frombits(atomic.LoadUint64(addr))
}
func storeFloat64(addr *uint64, newVal float64) {
atomic.StoreUint64(addr, math.Float64bits(newVal))
}