try to fix int max perf counter bug
This commit is contained in:
parent
ea1037bd63
commit
af7b6ebbcb
@ -2,9 +2,8 @@ package counters
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
|
||||||
"math"
|
"math"
|
||||||
|
"time"
|
||||||
|
|
||||||
c "github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
qgen "github.com/Azareal/Gosora/query_gen"
|
qgen "github.com/Azareal/Gosora/query_gen"
|
||||||
@ -30,7 +29,7 @@ func NewDefaultPerfCounter(acc *qgen.Accumulator) (*DefaultPerfCounter, error) {
|
|||||||
co := &DefaultPerfCounter{
|
co := &DefaultPerfCounter{
|
||||||
buckets: []PerfCounterBucket{
|
buckets: []PerfCounterBucket{
|
||||||
PerfCounterBucket{
|
PerfCounterBucket{
|
||||||
low: &MutexCounter64Bucket{counter: 0},
|
low: &MutexCounter64Bucket{counter: math.MaxInt64},
|
||||||
high: &MutexCounter64Bucket{counter: 0},
|
high: &MutexCounter64Bucket{counter: 0},
|
||||||
avg: &MutexCounter64Bucket{counter: 0},
|
avg: &MutexCounter64Bucket{counter: 0},
|
||||||
},
|
},
|
||||||
@ -45,11 +44,19 @@ func NewDefaultPerfCounter(acc *qgen.Accumulator) (*DefaultPerfCounter, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (co *DefaultPerfCounter) Tick() error {
|
func (co *DefaultPerfCounter) Tick() error {
|
||||||
getCounter := func(b *MutexCounter64Bucket) int64 {
|
getCounter := func(b *MutexCounter64Bucket) (c int64) {
|
||||||
return atomic.SwapInt64(&b.counter, 0)
|
b.Lock()
|
||||||
|
c = b.counter
|
||||||
|
b.counter = 0
|
||||||
|
b.Unlock()
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
for _, b := range co.buckets {
|
for _, b := range co.buckets {
|
||||||
low := atomic.SwapInt64(&b.low.counter, math.MaxInt64)
|
var low int64
|
||||||
|
b.low.Lock()
|
||||||
|
low = b.low.counter
|
||||||
|
b.low.counter = math.MaxInt64
|
||||||
|
b.low.Unlock()
|
||||||
if low == math.MaxInt64 {
|
if low == math.MaxInt64 {
|
||||||
low = 0
|
low = 0
|
||||||
}
|
}
|
||||||
@ -73,41 +80,34 @@ func (co *DefaultPerfCounter) insertChunk(low, high, avg int64) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (co *DefaultPerfCounter) Push(dur time.Duration) {
|
func (co *DefaultPerfCounter) Push(dur time.Duration /*_ bool*/) {
|
||||||
id := 0
|
id := 0
|
||||||
b := co.buckets[id]
|
b := co.buckets[id]
|
||||||
//c.DebugDetail("co.buckets[", id, "]: ", b)
|
//c.DebugDetail("buckets[", id, "]: ", b)
|
||||||
micro := dur.Microseconds()
|
micro := dur.Microseconds()
|
||||||
|
|
||||||
low := b.low
|
low := b.low
|
||||||
if micro < low.counter {
|
|
||||||
low.Lock()
|
low.Lock()
|
||||||
if micro < low.counter {
|
if micro < low.counter {
|
||||||
atomic.StoreInt64(&low.counter,micro)
|
low.counter = micro
|
||||||
}
|
}
|
||||||
low.Unlock()
|
low.Unlock()
|
||||||
}
|
|
||||||
|
|
||||||
high := b.high
|
high := b.high
|
||||||
if micro > high.counter {
|
|
||||||
high.Lock()
|
high.Lock()
|
||||||
if micro > high.counter {
|
if micro > high.counter {
|
||||||
atomic.StoreInt64(&high.counter,micro)
|
high.counter = micro
|
||||||
}
|
}
|
||||||
high.Unlock()
|
high.Unlock()
|
||||||
}
|
|
||||||
|
|
||||||
avg := b.avg
|
avg := b.avg
|
||||||
// TODO: Sync semantics are slightly loose but it should be close enough for our purposes here
|
|
||||||
if micro != avg.counter {
|
|
||||||
t := false
|
|
||||||
avg.Lock()
|
avg.Lock()
|
||||||
|
if micro != avg.counter {
|
||||||
if avg.counter == 0 {
|
if avg.counter == 0 {
|
||||||
t = atomic.CompareAndSwapInt64(&avg.counter, 0, micro)
|
avg.counter = micro
|
||||||
|
} else {
|
||||||
|
avg.counter = (micro + avg.counter) / 2
|
||||||
}
|
}
|
||||||
if !t && micro != avg.counter {
|
|
||||||
atomic.StoreInt64(&avg.counter,(micro+avg.counter) / 2)
|
|
||||||
}
|
}
|
||||||
avg.Unlock()
|
avg.Unlock()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user