micro-meter-prometheus/counter.go
Vasiliy Tolstov d4472e1ab2
Some checks failed
codeql / analyze (go) (push) Failing after 49s
build / test (push) Failing after 4m54s
build / lint (push) Successful in 9m28s
partially fix race cond
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-11-08 15:27:05 +03:00

94 lines
1.7 KiB
Go

package prometheus
import (
"math"
"sync/atomic"
"unsafe"
dto "github.com/prometheus/client_model/go"
)
type prometheusCounter struct {
name string
c *dto.Metric
n float64
}
func (c *prometheusCounter) Add(n int) {
addFloat64(&(c.n), float64(n))
}
func (c *prometheusCounter) Dec() {
addFloat64(&(c.n), float64(-1))
}
func (c *prometheusCounter) Inc() {
addFloat64(&(c.n), float64(1))
}
func (c *prometheusCounter) Get() uint64 {
return uint64(getFloat64(&(c.n)))
}
func (c *prometheusCounter) Set(n uint64) {
setFloat64(&(c.n), math.Float64frombits(n))
}
type prometheusFloatCounter struct {
name string
c *dto.Metric
n float64
}
func (c *prometheusFloatCounter) Add(n float64) {
addFloat64(&(c.n), n)
}
func (c *prometheusFloatCounter) Dec() {
addFloat64(&(c.n), float64(-1))
}
func (c *prometheusFloatCounter) Inc() {
addFloat64(&(c.n), float64(1))
}
func (c *prometheusFloatCounter) Get() float64 {
return getFloat64(&(c.n))
}
func (c *prometheusFloatCounter) Set(n float64) {
setFloat64(&(c.n), n)
}
func (c *prometheusFloatCounter) Sub(n float64) {
addFloat64(&(c.n), -n)
}
func setFloat64(_addr *float64, value float64) float64 {
addr := (*uint64)(unsafe.Pointer(_addr))
for {
x := atomic.LoadUint64(addr)
if atomic.CompareAndSwapUint64(addr, x, math.Float64bits(value)) {
return value
}
}
}
func addFloat64(_addr *float64, delta float64) float64 {
addr := (*uint64)(unsafe.Pointer(_addr))
for {
x := atomic.LoadUint64(addr)
y := math.Float64frombits(x) + delta
if atomic.CompareAndSwapUint64(addr, x, math.Float64bits(y)) {
return y
}
}
}
func getFloat64(_addr *float64) float64 {
addr := (*uint64)(unsafe.Pointer(_addr))
x := atomic.LoadUint64(addr)
y := math.Float64frombits(x)
return y
}