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:
committed by
John Hood
parent
cfc29387ae
commit
e52d22b6da
@@ -72,14 +72,16 @@ void freeze_timestamp( void )
|
|||||||
}
|
}
|
||||||
#elif HAVE_MACH_ABSOLUTE_TIME
|
#elif HAVE_MACH_ABSOLUTE_TIME
|
||||||
static mach_timebase_info_data_t s_timebase_info;
|
static mach_timebase_info_data_t s_timebase_info;
|
||||||
|
static double absolute_to_millis;
|
||||||
|
|
||||||
if (s_timebase_info.denom == 0) {
|
if (s_timebase_info.denom == 0) {
|
||||||
mach_timebase_info(&s_timebase_info);
|
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"
|
// NB: mach_absolute_time() returns "absolute time units"
|
||||||
// We need to apply a conversion to get milliseconds.
|
// 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;
|
return;
|
||||||
#elif HAVE_GETTIMEOFDAY
|
#elif HAVE_GETTIMEOFDAY
|
||||||
// NOTE: If time steps backwards, timeouts may be confused.
|
// NOTE: If time steps backwards, timeouts may be confused.
|
||||||
|
|||||||
Reference in New Issue
Block a user