clock: Ensure that now() is monotonic

This commit is contained in:
Hajime Hoshi 2019-05-09 02:44:14 +09:00
parent c65d035cc9
commit 009fa9accd
3 changed files with 13 additions and 0 deletions

View File

@ -112,6 +112,8 @@ func updateFPSAndTPS(now int64, count int) {
const UncappedTPS = -1
var previousNow int64
// Update updates the inner clock state and returns an integer value
// indicating how many times the game should update based on given tps.
// tps represents TPS (ticks per second).
@ -124,6 +126,10 @@ func Update(tps int) int {
defer m.Unlock()
n := now()
if n < previousNow {
panic("clock: now() must be monotonic but returned older time than before: perhaps overflowing?")
}
c := 0
if tps == UncappedTPS {
c = 1
@ -131,5 +137,7 @@ func Update(tps int) int {
c = calcCountFromTPS(int64(tps), n)
}
updateFPSAndTPS(n, c)
previousNow = n
return c
}

View File

@ -22,5 +22,7 @@ import (
)
func now() int64 {
// time.Now() is monotonic:
// https://golang.org/pkg/time/#hdr-Monotonic_Clocks
return time.Now().UnixNano()
}

View File

@ -23,5 +23,8 @@ import (
func now() int64 {
// time.Now() is not reliable until GopherJS supports performance.now().
//
// performance.now is monotonic:
// https://developers.google.com/web/updates/2012/08/When-milliseconds-are-not-enough-performance-now#monotonic_time
return int64(js.Global().Get("performance").Call("now").Float() * float64(time.Millisecond))
}