diff --git a/estimator/estimator.go b/estimator/estimator.go index ef7a14d..792f064 100644 --- a/estimator/estimator.go +++ b/estimator/estimator.go @@ -1,49 +1,47 @@ package estimator import ( - "sync" "sync/atomic" "time" + + "sfu/rtptime" ) type Estimator struct { - interval time.Duration - bytes uint32 - packets uint32 - - mu sync.Mutex + interval uint64 + time uint64 + bytes uint32 + packets uint32 totalBytes uint32 totalPackets uint32 rate uint32 packetRate uint32 - time time.Time } func New(interval time.Duration) *Estimator { return &Estimator{ - interval: interval, - time: time.Now(), + interval: rtptime.FromDuration(interval, rtptime.JiffiesPerSec), + time: rtptime.Now(rtptime.JiffiesPerSec), } } -func (e *Estimator) swap(now time.Time) { - interval := now.Sub(e.time) +func (e *Estimator) swap(now uint64) { + tm := atomic.LoadUint64(&e.time) + jiffies := now - tm bytes := atomic.SwapUint32(&e.bytes, 0) packets := atomic.SwapUint32(&e.packets, 0) atomic.AddUint32(&e.totalBytes, bytes) atomic.AddUint32(&e.totalPackets, packets) - if interval < time.Millisecond { - e.rate = 0 - e.packetRate = 0 - } else { - e.rate = uint32(uint64(bytes*1000) / - uint64(interval/time.Millisecond)) - e.packetRate = uint32(uint64(packets*1000) / - uint64(interval/time.Millisecond)) - + var rate, packetRate uint32 + if jiffies >= rtptime.JiffiesPerSec/1000 { + rate = uint32(uint64(bytes) * rtptime.JiffiesPerSec / jiffies) + packetRate = + uint32(uint64(packets) * rtptime.JiffiesPerSec / jiffies) } - e.time = now + atomic.StoreUint32(&e.rate, rate) + atomic.StoreUint32(&e.packetRate, packetRate) + atomic.StoreUint64(&e.time, now) } func (e *Estimator) Accumulate(count uint32) { @@ -51,20 +49,17 @@ func (e *Estimator) Accumulate(count uint32) { atomic.AddUint32(&e.packets, 1) } -func (e *Estimator) estimate(now time.Time) (uint32, uint32) { - if now.Sub(e.time) > e.interval { +func (e *Estimator) estimate(now uint64) (uint32, uint32) { + tm := atomic.LoadUint64(&e.time) + if now < tm || now-tm > e.interval { e.swap(now) } - return e.rate, e.packetRate + return atomic.LoadUint32(&e.rate), atomic.LoadUint32(&e.packetRate) } func (e *Estimator) Estimate() (uint32, uint32) { - now := time.Now() - - e.mu.Lock() - defer e.mu.Unlock() - return e.estimate(now) + return e.estimate(rtptime.Now(rtptime.JiffiesPerSec)) } func (e *Estimator) Totals() (uint32, uint32) { diff --git a/estimator/estimator_test.go b/estimator/estimator_test.go index 21ae682..7876347 100644 --- a/estimator/estimator_test.go +++ b/estimator/estimator_test.go @@ -2,18 +2,20 @@ package estimator import ( "testing" - "time" + + "sfu/rtptime" ) func TestEstimator(t *testing.T) { - now := time.Now() - e := New(time.Second) + now := rtptime.Jiffies() + e := New(rtptime.JiffiesPerSec) e.estimate(now) e.Accumulate(42) e.Accumulate(128) - e.estimate(now.Add(time.Second)) - rate, packetRate := e.estimate(now.Add(time.Second + time.Millisecond)) + e.estimate(now + rtptime.JiffiesPerSec) + rate, packetRate := + e.estimate(now + (rtptime.JiffiesPerSec * 1001) / 1000) if rate != 42+128 { t.Errorf("Expected %v, got %v", 42+128, rate)