aboutsummaryrefslogtreecommitdiff
path: root/src/lib/time
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-09-20 10:43:08 -0400
committerNick Mathewson <nickm@torproject.org>2018-09-20 10:43:08 -0400
commit1f377e910f89753f6e64a4f9ddc2ff9c35d1e341 (patch)
tree44144764cc26c0a984bd9b0bc5075dc0bcd0be28 /src/lib/time
parent119159677be14351ebcae647d3988f4f2fd9eb72 (diff)
parent163230e2405af394ce3684dc7fdf2475bf1318b0 (diff)
downloadtor-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.c22
-rw-r--r--src/lib/time/compat_time.h1
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
}