12 #define COMPAT_TIME_PRIVATE
28 #ifdef HAVE_SYS_TYPES_H
29 #include <sys/types.h>
31 #ifdef HAVE_SYS_TIME_H
38 #if !defined(HAVE_USLEEP) && defined(HAVE_SYS_SELECT_H)
40 #include <sys/select.h>
45 #include <mach/mach_time.h>
53 #undef HAVE_CLOCK_GETTIME
59 tor_sleep_msec(
int msec)
63 #elif defined(HAVE_USLEEP)
66 usleep((msec % 1000) * 1000);
67 #elif defined(HAVE_SYS_SELECT_H)
68 struct timeval tv = { msec / 1000, (msec % 1000) * 1000};
69 select(0, NULL, NULL, NULL, &tv);
71 sleep(CEIL_DIV(msec, 1000));
76 #define ONE_MILLION ((int64_t) (1000 * 1000))
77 #define ONE_BILLION ((int64_t) (1000 * 1000 * 1000))
83 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
84 static monotime_coarse_t initialized_at_coarse;
91 static int monotime_mocking_enabled = 0;
94 static int64_t mock_time_nsec = 0;
95 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
96 static int64_t mock_time_nsec_coarse = 0;
97 static monotime_coarse_t initialized_at_coarse_saved;
101 monotime_enable_test_mocking(
void)
107 tor_assert_nonfatal(monotime_mocking_enabled == 0);
108 monotime_mocking_enabled = 1;
109 memcpy(&initialized_at_saved,
111 memset(&initialized_at, 0,
sizeof(
monotime_t));
112 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
113 memcpy(&initialized_at_coarse_saved,
114 &initialized_at_coarse,
sizeof(monotime_coarse_t));
115 memset(&initialized_at_coarse, 0,
sizeof(monotime_coarse_t));
120 monotime_disable_test_mocking(
void)
122 tor_assert_nonfatal(monotime_mocking_enabled == 1);
123 monotime_mocking_enabled = 0;
125 memcpy(&initialized_at,
127 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
128 memcpy(&initialized_at_coarse,
129 &initialized_at_coarse_saved,
sizeof(monotime_coarse_t));
134 monotime_set_mock_time_nsec(int64_t nsec)
136 tor_assert_nonfatal(monotime_mocking_enabled == 1);
137 mock_time_nsec = nsec;
140 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
142 monotime_coarse_set_mock_time_nsec(int64_t nsec)
144 tor_assert_nonfatal(monotime_mocking_enabled == 1);
145 mock_time_nsec_coarse = nsec;
152 #if defined(_WIN32) || defined(TOR_UNIT_TESTS)
155 static int64_t last_pctr = 0;
157 static int64_t pctr_offset = 0;
159 static uint32_t rollover_count = 0;
161 static int64_t last_tick_count = 0;
171 ratchet_performance_counter(int64_t count_raw)
174 const int64_t count_adjusted = count_raw + pctr_offset;
176 if (PREDICT_UNLIKELY(count_adjusted < last_pctr)) {
178 pctr_offset = last_pctr - count_raw;
181 last_pctr = count_adjusted;
182 return count_adjusted;
187 ratchet_coarse_performance_counter(
const int64_t count_raw)
189 int64_t count = count_raw + (((int64_t)rollover_count) << 32);
190 while (PREDICT_UNLIKELY(count < last_tick_count)) {
192 count = count_raw + (((int64_t)rollover_count) << 32);
194 last_tick_count = count;
199 #if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS)
200 static struct timeval last_timeofday = { 0, 0 };
201 static struct timeval timeofday_offset = { 0, 0 };
211 ratchet_timeval(
const struct timeval *timeval_raw,
struct timeval *out)
214 timeradd(timeval_raw, &timeofday_offset, out);
215 if (PREDICT_UNLIKELY(
timercmp(out, &last_timeofday, OP_LT))) {
217 timersub(&last_timeofday, timeval_raw, &timeofday_offset);
218 memcpy(out, &last_timeofday,
sizeof(
struct timeval));
220 memcpy(&last_timeofday, out,
sizeof(
struct timeval));
225 #ifdef TOR_UNIT_TESTS
228 monotime_reset_ratchets_for_testing(
void)
230 last_pctr = pctr_offset = last_tick_count = 0;
232 memset(&last_timeofday, 0,
sizeof(
struct timeval));
233 memset(&timeofday_offset, 0,
sizeof(
struct timeval));
242 static struct mach_timebase_info mach_time_info;
243 static struct mach_timebase_info mach_time_info_msec_cvt;
244 static int32_t mach_time_msec_cvt_threshold;
245 static int monotime_shift = 0;
248 monotime_init_internal(
void)
251 int r = mach_timebase_info(&mach_time_info);
260 uint64_t ticks_per_ms = (ONE_MILLION * mach_time_info.denom)
261 / mach_time_info.numer;
263 monotime_shift =
tor_log2(ticks_per_ms);
270 mach_time_info_msec_cvt.numer = mach_time_info.numer * 2048;
271 mach_time_info_msec_cvt.denom = mach_time_info.denom * 1953;
275 mach_time_msec_cvt_threshold = INT32_MAX / mach_time_info_msec_cvt.numer;
287 #ifdef TOR_UNIT_TESTS
288 if (monotime_mocking_enabled) {
289 out->abstime_ = (mock_time_nsec * mach_time_info.denom)
290 / mach_time_info.numer;
294 out->abstime_ = mach_absolute_time();
297 #if defined(HAVE_MACH_APPROXIMATE_TIME)
299 monotime_coarse_get(monotime_coarse_t *out)
301 #ifdef TOR_UNIT_TESTS
302 if (monotime_mocking_enabled) {
303 out->abstime_ = (mock_time_nsec_coarse * mach_time_info.denom)
304 / mach_time_info.numer;
308 out->abstime_ = mach_approximate_time();
321 if (BUG(mach_time_info.denom == 0)) {
324 const int64_t diff_ticks = end->abstime_ - start->abstime_;
325 const int64_t diff_nsec =
326 (diff_ticks * mach_time_info.numer) / mach_time_info.denom;
332 const monotime_coarse_t *end)
334 if (BUG(mach_time_info.denom == 0)) {
337 const int64_t diff_ticks = end->abstime_ - start->abstime_;
340 const int32_t diff_microticks = (int32_t)(diff_ticks >> 20);
342 if (diff_microticks >= mach_time_msec_cvt_threshold) {
343 return (diff_microticks / mach_time_info_msec_cvt.denom) *
344 mach_time_info_msec_cvt.numer;
346 return (diff_microticks * mach_time_info_msec_cvt.numer) /
347 mach_time_info_msec_cvt.denom;
354 return (uint32_t)(t->abstime_ >> monotime_shift);
360 return val->abstime_ == 0;
366 const uint64_t nsec = msec * ONE_MILLION;
367 const uint64_t ticks = (nsec * mach_time_info.denom) / mach_time_info.numer;
368 out->abstime_ = val->abstime_ + ticks;
372 #elif defined(HAVE_CLOCK_GETTIME)
374 #ifdef CLOCK_MONOTONIC_COARSE
381 static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
385 monotime_init_internal(
void)
387 #ifdef CLOCK_MONOTONIC_COARSE
389 if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) < 0) {
390 log_info(
LD_GENERAL,
"CLOCK_MONOTONIC_COARSE isn't working (%s); "
391 "falling back to CLOCK_MONOTONIC.", strerror(errno));
392 clock_monotonic_coarse = CLOCK_MONOTONIC;
400 #ifdef TOR_UNIT_TESTS
401 if (monotime_mocking_enabled) {
402 out->ts_.tv_sec = (time_t) (mock_time_nsec / ONE_BILLION);
403 out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION);
407 int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
411 #ifdef CLOCK_MONOTONIC_COARSE
413 monotime_coarse_get(monotime_coarse_t *out)
415 #ifdef TOR_UNIT_TESTS
416 if (monotime_mocking_enabled) {
417 out->ts_.tv_sec = (time_t) (mock_time_nsec_coarse / ONE_BILLION);
418 out->ts_.tv_nsec = (int) (mock_time_nsec_coarse % ONE_BILLION);
422 int r = clock_gettime(clock_monotonic_coarse, &out->ts_);
423 if (PREDICT_UNLIKELY(r < 0) &&
425 clock_monotonic_coarse == CLOCK_MONOTONIC_COARSE) {
428 log_warn(
LD_BUG,
"Falling back to non-coarse monotonic time %s initial "
430 clock_monotonic_coarse = CLOCK_MONOTONIC;
431 r = clock_gettime(clock_monotonic_coarse, &out->ts_);
442 const int64_t diff_sec = end->ts_.tv_sec - start->ts_.tv_sec;
443 const int64_t diff_nsec = diff_sec * ONE_BILLION +
444 (end->ts_.tv_nsec - start->ts_.tv_nsec);
451 const monotime_coarse_t *end)
453 const int32_t diff_sec = (int32_t)(end->ts_.tv_sec - start->ts_.tv_sec);
454 const int32_t diff_nsec = (int32_t)(end->ts_.tv_nsec - start->ts_.tv_nsec);
455 return diff_sec * 1000 + diff_nsec / ONE_MILLION;
459 static const uint32_t STAMP_TICKS_PER_SECOND = 953;
464 uint32_t nsec = (uint32_t)t->ts_.tv_nsec;
465 uint32_t sec = (uint32_t)t->ts_.tv_sec;
467 return (sec * STAMP_TICKS_PER_SECOND) + (nsec >> 20);
473 return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0;
479 const uint32_t sec = msec / 1000;
480 const uint32_t msec_remainder = msec % 1000;
481 out->ts_.tv_sec = val->ts_.tv_sec + sec;
482 out->ts_.tv_nsec = val->ts_.tv_nsec + (msec_remainder * ONE_MILLION);
483 if (out->ts_.tv_nsec > ONE_BILLION) {
484 out->ts_.tv_nsec -= ONE_BILLION;
485 out->ts_.tv_sec += 1;
490 #elif defined (_WIN32)
494 static int64_t nsec_per_tick_numer = 1;
495 static int64_t nsec_per_tick_denom = 1;
498 static CRITICAL_SECTION monotime_lock;
500 static CRITICAL_SECTION monotime_coarse_lock;
502 typedef ULONGLONG (WINAPI *GetTickCount64_fn_t)(void);
503 static GetTickCount64_fn_t GetTickCount64_fn = NULL;
506 monotime_init_internal(
void)
509 BOOL ok = InitializeCriticalSectionAndSpinCount(&monotime_lock, 200);
511 ok = InitializeCriticalSectionAndSpinCount(&monotime_coarse_lock, 200);
514 ok = QueryPerformanceFrequency(&li);
518 uint64_t n = ONE_BILLION;
519 uint64_t d = li.QuadPart;
521 simplify_fraction64(&n, &d);
525 nsec_per_tick_numer = (int64_t) n;
526 nsec_per_tick_denom = (int64_t) d;
531 HANDLE h = load_windows_system_library(TEXT(
"kernel32.dll"));
533 GetTickCount64_fn = (GetTickCount64_fn_t) (
void(*)(void))
534 GetProcAddress(h,
"GetTickCount64");
548 #ifdef TOR_UNIT_TESTS
549 if (monotime_mocking_enabled) {
550 out->pcount_ = (mock_time_nsec * nsec_per_tick_denom)
551 / nsec_per_tick_numer;
561 EnterCriticalSection(&monotime_lock);
563 BOOL ok = QueryPerformanceCounter(&res);
565 const int64_t count_raw = res.QuadPart;
566 out->pcount_ = ratchet_performance_counter(count_raw);
567 LeaveCriticalSection(&monotime_lock);
571 monotime_coarse_get(monotime_coarse_t *out)
573 #ifdef TOR_UNIT_TESTS
574 if (monotime_mocking_enabled) {
575 out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
580 if (GetTickCount64_fn) {
581 out->tick_count_ = (int64_t)GetTickCount64_fn();
583 EnterCriticalSection(&monotime_coarse_lock);
584 DWORD tick = GetTickCount();
585 out->tick_count_ = ratchet_coarse_performance_counter(tick);
586 LeaveCriticalSection(&monotime_coarse_lock);
597 const int64_t diff_ticks = end->pcount_ - start->pcount_;
598 return (diff_ticks * nsec_per_tick_numer) / nsec_per_tick_denom;
602 monotime_coarse_diff_msec(
const monotime_coarse_t *start,
603 const monotime_coarse_t *end)
605 const int64_t diff_ticks = end->tick_count_ - start->tick_count_;
611 const monotime_coarse_t *end)
613 return (int32_t)monotime_coarse_diff_msec(start, end);
617 monotime_coarse_diff_usec(
const monotime_coarse_t *start,
618 const monotime_coarse_t *end)
620 return monotime_coarse_diff_msec(start, end) * 1000;
624 monotime_coarse_diff_nsec(
const monotime_coarse_t *start,
625 const monotime_coarse_t *end)
627 return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
630 static const uint32_t STAMP_TICKS_PER_SECOND = 1000;
635 return (uint32_t) t->tick_count_;
641 return val->pcount_ == 0;
645 monotime_coarse_is_zero(
const monotime_coarse_t *val)
647 return val->tick_count_ == 0;
653 const uint64_t nsec = msec * ONE_MILLION;
654 const uint64_t ticks = (nsec * nsec_per_tick_denom) / nsec_per_tick_numer;
655 out->pcount_ = val->pcount_ + ticks;
659 monotime_coarse_add_msec(monotime_coarse_t *out,
const monotime_coarse_t *val,
662 out->tick_count_ = val->tick_count_ + msec;
666 #elif defined(MONOTIME_USING_GETTIMEOFDAY)
672 monotime_init_internal(
void)
688 ratchet_timeval(&timeval_raw, &out->tv_);
697 timersub(&end->tv_, &start->tv_, &diff);
698 return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
703 const monotime_coarse_t *end)
706 timersub(&end->tv_, &start->tv_, &diff);
707 return diff.tv_sec * 1000 + diff.tv_usec / 1000;
711 static const uint32_t STAMP_TICKS_PER_SECOND = 976;
716 const uint32_t usec = (uint32_t)t->tv_.tv_usec;
717 const uint32_t sec = (uint32_t)t->tv_.tv_sec;
718 return (sec * STAMP_TICKS_PER_SECOND) | (nsec >> 10);
724 return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0;
730 const uint32_t sec = msec / 1000;
731 const uint32_t msec_remainder = msec % 1000;
732 out->tv_.tv_sec = val->tv_.tv_sec + sec;
733 out->tv_.tv_usec = val->tv_.tv_nsec + (msec_remainder * 1000);
734 if (out->tv_.tv_usec > ONE_MILLION) {
735 out->tv_.tv_usec -= ONE_MILLION;
736 out->tv_.tv_sec += 1;
742 #error "No way to implement monotonic timers."
753 monotime_init_internal();
756 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
757 monotime_coarse_get(&initialized_at_coarse);
765 memset(out, 0,
sizeof(*out));
767 #ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
769 monotime_coarse_zero(monotime_coarse_t *out)
771 memset(out, 0,
sizeof(*out));
780 return CEIL_DIV(nsec, 1000);
788 return CEIL_DIV(nsec, ONE_MILLION);
815 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
817 monotime_coarse_absolute_nsec(
void)
823 monotime_coarse_t now;
824 monotime_coarse_get(&now);
825 return monotime_coarse_diff_nsec(&initialized_at_coarse, &now);
829 monotime_coarse_absolute_usec(
void)
831 return monotime_coarse_absolute_nsec() / 1000;
835 monotime_coarse_absolute_msec(
void)
837 return monotime_coarse_absolute_nsec() / ONE_MILLION;
840 #define initialized_at_coarse initialized_at
849 monotime_coarse_t now;
850 monotime_coarse_get(&now);
859 uint64_t abstime_diff = (units << monotime_shift);
860 return (abstime_diff * mach_time_info.numer) /
861 (mach_time_info.denom * ONE_MILLION);
864 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
866 uint64_t abstime_val =
867 (((uint64_t)msec) * ONE_MILLION * mach_time_info.denom) /
868 mach_time_info.numer;
869 return abstime_val >> monotime_shift;
875 return (units * 1000) / STAMP_TICKS_PER_SECOND;
878 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
880 return (msec * STAMP_TICKS_PER_SECOND) / 1000;
int tor_log2(uint64_t u64)
void tor_mutex_release(tor_mutex_t *m)
void tor_mutex_init(tor_mutex_t *m)
void tor_mutex_acquire(tor_mutex_t *m)
static int monotime_initialized
int64_t monotime_diff_msec(const monotime_t *start, const monotime_t *end)
uint64_t monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
void monotime_zero(monotime_t *out)
uint64_t monotime_absolute_nsec(void)
uint32_t monotime_coarse_get_stamp(void)
int64_t monotime_diff_usec(const monotime_t *start, const monotime_t *end)
uint64_t monotime_absolute_msec(void)
uint64_t monotime_absolute_usec(void)
Functions and types for monotonic times.
void monotime_get(monotime_t *out)
int monotime_is_zero(const monotime_t *out)
uint32_t monotime_coarse_to_stamp(const monotime_coarse_t *t)
void monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
int64_t monotime_diff_nsec(const monotime_t *start, const monotime_t *end)
int32_t monotime_coarse_diff_msec32_(const monotime_coarse_t *start, const monotime_coarse_t *end)
#define MOCK_IMPL(rv, funcname, arglist)
Declarations for timeval-related macros that some platforms are missing.
#define timercmp(tv1, tv2, op)
#define timeradd(tv1, tv2, tvout)
#define timersub(tv1, tv2, tvout)
void tor_gettimeofday(struct timeval *timeval)
Macros to manage assertions, fatal and non-fatal.