From 3332118be2dca1cd72c0a1d8523cc4fbf31f4311 Mon Sep 17 00:00:00 2001 From: xieyuschen Date: Mon, 18 Mar 2024 22:31:39 +0800 Subject: [PATCH] fix: fix the possible overflow --- prometheus/counter.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/prometheus/counter.go b/prometheus/counter.go index 4ce84e7..b10ab3d 100644 --- a/prometheus/counter.go +++ b/prometheus/counter.go @@ -129,11 +129,22 @@ func (c *counter) Add(v float64) { } ival := uint64(v) - if float64(ival) == v { - atomic.AddUint64(&c.valInt, ival) - return - } + // if the v is an unsigned integer + // and the precise doesn't lose during uint cast and cast it back to float + for v == float64(ival) { + oldUint := atomic.LoadUint64(&c.valInt) + leftNum := math.MaxUint64 - oldUint + + if leftNum < ival { + // overflow happens, we need to handle as a float number + break + } + if atomic.CompareAndSwapUint64(&c.valInt, oldUint, oldUint+ival) { + return + } + + } for { oldBits := atomic.LoadUint64(&c.valBits) newBits := math.Float64bits(math.Float64frombits(oldBits) + v)