diff options
author | Nick Mathewson <nickm@torproject.org> | 2016-07-13 10:18:15 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2016-07-19 11:40:47 +0200 |
commit | 2a217ef72392d685e6c9b48b2be3b467a8244b48 (patch) | |
tree | b4522f1456714baa265fc7c2ef208ee1da59d20d /src/common/compat_time.c | |
parent | 7bc4ca7de9d434edeb21525917c81d6963a26511 (diff) | |
download | tor-2a217ef72392d685e6c9b48b2be3b467a8244b48.tar.gz tor-2a217ef72392d685e6c9b48b2be3b467a8244b48.zip |
Expose monotonic time ratchet functions for testing.
Diffstat (limited to 'src/common/compat_time.c')
-rw-r--r-- | src/common/compat_time.c | 156 |
1 files changed, 86 insertions, 70 deletions
diff --git a/src/common/compat_time.c b/src/common/compat_time.c index bbbca33ca5..de3956685a 100644 --- a/src/common/compat_time.c +++ b/src/common/compat_time.c @@ -118,6 +118,89 @@ tor_gettimeofday(struct timeval *timeval) /** True iff monotime_init has been called. */ static int monotime_initialized = 0; +/* "ratchet" functions for monotonic time. */ + +#if defined(_WIN32) || defined(TOR_UNIT_TESTS) + +/** Protected by lock: last value returned by monotime_get(). */ +static int64_t last_pctr = 0; +/** Protected by lock: offset we must add to monotonic time values. */ +static int64_t pctr_offset = 0; +/* If we are using GetTickCount(), how many times has it rolled over? */ +static uint32_t rollover_count = 0; +/* If we are using GetTickCount(), what's the last value it returned? */ +static int64_t last_tick_count = 0; + +/** Helper for windows: Called with a sequence of times that are supposed + * to be monotonic; increments them as appropriate so that they actually + * _are_ monotonic. + * + * Caller must hold lock. */ +STATIC int64_t +ratchet_performance_counter(int64_t count_raw) +{ + /* must hold lock */ + const int64_t count_adjusted = count_raw + pctr_offset; + + if (PREDICT_UNLIKELY(count_adjusted < last_pctr)) { + /* Monotonicity failed! Pretend no time elapsed. */ + pctr_offset = last_pctr - count_raw; + return last_pctr; + } else { + last_pctr = count_adjusted; + return count_adjusted; + } +} + +STATIC int64_t +ratchet_coarse_performance_counter(const int64_t count_raw) +{ + int64_t count = count_raw + (((int64_t)rollover_count) << 32); + while (PREDICT_UNLIKELY(count < last_tick_count)) { + ++rollover_count; + count = count_raw + (((int64_t)rollover_count) << 32); + } + last_tick_count = count; + return count; +} +#endif + +#if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS) +static struct timeval last_timeofday = { 0, 0 }; +static struct timeval timeofday_offset = { 0, 0 }; + +/** Helper for gettimeofday(): Called with a sequence of times that are + * supposed to be monotonic; increments them as appropriate so that they + * actually _are_ monotonic. + * + * Caller must hold lock. */ +STATIC void +ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out) +{ + /* must hold lock */ + timeradd(timeval_raw, &timeofday_offset, out); + if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, <))) { + /* time ran backwards. Instead, declare that no time occurred. */ + timersub(&last_timeofday, timeval_raw, &timeofday_offset); + memcpy(out, &last_timeofday, sizeof(struct timeval)); + } else { + memcpy(&last_timeofday, out, sizeof(struct timeval)); + } +} +#endif + +#ifdef TOR_UNIT_TESTS +/** For testing: reset all the ratchets */ +void +monotime_reset_ratchets_for_testing(void) +{ + last_pctr = pctr_offset = last_tick_count = 0; + rollover_count = 0; + memset(&last_timeofday, 0, sizeof(struct timeval)); + memset(&timeofday_offset, 0, sizeof(struct timeval)); +} +#endif + #ifdef __APPLE__ /** Initialized on startup: tells is how to convert from ticks to @@ -201,17 +284,9 @@ monotime_diff_nsec(const monotime_t *start, /** Result of QueryPerformanceFrequency, as an int64_t. */ static int64_t ticks_per_second = 0; -/** Protected by lock: last value returned by monotime_get(). */ -static int64_t last_pctr = 0; -/** Protected by lock: offset we must add to monotonic time values. */ -static int64_t pctr_offset = 0; /** Lock to protect last_pctr and pctr_offset */ static CRITICAL_SECTION monotime_lock; -/* If we are using GetTickCount(), how many times has it rolled over? */ -static uint32_t rollover_count = 0; -/* If we are using GetTickCount(), what's the last value it returned? */ -static int64_t last_tick_count = 0; -/** Lock to protect rollover_count and */ +/** Lock to protect rollover_count and last_tick_count */ static CRITICAL_SECTION monotime_coarse_lock; typedef ULONGLONG (WINAPI *GetTickCount64_fn_t)(void); @@ -241,39 +316,6 @@ monotime_init_internal(void) // FreeLibrary(h) ? } -/** Helper for windows: Called with a sequence of times that are supposed - * to be monotonic; increments them as appropriate so that they actually - * _are_ monotonic. - * - * Caller must hold lock. */ -STATIC int64_t -ratchet_performance_counter(int64_t count_raw) -{ - /* must hold lock */ - const int64_t count_adjusted = count_raw + pctr_offset; - - if (PREDICT_UNLIKELY(count_adjusted < last_pctr)) { - /* Monotonicity failed! Pretend no time elapsed. */ - pctr_offset = last_pctr - count_raw; - return last_pctr; - } else { - last_pctr = count_adjusted; - return count_adjusted; - } -} - -STATIC int64_t -ratchet_coarse_performance_counter(const int64_t count_raw) -{ - int64_t count = count_raw + (((int64_t)rollover_count) << 32); - while (PREDICT_UNLIKELY(count < last_tick_count)) { - ++rollover_count; - count = count_raw + (((int64_t)rollover_count) << 32); - } - last_tick_count = count; - return count; -} - void monotime_get(monotime_t *out) { @@ -344,9 +386,6 @@ monotime_coarse_diff_nsec(const monotime_coarse_t *start, /* end of "_WIN32" */ #elif defined(MONOTIME_USING_GETTIMEOFDAY) -static int monotime_initialized = 0; -static struct timeval last_timeofday = { 0, 0 }; -static struct timeval timeofday_offset = { 0, 0 }; static tor_mutex_t monotime_lock; /** Initialize the monotonic timer subsystem. */ @@ -357,25 +396,6 @@ monotime_init_internal(void) tor_mutex_init(&monotime_lock); } -/** Helper for gettimeofday(): Called with a sequence of times that are - * supposed to be monotonic; increments them as appropriate so that they - * actually _are_ monotonic. - * - * Caller must hold lock. */ -STATIC void -ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out) -{ - /* must hold lock */ - timeradd(timeval_raw, &timeofday_offset, out); - if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, <))) { - /* time ran backwards. Instead, declare that no time occurred. */ - timersub(&last_timeofday, timeval_raw, &timeofday_offset); - memcpy(out, &last_timeofday, sizeof(struct timeval)); - } else { - memcpy(&last_timeofday, out, sizeof(struct timeval)); - } -} - void monotime_get(monotime_t *out) { @@ -474,16 +494,12 @@ monotime_coarse_absolute_nsec(void) uint64_t monotime_coarse_absolute_usec(void) { - monotime_coarse_t now; - monotime_coarse_get(&now); - return monotime_coarse_diff_usec(&initialized_at_coarse, &now); + return monotime_coarse_absolute_nsec() / 1000; } uint64_t monotime_coarse_absolute_msec(void) { - monotime_coarse_t now; - monotime_coarse_get(&now); - return monotime_coarse_diff_msec(&initialized_at_coarse, &now); + return monotime_coarse_absolute_nsec() / ONE_MILLION; } #endif |