diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-09-20 10:43:08 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-09-20 10:43:08 -0400 |
commit | 1f377e910f89753f6e64a4f9ddc2ff9c35d1e341 (patch) | |
tree | 44144764cc26c0a984bd9b0bc5075dc0bcd0be28 /src/lib/time | |
parent | 119159677be14351ebcae647d3988f4f2fd9eb72 (diff) | |
parent | 163230e2405af394ce3684dc7fdf2475bf1318b0 (diff) | |
download | tor-1f377e910f89753f6e64a4f9ddc2ff9c35d1e341.tar.gz tor-1f377e910f89753f6e64a4f9ddc2ff9c35d1e341.zip |
Merge branch 'maint-0.3.4'
Diffstat (limited to 'src/lib/time')
-rw-r--r-- | src/lib/time/compat_time.c | 22 | ||||
-rw-r--r-- | src/lib/time/compat_time.h | 1 |
2 files changed, 17 insertions, 6 deletions
diff --git a/src/lib/time/compat_time.c b/src/lib/time/compat_time.c index d26cb6880d..f1ddb4fdc4 100644 --- a/src/lib/time/compat_time.c +++ b/src/lib/time/compat_time.c @@ -237,6 +237,7 @@ monotime_reset_ratchets_for_testing(void) */ static struct mach_timebase_info mach_time_info; static struct mach_timebase_info mach_time_info_msec_cvt; +static int32_t mach_time_msec_cvt_threshold; static int monotime_shift = 0; static void @@ -256,11 +257,15 @@ monotime_init_internal(void) } { // For converting ticks to milliseconds in a 32-bit-friendly way, we - // will first right-shift by 20, and then multiply by 20/19, since - // (1<<20) * 19/20 is about 1e6. We precompute a new numerate and + // will first right-shift by 20, and then multiply by 2048/1953, since + // (1<<20) * 1953/2048 is about 1e6. We precompute a new numerator and // denominator here to avoid multiple multiplies. - mach_time_info_msec_cvt.numer = mach_time_info.numer * 20; - mach_time_info_msec_cvt.denom = mach_time_info.denom * 19; + mach_time_info_msec_cvt.numer = mach_time_info.numer * 2048; + mach_time_info_msec_cvt.denom = mach_time_info.denom * 1953; + // For any value above this amount, we should divide before multiplying, + // to avoid overflow. For a value below this, we should multiply + // before dividing, to improve accuracy. + mach_time_msec_cvt_threshold = INT32_MAX / mach_time_info_msec_cvt.numer; } } @@ -323,8 +328,13 @@ monotime_coarse_diff_msec32_(const monotime_coarse_t *start, /* We already require in di_ops.c that right-shift performs a sign-extend. */ const int32_t diff_microticks = (int32_t)(diff_ticks >> 20); - return (diff_microticks * mach_time_info_msec_cvt.numer) / - mach_time_info_msec_cvt.denom; + if (diff_microticks >= mach_time_msec_cvt_threshold) { + return (diff_microticks / mach_time_info_msec_cvt.denom) * + mach_time_info_msec_cvt.numer; + } else { + return (diff_microticks * mach_time_info_msec_cvt.numer) / + mach_time_info_msec_cvt.denom; + } } uint32_t diff --git a/src/lib/time/compat_time.h b/src/lib/time/compat_time.h index 4427ce8f92..44fab62de5 100644 --- a/src/lib/time/compat_time.h +++ b/src/lib/time/compat_time.h @@ -200,6 +200,7 @@ monotime_coarse_diff_msec32(const monotime_coarse_t *start, // on a 64-bit platform, let's assume 64/64 division is cheap. return (int32_t) monotime_coarse_diff_msec(start, end); #else +#define USING_32BIT_MSEC_HACK return monotime_coarse_diff_msec32_(start, end); #endif } |