mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
TimeUtil: fix the generic fallback platform's clocks
This branch is live on the Switch and the BSDs - ppsspp_config.h only maps LINUX to Android and Linux - and three of its functions didn't do what their callers assume. time_now_raw() is documented and used as nanoseconds, and from_time_raw() scales it by 1/nanos, but this built a double of *seconds* and returned it through the uint64_t return type: the fraction was truncated away and the result was off by a factor of a billion. Return real monotonic nanoseconds, like every other platform branch. time_now_unix_utc() just forwarded to time_now_raw(), which is now explicitly a monotonic clock with no relation to the epoch (and before this, was seconds truncated to a whole number). Read the wall clock. Instant took gettimeofday's tv_usec into nsecs_ and stored tv_sec as the start, while ElapsedNanos() subtracts those from clock_gettime(CLOCK_MONOTONIC) - so it mixed two different clocks *and* two different units, then applied a microsecond borrow to a nanosecond difference. Elapsed times were nonsense and could come out negative.
This commit is contained in:
1 parent
5c329415a5
commit
820c6e0134
1 file changed
+20
-15
+20
-15
@@ -238,12 +238,12 @@ double time_now_d() {
|
||||
}
|
||||
|
||||
uint64_t time_now_raw() {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
if (start == 0) {
|
||||
start = tv.tv_sec;
|
||||
}
|
||||
return (double)tv.tv_sec + (double)tv.tv_usec * (1.0 / micros);
|
||||
// Nanoseconds, like the other platforms - from_time_raw() scales by 1/nanos. This used to
|
||||
// build a double of seconds and return it through the uint64_t, so it both lost the fraction
|
||||
// and was off by a factor of a billion.
|
||||
struct timespec tp;
|
||||
clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
return (uint64_t)tp.tv_sec * 1000000000ULL + tp.tv_nsec;
|
||||
}
|
||||
|
||||
double from_time_raw(uint64_t raw_time) {
|
||||
@@ -257,7 +257,10 @@ double from_time_raw_relative(uint64_t raw_time) {
|
||||
void yield() {}
|
||||
|
||||
double time_now_unix_utc() {
|
||||
return time_now_raw();
|
||||
// Not time_now_raw() - that's a monotonic clock with no relation to the epoch.
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
return (double)tv.tv_sec + (double)tv.tv_usec * (1.0 / micros);
|
||||
}
|
||||
|
||||
double time_to_unix_utc(double t) {
|
||||
@@ -267,10 +270,12 @@ double time_to_unix_utc(double t) {
|
||||
}
|
||||
|
||||
Instant::Instant() {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
nativeStart_ = tv.tv_sec;
|
||||
nsecs_ = tv.tv_usec;
|
||||
// Has to be the same clock, and the same unit, as ElapsedNanos() below: this took the wall
|
||||
// clock in microseconds while that one subtracts it from a monotonic clock in nanoseconds.
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
nativeStart_ = ts.tv_sec;
|
||||
nsecs_ = ts.tv_nsec;
|
||||
}
|
||||
|
||||
int64_t Instant::ElapsedNanos() const {
|
||||
@@ -278,12 +283,12 @@ int64_t Instant::ElapsedNanos() const {
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
|
||||
int64_t secs = ts.tv_sec - nativeStart_;
|
||||
int64_t usecs = ts.tv_nsec - nsecs_;
|
||||
if (usecs < 0) {
|
||||
int64_t nsecs = ts.tv_nsec - nsecs_;
|
||||
if (nsecs < 0) {
|
||||
secs--;
|
||||
usecs += 1000000;
|
||||
nsecs += 1000000000;
|
||||
}
|
||||
return secs * 1000000000 + usecs * 1000;
|
||||
return secs * 1000000000 + nsecs;
|
||||
}
|
||||
|
||||
double Instant::ElapsedSeconds() const {
|
||||
|
||||
Reference in new issue
Block a user