From e52d22b6da2ccaee74fb00438143c1e8baf5b275 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Fri, 18 Apr 2014 05:09:27 -0400 Subject: [PATCH] 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 --- src/util/timestamp.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/util/timestamp.cc b/src/util/timestamp.cc index 275cdd3..0c33054 100644 --- a/src/util/timestamp.cc +++ b/src/util/timestamp.cc @@ -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.