-
Notifications
You must be signed in to change notification settings - Fork 0
/
counter.go
58 lines (48 loc) · 997 Bytes
/
counter.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
55
56
57
58
package perp
import (
"sync/atomic"
)
// Counter is sharded across processors in Go runtime.
type Counter struct {
vs *Values[*counter]
}
// NewCounter returns a new Counter initialized to zero.
func NewCounter() *Counter {
vs := NewValues(func() *counter {
return &counter{}
})
return &Counter{vs: vs}
}
// Add n to the counter.
func (c *Counter) Add(n int64) {
c.vs.Get().Add(n)
}
// Load the total counter value.
func (c *Counter) Load() int64 {
var sum int64
c.vs.Iter(func(v *counter) {
sum += v.Load()
})
return sum
}
// Reset the counter to zero and return the old value.
func (c *Counter) Reset() int64 {
var sum int64
c.vs.Iter(func(v *counter) {
sum += v.Reset()
})
return sum
}
type counter struct {
n int64
_ [56]byte // cache line aligment
}
func (c *counter) Add(n int64) int64 {
return atomic.AddInt64(&c.n, n)
}
func (c *counter) Load() int64 {
return atomic.LoadInt64(&c.n)
}
func (c *counter) Reset() int64 {
return atomic.SwapInt64(&c.n, 0)
}