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);
257 uint64_t ns_per_tick = mach_time_info.numer / mach_time_info.denom;
258 uint64_t ms_per_tick = ns_per_tick * ONE_MILLION;
260 monotime_shift =
tor_log2(ms_per_tick);
267 mach_time_info_msec_cvt.numer = mach_time_info.numer * 2048;
268 mach_time_info_msec_cvt.denom = mach_time_info.denom * 1953;
272 mach_time_msec_cvt_threshold = INT32_MAX / mach_time_info_msec_cvt.numer;
284 #ifdef TOR_UNIT_TESTS
285 if (monotime_mocking_enabled) {
286 out->abstime_ = (mock_time_nsec * mach_time_info.denom)
287 / mach_time_info.numer;
291 out->abstime_ = mach_absolute_time();
294 #if defined(HAVE_MACH_APPROXIMATE_TIME)
296 monotime_coarse_get(monotime_coarse_t *out)
298 #ifdef TOR_UNIT_TESTS
299 if (monotime_mocking_enabled) {
300 out->abstime_ = (mock_time_nsec_coarse * mach_time_info.denom)
301 / mach_time_info.numer;
305 out->abstime_ = mach_approximate_time();
318 if (BUG(mach_time_info.denom == 0)) {
321 const int64_t diff_ticks = end->abstime_ - start->abstime_;
322 const int64_t diff_nsec =
323 (diff_ticks * mach_time_info.numer) / mach_time_info.denom;
329 const monotime_coarse_t *end)
331 if (BUG(mach_time_info.denom == 0)) {
334 const int64_t diff_ticks = end->abstime_ - start->abstime_;
337 const int32_t diff_microticks = (int32_t)(diff_ticks >> 20);
339 if (diff_microticks >= mach_time_msec_cvt_threshold) {
340 return (diff_microticks / mach_time_info_msec_cvt.denom) *
341 mach_time_info_msec_cvt.numer;
343 return (diff_microticks * mach_time_info_msec_cvt.numer) /
344 mach_time_info_msec_cvt.denom;
351 return (uint32_t)(t->abstime_ >> monotime_shift);
357 return val->abstime_ == 0;
363 const uint64_t nsec = msec * ONE_MILLION;
364 const uint64_t ticks = (nsec * mach_time_info.denom) / mach_time_info.numer;
365 out->abstime_ = val->abstime_ + ticks;
369 #elif defined(HAVE_CLOCK_GETTIME)
371 #ifdef CLOCK_MONOTONIC_COARSE
378 static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
382 monotime_init_internal(
void)
384 #ifdef CLOCK_MONOTONIC_COARSE
386 if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) < 0) {
387 log_info(
LD_GENERAL,
"CLOCK_MONOTONIC_COARSE isn't working (%s); "
388 "falling back to CLOCK_MONOTONIC.", strerror(errno));
389 clock_monotonic_coarse = CLOCK_MONOTONIC;
397 #ifdef TOR_UNIT_TESTS
398 if (monotime_mocking_enabled) {
399 out->ts_.tv_sec = (time_t) (mock_time_nsec / ONE_BILLION);
400 out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION);
404 int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
408 #ifdef CLOCK_MONOTONIC_COARSE
410 monotime_coarse_get(monotime_coarse_t *out)
412 #ifdef TOR_UNIT_TESTS
413 if (monotime_mocking_enabled) {
414 out->ts_.tv_sec = (time_t) (mock_time_nsec_coarse / ONE_BILLION);
415 out->ts_.tv_nsec = (int) (mock_time_nsec_coarse % ONE_BILLION);
419 int r = clock_gettime(clock_monotonic_coarse, &out->ts_);
420 if (PREDICT_UNLIKELY(r < 0) &&
422 clock_monotonic_coarse == CLOCK_MONOTONIC_COARSE) {
425 log_warn(
LD_BUG,
"Falling back to non-coarse monotonic time %s initial "
427 clock_monotonic_coarse = CLOCK_MONOTONIC;
428 r = clock_gettime(clock_monotonic_coarse, &out->ts_);
439 const int64_t diff_sec = end->ts_.tv_sec - start->ts_.tv_sec;
440 const int64_t diff_nsec = diff_sec * ONE_BILLION +
441 (end->ts_.tv_nsec - start->ts_.tv_nsec);
448 const monotime_coarse_t *end)
450 const int32_t diff_sec = (int32_t)(end->ts_.tv_sec - start->ts_.tv_sec);
451 const int32_t diff_nsec = (int32_t)(end->ts_.tv_nsec - start->ts_.tv_nsec);
452 return diff_sec * 1000 + diff_nsec / ONE_MILLION;
456 static const uint32_t STAMP_TICKS_PER_SECOND = 953;
461 uint32_t nsec = (uint32_t)t->ts_.tv_nsec;
462 uint32_t sec = (uint32_t)t->ts_.tv_sec;
464 return (sec * STAMP_TICKS_PER_SECOND) + (nsec >> 20);
470 return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0;
476 const uint32_t sec = msec / 1000;
477 const uint32_t msec_remainder = msec % 1000;
478 out->ts_.tv_sec = val->ts_.tv_sec + sec;
479 out->ts_.tv_nsec = val->ts_.tv_nsec + (msec_remainder * ONE_MILLION);
480 if (out->ts_.tv_nsec > ONE_BILLION) {
481 out->ts_.tv_nsec -= ONE_BILLION;
482 out->ts_.tv_sec += 1;
487 #elif defined (_WIN32)
491 static int64_t nsec_per_tick_numer = 1;
492 static int64_t nsec_per_tick_denom = 1;
495 static CRITICAL_SECTION monotime_lock;
497 static CRITICAL_SECTION monotime_coarse_lock;
499 typedef ULONGLONG (WINAPI *GetTickCount64_fn_t)(void);
500 static GetTickCount64_fn_t GetTickCount64_fn = NULL;
503 monotime_init_internal(
void)
506 BOOL ok = InitializeCriticalSectionAndSpinCount(&monotime_lock, 200);
508 ok = InitializeCriticalSectionAndSpinCount(&monotime_coarse_lock, 200);
511 ok = QueryPerformanceFrequency(&li);
515 uint64_t n = ONE_BILLION;
516 uint64_t d = li.QuadPart;
518 simplify_fraction64(&n, &d);
522 nsec_per_tick_numer = (int64_t) n;
523 nsec_per_tick_denom = (int64_t) d;
528 HANDLE h = load_windows_system_library(TEXT(
"kernel32.dll"));
530 GetTickCount64_fn = (GetTickCount64_fn_t) (
void(*)(void))
531 GetProcAddress(h,
"GetTickCount64");
545 #ifdef TOR_UNIT_TESTS
546 if (monotime_mocking_enabled) {
547 out->pcount_ = (mock_time_nsec * nsec_per_tick_denom)
548 / nsec_per_tick_numer;
558 EnterCriticalSection(&monotime_lock);
560 BOOL ok = QueryPerformanceCounter(&res);
562 const int64_t count_raw = res.QuadPart;
563 out->pcount_ = ratchet_performance_counter(count_raw);
564 LeaveCriticalSection(&monotime_lock);
568 monotime_coarse_get(monotime_coarse_t *out)
570 #ifdef TOR_UNIT_TESTS
571 if (monotime_mocking_enabled) {
572 out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
577 if (GetTickCount64_fn) {
578 out->tick_count_ = (int64_t)GetTickCount64_fn();
580 EnterCriticalSection(&monotime_coarse_lock);
581 DWORD tick = GetTickCount();
582 out->tick_count_ = ratchet_coarse_performance_counter(tick);
583 LeaveCriticalSection(&monotime_coarse_lock);
594 const int64_t diff_ticks = end->pcount_ - start->pcount_;
595 return (diff_ticks * nsec_per_tick_numer) / nsec_per_tick_denom;
599 monotime_coarse_diff_msec(
const monotime_coarse_t *start,
600 const monotime_coarse_t *end)
602 const int64_t diff_ticks = end->tick_count_ - start->tick_count_;
608 const monotime_coarse_t *end)
610 return (int32_t)monotime_coarse_diff_msec(start, end);
614 monotime_coarse_diff_usec(
const monotime_coarse_t *start,
615 const monotime_coarse_t *end)
617 return monotime_coarse_diff_msec(start, end) * 1000;
621 monotime_coarse_diff_nsec(
const monotime_coarse_t *start,
622 const monotime_coarse_t *end)
624 return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
627 static const uint32_t STAMP_TICKS_PER_SECOND = 1000;
632 return (uint32_t) t->tick_count_;
638 return val->pcount_ == 0;
642 monotime_coarse_is_zero(
const monotime_coarse_t *val)
644 return val->tick_count_ == 0;
650 const uint64_t nsec = msec * ONE_MILLION;
651 const uint64_t ticks = (nsec * nsec_per_tick_denom) / nsec_per_tick_numer;
652 out->pcount_ = val->pcount_ + ticks;
656 monotime_coarse_add_msec(monotime_coarse_t *out,
const monotime_coarse_t *val,
659 out->tick_count_ = val->tick_count_ + msec;
663 #elif defined(MONOTIME_USING_GETTIMEOFDAY)
669 monotime_init_internal(
void)
685 ratchet_timeval(&timeval_raw, &out->tv_);
694 timersub(&end->tv_, &start->tv_, &diff);
695 return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
700 const monotime_coarse_t *end)
703 timersub(&end->tv_, &start->tv_, &diff);
704 return diff.tv_sec * 1000 + diff.tv_usec / 1000;
708 static const uint32_t STAMP_TICKS_PER_SECOND = 976;
713 const uint32_t usec = (uint32_t)t->tv_.tv_usec;
714 const uint32_t sec = (uint32_t)t->tv_.tv_sec;
715 return (sec * STAMP_TICKS_PER_SECOND) | (nsec >> 10);
721 return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0;
727 const uint32_t sec = msec / 1000;
728 const uint32_t msec_remainder = msec % 1000;
729 out->tv_.tv_sec = val->tv_.tv_sec + sec;
730 out->tv_.tv_usec = val->tv_.tv_nsec + (msec_remainder * 1000);
731 if (out->tv_.tv_usec > ONE_MILLION) {
732 out->tv_.tv_usec -= ONE_MILLION;
733 out->tv_.tv_sec += 1;
739 #error "No way to implement monotonic timers."
750 monotime_init_internal();
753 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
754 monotime_coarse_get(&initialized_at_coarse);
762 memset(out, 0,
sizeof(*out));
764 #ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
766 monotime_coarse_zero(monotime_coarse_t *out)
768 memset(out, 0,
sizeof(*out));
777 return CEIL_DIV(nsec, 1000);
785 return CEIL_DIV(nsec, ONE_MILLION);
812 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
814 monotime_coarse_absolute_nsec(
void)
820 monotime_coarse_t now;
821 monotime_coarse_get(&now);
822 return monotime_coarse_diff_nsec(&initialized_at_coarse, &now);
826 monotime_coarse_absolute_usec(
void)
828 return monotime_coarse_absolute_nsec() / 1000;
832 monotime_coarse_absolute_msec(
void)
834 return monotime_coarse_absolute_nsec() / ONE_MILLION;
837 #define initialized_at_coarse initialized_at
846 monotime_coarse_t now;
847 monotime_coarse_get(&now);
856 uint64_t abstime_diff = (units << monotime_shift);
857 return (abstime_diff * mach_time_info.numer) /
858 (mach_time_info.denom * ONE_MILLION);
861 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
863 uint64_t abstime_val =
864 (((uint64_t)msec) * ONE_MILLION * mach_time_info.denom) /
865 mach_time_info.numer;
866 return abstime_val >> monotime_shift;
872 return (units * 1000) / STAMP_TICKS_PER_SECOND;
875 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
877 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.