diff --git a/xpcom/ds/TimeStamp_posix.cpp b/xpcom/ds/TimeStamp_posix.cpp index 5d299a6dfa5..062ff898db3 100644 --- a/xpcom/ds/TimeStamp_posix.cpp +++ b/xpcom/ds/TimeStamp_posix.cpp @@ -58,6 +58,12 @@ static const PRUint64 kNsPerMs = 1000000; static const PRUint64 kNsPerSec = 1000000000; static const double kNsPerSecd = 1000000000.0; +static PRUint64 +TimespecToNs(const struct timespec& ts) +{ + PRUint64 baseNs = PRUint64(ts.tv_sec) * kNsPerSec; + return baseNs + PRUint64(ts.tv_nsec); +} static PRUint64 ClockTimeNs() @@ -73,16 +79,14 @@ ClockTimeNs() // bits, tv_sec won't overflow while the browser is open. Revisit // this argument if we're still building with 32-bit time_t around // the year 2037. - PRUint64 baseNs = PRUint64(ts.tv_sec) * kNsPerSec; - - return baseNs + PRUint64(ts.tv_nsec); + return TimespecToNs(ts); } static PRUint64 ClockResolutionNs() { - // NB: why not use clock_getres()? Two reasons: (i) it might lie, - // and (ii) it might return an "ideal" resolution that while + // NB: why not rely on clock_getres()? Two reasons: (i) it might + // lie, and (ii) it might return an "ideal" resolution that while // theoretically true, could never be measured in practice. Since // clock_gettime() likely involves a system call on your platform, // the "actual" timing resolution shouldn't be lower than syscall @@ -105,11 +109,19 @@ ClockResolutionNs() } if (0 == minres) { - NS_WARNING("the clock resolution is *not* 1ns, something's wrong"); - minres = 1; // to avoid /0 + // measurable resolution is either incredibly low, ~1ns, or very + // high. fall back on clock_getres() + struct timespec ts; + clock_getres(CLOCK_MONOTONIC, &ts); + + minres = TimespecToNs(ts); + } + + if (0 == minres) { + // clock_getres probably failed. fall back on NSPR's resolution + // assumption + minres = 1 * kNsPerMs; } - if (minres / kNsPerMs) - NS_WARNING("the clock resolution is *not* >=1ms, something's wrong"); return minres; } diff --git a/xpcom/tests/TestTimeStamp.cpp b/xpcom/tests/TestTimeStamp.cpp index 29dad87089b..03c1fdcbb42 100644 --- a/xpcom/tests/TestTimeStamp.cpp +++ b/xpcom/tests/TestTimeStamp.cpp @@ -121,7 +121,8 @@ int main(int argc, char** argv) double resolution = TimeDuration::Resolution().ToSecondsSigDigits(); printf(" (platform timer resolution is ~%g s)\n", resolution); Assert(0.000000001 < resolution, "Time resolution is sane"); - Assert(resolution <= 0.001, "Time resolution as good as NSPR's worst"); + // Don't upper-bound sanity check ... although NSPR reports 1ms + // resolution, it might be lying, so we shouldn't compare with it return gFailCount > 0; }