mirror of
https://github.com/jech/galene.git
synced 2024-11-08 17:55:59 +01:00
Avoid overflow in FromDuration and ToDuration.
Thanks to lamhai1401.
This commit is contained in:
parent
7d01f0339b
commit
b4edb7c0c7
2 changed files with 34 additions and 10 deletions
|
@ -2,6 +2,7 @@
|
|||
package rtptime
|
||||
|
||||
import (
|
||||
"math/bits"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -9,25 +10,29 @@ import (
|
|||
var epoch = time.Now()
|
||||
|
||||
// FromDuration converts a time.Duration into units of 1/hz.
|
||||
// Negative values are clamped to zero.
|
||||
func FromDuration(d time.Duration, hz uint32) int64 {
|
||||
return int64(d) * int64(hz) / int64(time.Second)
|
||||
if d < 0 {
|
||||
return -FromDuration(-d, hz)
|
||||
}
|
||||
hi, lo := bits.Mul64(uint64(d), uint64(hz))
|
||||
q, _ := bits.Div64(hi, lo, uint64(time.Second))
|
||||
return int64(q)
|
||||
}
|
||||
|
||||
// ToDuration converts units of 1/hz into a time.Duration.
|
||||
func ToDuration(tm int64, hz uint32) time.Duration {
|
||||
return time.Duration(tm * int64(time.Second) / int64(hz))
|
||||
}
|
||||
|
||||
func sat(a int64) uint64 {
|
||||
if a < 0 {
|
||||
return 0
|
||||
if tm < 0 {
|
||||
return -ToDuration(-tm, hz)
|
||||
}
|
||||
return uint64(a)
|
||||
hi, lo := bits.Mul64(uint64(tm), uint64(time.Second))
|
||||
q, _ := bits.Div64(hi, lo, uint64(hz))
|
||||
return time.Duration(q)
|
||||
}
|
||||
|
||||
// Now returns the current time in units of 1/hz from an arbitrary origin.
|
||||
func Now(hz uint32) uint64 {
|
||||
return sat(FromDuration(time.Since(epoch), hz))
|
||||
return uint64(FromDuration(time.Since(epoch), hz))
|
||||
}
|
||||
|
||||
// Microseconds is like Now, but uses microseconds.
|
||||
|
@ -46,7 +51,7 @@ func Jiffies() uint64 {
|
|||
|
||||
// TimeToJiffies converts a time.Time into jiffies.
|
||||
func TimeToJiffies(tm time.Time) uint64 {
|
||||
return sat(FromDuration(tm.Sub(epoch), JiffiesPerSec))
|
||||
return uint64(FromDuration(tm.Sub(epoch), JiffiesPerSec))
|
||||
}
|
||||
|
||||
// The origin of NTP time.
|
||||
|
|
|
@ -27,6 +27,25 @@ func TestDuration(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDurationOverflow(t *testing.T) {
|
||||
delta := 10 * time.Minute
|
||||
dj := FromDuration(delta, JiffiesPerSec)
|
||||
var prev int64
|
||||
for d := time.Duration(0); d < time.Duration(1000*time.Hour); d += delta {
|
||||
jiffies := FromDuration(d, JiffiesPerSec)
|
||||
if d != 0 {
|
||||
if jiffies != prev+dj {
|
||||
t.Errorf("%v: %v, %v", d, jiffies, prev)
|
||||
}
|
||||
}
|
||||
d2 := ToDuration(jiffies, JiffiesPerSec)
|
||||
if d2 != d {
|
||||
t.Errorf("%v != %v (%v)", d2, d, jiffies)
|
||||
}
|
||||
prev = jiffies
|
||||
}
|
||||
}
|
||||
|
||||
func differs(a, b, delta uint64) bool {
|
||||
if a < b {
|
||||
a, b = b, a
|
||||
|
|
Loading…
Reference in a new issue