11package metrics
22
33import (
4+ "math"
45 "sync"
6+ "sync/atomic"
57 "time"
68)
79
@@ -62,7 +64,7 @@ func NewRegisteredMeter(name string, r Registry) Meter {
6264// MeterSnapshot is a read-only copy of another Meter.
6365type MeterSnapshot struct {
6466 count int64
65- rate1 , rate5 , rate15 , rateMean float64
67+ rate1 , rate5 , rate15 , rateMean uint64
6668}
6769
6870// Count returns the count of events at the time the snapshot was taken.
@@ -75,19 +77,19 @@ func (*MeterSnapshot) Mark(n int64) {
7577
7678// Rate1 returns the one-minute moving average rate of events per second at the
7779// time the snapshot was taken.
78- func (m * MeterSnapshot ) Rate1 () float64 { return m .rate1 }
80+ func (m * MeterSnapshot ) Rate1 () float64 { return math . Float64frombits ( m .rate1 ) }
7981
8082// Rate5 returns the five-minute moving average rate of events per second at
8183// the time the snapshot was taken.
82- func (m * MeterSnapshot ) Rate5 () float64 { return m .rate5 }
84+ func (m * MeterSnapshot ) Rate5 () float64 { return math . Float64frombits ( m .rate5 ) }
8385
8486// Rate15 returns the fifteen-minute moving average rate of events per second
8587// at the time the snapshot was taken.
86- func (m * MeterSnapshot ) Rate15 () float64 { return m .rate15 }
88+ func (m * MeterSnapshot ) Rate15 () float64 { return math . Float64frombits ( m .rate15 ) }
8789
8890// RateMean returns the meter's mean rate of events per second at the time the
8991// snapshot was taken.
90- func (m * MeterSnapshot ) RateMean () float64 { return m .rateMean }
92+ func (m * MeterSnapshot ) RateMean () float64 { return math . Float64frombits ( m .rateMean ) }
9193
9294// Snapshot returns the snapshot.
9395func (m * MeterSnapshot ) Snapshot () Meter { return m }
@@ -124,11 +126,12 @@ func (NilMeter) Stop() {}
124126
125127// StandardMeter is the standard implementation of a Meter.
126128type StandardMeter struct {
127- lock sync.RWMutex
129+ // Only used on stop.
130+ lock sync.Mutex
128131 snapshot * MeterSnapshot
129132 a1 , a5 , a15 EWMA
130133 startTime time.Time
131- stopped bool
134+ stopped uint32
132135}
133136
134137func newStandardMeter () * StandardMeter {
@@ -145,9 +148,9 @@ func newStandardMeter() *StandardMeter {
145148func (m * StandardMeter ) Stop () {
146149 m .lock .Lock ()
147150 stopped := m .stopped
148- m .stopped = true
151+ m .stopped = 1
149152 m .lock .Unlock ()
150- if ! stopped {
153+ if stopped != 1 {
151154 arbiter .Lock ()
152155 delete (arbiter .meters , m )
153156 arbiter .Unlock ()
@@ -156,20 +159,17 @@ func (m *StandardMeter) Stop() {
156159
157160// Count returns the number of events recorded.
158161func (m * StandardMeter ) Count () int64 {
159- m .lock .RLock ()
160- count := m .snapshot .count
161- m .lock .RUnlock ()
162- return count
162+ return atomic .LoadInt64 (& m .snapshot .count )
163163}
164164
165165// Mark records the occurance of n events.
166166func (m * StandardMeter ) Mark (n int64 ) {
167- m .lock .Lock ()
168- defer m .lock .Unlock ()
169- if m .stopped {
167+ if atomic .LoadUint32 (& m .stopped ) == 1 {
170168 return
171169 }
172- m .snapshot .count += n
170+
171+ atomic .AddInt64 (& m .snapshot .count , n )
172+
173173 m .a1 .Update (n )
174174 m .a5 .Update (n )
175175 m .a15 .Update (n )
@@ -178,56 +178,49 @@ func (m *StandardMeter) Mark(n int64) {
178178
179179// Rate1 returns the one-minute moving average rate of events per second.
180180func (m * StandardMeter ) Rate1 () float64 {
181- m .lock .RLock ()
182- rate1 := m .snapshot .rate1
183- m .lock .RUnlock ()
184- return rate1
181+ return math .Float64frombits (atomic .LoadUint64 (& m .snapshot .rate1 ))
185182}
186183
187184// Rate5 returns the five-minute moving average rate of events per second.
188185func (m * StandardMeter ) Rate5 () float64 {
189- m .lock .RLock ()
190- rate5 := m .snapshot .rate5
191- m .lock .RUnlock ()
192- return rate5
186+ return math .Float64frombits (atomic .LoadUint64 (& m .snapshot .rate5 ))
193187}
194188
195189// Rate15 returns the fifteen-minute moving average rate of events per second.
196190func (m * StandardMeter ) Rate15 () float64 {
197- m .lock .RLock ()
198- rate15 := m .snapshot .rate15
199- m .lock .RUnlock ()
200- return rate15
191+ return math .Float64frombits (atomic .LoadUint64 (& m .snapshot .rate15 ))
201192}
202193
203194// RateMean returns the meter's mean rate of events per second.
204195func (m * StandardMeter ) RateMean () float64 {
205- m .lock .RLock ()
206- rateMean := m .snapshot .rateMean
207- m .lock .RUnlock ()
208- return rateMean
196+ return math .Float64frombits (atomic .LoadUint64 (& m .snapshot .rateMean ))
209197}
210198
211199// Snapshot returns a read-only copy of the meter.
212200func (m * StandardMeter ) Snapshot () Meter {
213- m .lock .RLock ()
214- snapshot := * m .snapshot
215- m .lock .RUnlock ()
216- return & snapshot
201+ copiedSnapshot := MeterSnapshot {
202+ count : atomic .LoadInt64 (& m .snapshot .count ),
203+ rate1 : atomic .LoadUint64 (& m .snapshot .rate1 ),
204+ rate5 : atomic .LoadUint64 (& m .snapshot .rate5 ),
205+ rate15 : atomic .LoadUint64 (& m .snapshot .rate15 ),
206+ rateMean : atomic .LoadUint64 (& m .snapshot .rateMean ),
207+ }
208+ return & copiedSnapshot
217209}
218210
219211func (m * StandardMeter ) updateSnapshot () {
220- // should run with write lock held on m.lock
221- snapshot := m .snapshot
222- snapshot .rate1 = m .a1 .Rate ()
223- snapshot .rate5 = m .a5 .Rate ()
224- snapshot .rate15 = m .a15 .Rate ()
225- snapshot .rateMean = float64 (snapshot .count ) / time .Since (m .startTime ).Seconds ()
212+ rate1 := math .Float64bits (m .a1 .Rate ())
213+ rate5 := math .Float64bits (m .a5 .Rate ())
214+ rate15 := math .Float64bits (m .a15 .Rate ())
215+ rateMean := math .Float64bits (float64 (m .Count ()) / time .Since (m .startTime ).Seconds ())
216+
217+ atomic .StoreUint64 (& m .snapshot .rate1 , rate1 )
218+ atomic .StoreUint64 (& m .snapshot .rate5 , rate5 )
219+ atomic .StoreUint64 (& m .snapshot .rate15 , rate15 )
220+ atomic .StoreUint64 (& m .snapshot .rateMean , rateMean )
226221}
227222
228223func (m * StandardMeter ) tick () {
229- m .lock .Lock ()
230- defer m .lock .Unlock ()
231224 m .a1 .Tick ()
232225 m .a5 .Tick ()
233226 m .a15 .Tick ()
0 commit comments