Timestamp: Prevent integer overflow on Darwin PPC 32-bit

A Darwin PPC 32-bit user observes huge values numer == 1000000000 and
denom == 18431683 returned from mach_timebase_info().  For these
values, mach_absolute_time() * numer overflows uint64_t every 1000.82
seconds, and 1000000 * denom always overflows uint32_t, with the
effect of making time run backwards at -11190660 times its usual
speed.

This bug was masked on Darwin x86 64-bit, where numer == denom == 1.

Fix it by doing the conversion with double arithmetic instead.

Closes #479.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
This commit is contained in:
Anders Kaseorg
2014-04-18 05:09:27 -04:00
committed by John Hood
parent cfc29387ae
commit e52d22b6da
+3 -1
View File
@@ -72,14 +72,16 @@ void freeze_timestamp( void )
}
#elif HAVE_MACH_ABSOLUTE_TIME
static mach_timebase_info_data_t s_timebase_info;
static double absolute_to_millis;
if (s_timebase_info.denom == 0) {
mach_timebase_info(&s_timebase_info);
absolute_to_millis = 1e-6 * s_timebase_info.numer / s_timebase_info.denom;
}
// NB: mach_absolute_time() returns "absolute time units"
// We need to apply a conversion to get milliseconds.
millis_cache = ((mach_absolute_time() * s_timebase_info.numer) / (1000000 * s_timebase_info.denom));
millis_cache = mach_absolute_time() * absolute_to_millis;
return;
#elif HAVE_GETTIMEOFDAY
// NOTE: If time steps backwards, timeouts may be confused.