summaryrefslogtreecommitdiff
path: root/src/common/compat_time.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-04-26 11:17:48 -0400
committerNick Mathewson <nickm@torproject.org>2018-04-26 12:01:48 -0400
commit9abf541f7f70068b6f7567481739ca6374f1fd57 (patch)
tree2d3feeaa192761116fb7eee48d1b8cde46b86a49 /src/common/compat_time.c
parent7cbc44eeb19831bc467f8e1b87062ed1c87934d5 (diff)
downloadtor-9abf541f7f70068b6f7567481739ca6374f1fd57.tar.gz
tor-9abf541f7f70068b6f7567481739ca6374f1fd57.zip
Add a function to compute millisecond time difference quickly.
Our main function, though accurate on all platforms, can be very slow on 32-bit hosts. This one is faster on all 32-bit hosts, and accurate everywhere except apple, where it will typically be off by 1%. But since 32-bit apple is a relic anyway, I think we should be fine.
Diffstat (limited to 'src/common/compat_time.c')
-rw-r--r--src/common/compat_time.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/common/compat_time.c b/src/common/compat_time.c
index 966216768f..b3723f533c 100644
--- a/src/common/compat_time.c
+++ b/src/common/compat_time.c
@@ -279,6 +279,7 @@ monotime_reset_ratchets_for_testing(void)
* nanoseconds.
*/
static struct mach_timebase_info mach_time_info;
+static struct mach_timebase_info mach_time_info_msec_cvt;
static int monotime_shift = 0;
static void
@@ -296,6 +297,14 @@ monotime_init_internal(void)
// requires that tor_log2(0) == 0.
monotime_shift = tor_log2(ms_per_tick);
}
+ {
+ // 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
+ // 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;
+ }
}
/**
@@ -345,6 +354,22 @@ monotime_diff_nsec(const monotime_t *start,
return diff_nsec;
}
+int32_t
+monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
+ const monotime_coarse_t *end)
+{
+ if (BUG(mach_time_info.denom == 0)) {
+ monotime_init();
+ }
+ const int64_t diff_ticks = end->abstime_ - start->abstime_;
+
+ /* 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;
+}
+
uint32_t
monotime_coarse_to_stamp(const monotime_coarse_t *t)
{
@@ -443,6 +468,15 @@ monotime_diff_nsec(const monotime_t *start,
return diff_nsec;
}
+int32_t
+monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
+ const monotime_coarse_t *end)
+{
+ const int32_t diff_sec = (int32_t)(end->ts_.tv_sec - start->ts_.tv_sec);
+ const int32_t diff_nsec = (int32_t)(end->ts_.tv_nsec - start->ts_.tv_nsec);
+ return diff_sec * 1000 + diff_nsec / ONE_MILLION;
+}
+
/* This value is ONE_BILLION >> 20. */
static const uint32_t STAMP_TICKS_PER_SECOND = 953;
@@ -592,6 +626,13 @@ monotime_coarse_diff_msec(const monotime_coarse_t *start,
return diff_ticks;
}
+int32_t
+monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
+ const monotime_coarse_t *end)
+{
+ return (int32_t)monotime_coarse_diff_msec(start, end)
+}
+
int64_t
monotime_coarse_diff_usec(const monotime_coarse_t *start,
const monotime_coarse_t *end)
@@ -677,6 +718,15 @@ monotime_diff_nsec(const monotime_t *start,
return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
}
+int32_t
+monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
+ const monotime_coarse_t *end)
+{
+ struct timeval diff;
+ timersub(&end->tv_, &start->tv_, &diff);
+ return diff.tv_sec * 1000 + diff.tv_usec / 1000;
+}
+
/* This value is ONE_MILLION >> 10. */
static const uint32_t STAMP_TICKS_PER_SECOND = 976;