From e531d4d1b9753e80b56a28805b01c014a1fe5d51 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 13 Oct 2022 13:40:10 -0400 Subject: Fix a completely wrong calculation in mach monotime_init_internal() Bug 1: We were purporting to calculate milliseconds per tick, when we *should* have been computing ticks per millisecond. Bug 2: Instead of computing either one of those, we were _actually_ computing femtoseconds per tick. These two bugs covered for one another on x86 hardware, where 1 tick == 1 nanosecond. But on M1 OSX, 1 tick is about 41 nanoseconds, causing surprising results. Fixes bug 40684; bugfix on 0.3.3.1-alpha. --- src/lib/time/compat_time.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/time/compat_time.c b/src/lib/time/compat_time.c index 6bbad4f98a..9a5ce062d7 100644 --- a/src/lib/time/compat_time.c +++ b/src/lib/time/compat_time.c @@ -253,11 +253,14 @@ monotime_init_internal(void) tor_assert(mach_time_info.denom != 0); { - // approximate only. - uint64_t ns_per_tick = mach_time_info.numer / mach_time_info.denom; - uint64_t ms_per_tick = ns_per_tick * ONE_MILLION; + // We want to compute this, approximately: + // uint64_t ns_per_tick = mach_time_info.numer / mach_time_info.denom; + // uint64_t ticks_per_ms = ONE_MILLION / ns_per_tick; + // This calculation multiplies first, though, to improve accuracy. + uint64_t ticks_per_ms = (ONE_MILLION * mach_time_info.denom) + / mach_time_info.numer; // requires that tor_log2(0) == 0. - monotime_shift = tor_log2(ms_per_tick); + monotime_shift = tor_log2(ticks_per_ms); } { // For converting ticks to milliseconds in a 32-bit-friendly way, we -- cgit v1.2.3-54-g00ecf