github.com/ethereum/go-ethereum@v1.16.1/metrics/counter_float64.go (about)

     1  package metrics
     2  
     3  import (
     4  	"math"
     5  	"sync/atomic"
     6  )
     7  
     8  // GetOrRegisterCounterFloat64 returns an existing *CounterFloat64 or constructs and registers
     9  // a new CounterFloat64.
    10  func GetOrRegisterCounterFloat64(name string, r Registry) *CounterFloat64 {
    11  	return getOrRegister(name, NewCounterFloat64, r)
    12  }
    13  
    14  // NewCounterFloat64 constructs a new CounterFloat64.
    15  func NewCounterFloat64() *CounterFloat64 {
    16  	return new(CounterFloat64)
    17  }
    18  
    19  // NewRegisteredCounterFloat64 constructs and registers a new CounterFloat64.
    20  func NewRegisteredCounterFloat64(name string, r Registry) *CounterFloat64 {
    21  	c := NewCounterFloat64()
    22  	if r == nil {
    23  		r = DefaultRegistry
    24  	}
    25  	r.Register(name, c)
    26  	return c
    27  }
    28  
    29  // CounterFloat64Snapshot is a read-only copy of a float64 counter.
    30  type CounterFloat64Snapshot float64
    31  
    32  // Count returns the value at the time the snapshot was taken.
    33  func (c CounterFloat64Snapshot) Count() float64 { return float64(c) }
    34  
    35  // CounterFloat64 holds a float64 value that can be incremented and decremented.
    36  type CounterFloat64 atomic.Uint64
    37  
    38  // Clear sets the counter to zero.
    39  func (c *CounterFloat64) Clear() {
    40  	(*atomic.Uint64)(c).Store(0)
    41  }
    42  
    43  // Dec decrements the counter by the given amount.
    44  func (c *CounterFloat64) Dec(v float64) {
    45  	atomicAddFloat((*atomic.Uint64)(c), -v)
    46  }
    47  
    48  // Inc increments the counter by the given amount.
    49  func (c *CounterFloat64) Inc(v float64) {
    50  	atomicAddFloat((*atomic.Uint64)(c), v)
    51  }
    52  
    53  // Snapshot returns a read-only copy of the counter.
    54  func (c *CounterFloat64) Snapshot() CounterFloat64Snapshot {
    55  	return CounterFloat64Snapshot(math.Float64frombits((*atomic.Uint64)(c).Load()))
    56  }
    57  
    58  func atomicAddFloat(fbits *atomic.Uint64, v float64) {
    59  	for {
    60  		loadedBits := fbits.Load()
    61  		newBits := math.Float64bits(math.Float64frombits(loadedBits) + v)
    62  		if fbits.CompareAndSwap(loadedBits, newBits) {
    63  			break
    64  		}
    65  	}
    66  }