@@ -101,7 +101,11 @@ func NewRegisteredMeterForced(name string, r Registry) Meter {
101
101
102
102
// MeterSnapshot is a read-only copy of another Meter.
103
103
type MeterSnapshot struct {
104
- temp atomic.Int64
104
+ // WARNING: The `temp` field is accessed atomically.
105
+ // On 32 bit platforms, only 64-bit aligned fields can be atomic. The struct is
106
+ // guaranteed to be so aligned, so take advantage of that. For more information,
107
+ // see https://golang.org/pkg/sync/atomic/#pkg-note-BUG.
108
+ temp int64
105
109
count int64
106
110
rate1 , rate5 , rate15 , rateMean float64
107
111
}
@@ -169,7 +173,7 @@ type StandardMeter struct {
169
173
snapshot * MeterSnapshot
170
174
a1 , a5 , a15 EWMA
171
175
startTime time.Time
172
- stopped atomic. Bool
176
+ stopped uint32
173
177
}
174
178
175
179
func newStandardMeter () * StandardMeter {
@@ -184,8 +188,8 @@ func newStandardMeter() *StandardMeter {
184
188
185
189
// Stop stops the meter, Mark() will be a no-op if you use it after being stopped.
186
190
func (m * StandardMeter ) Stop () {
187
- stopped := m .stopped . Swap ( true )
188
- if ! stopped {
191
+ stopped := atomic . SwapUint32 ( & m .stopped , 1 )
192
+ if stopped != 1 {
189
193
arbiter .Lock ()
190
194
delete (arbiter .meters , m )
191
195
arbiter .Unlock ()
@@ -203,7 +207,7 @@ func (m *StandardMeter) Count() int64 {
203
207
204
208
// Mark records the occurrence of n events.
205
209
func (m * StandardMeter ) Mark (n int64 ) {
206
- m .snapshot .temp . Add ( n )
210
+ atomic . AddInt64 ( & m .snapshot .temp , n )
207
211
}
208
212
209
213
// Rate1 returns the one-minute moving average rate of events per second.
@@ -237,14 +241,7 @@ func (m *StandardMeter) RateMean() float64 {
237
241
// Snapshot returns a read-only copy of the meter.
238
242
func (m * StandardMeter ) Snapshot () Meter {
239
243
m .lock .RLock ()
240
- snapshot := MeterSnapshot {
241
- count : m .snapshot .count ,
242
- rate1 : m .snapshot .rate1 ,
243
- rate5 : m .snapshot .rate5 ,
244
- rate15 : m .snapshot .rate15 ,
245
- rateMean : m .snapshot .rateMean ,
246
- }
247
- snapshot .temp .Store (m .snapshot .temp .Load ())
244
+ snapshot := * m .snapshot
248
245
m .lock .RUnlock ()
249
246
return & snapshot
250
247
}
@@ -260,7 +257,7 @@ func (m *StandardMeter) updateSnapshot() {
260
257
261
258
func (m * StandardMeter ) updateMeter () {
262
259
// should only run with write lock held on m.lock
263
- n := m .snapshot .temp . Swap ( 0 )
260
+ n := atomic . SwapInt64 ( & m .snapshot .temp , 0 )
264
261
m .snapshot .count += n
265
262
m .a1 .Update (n )
266
263
m .a5 .Update (n )
0 commit comments