12#define COMPAT_TIME_PRIVATE
28#ifdef HAVE_SYS_TYPES_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
62#elif defined(HAVE_TIME_H)
63 struct timespec ts = {msec / 1000, (msec % 1000) * 1000 * 1000};
64 while (nanosleep(&ts, &ts) == -1 && errno == EINTR);
65#elif defined(HAVE_USLEEP)
68 usleep((msec % 1000) * 1000);
69#elif defined(HAVE_SYS_SELECT_H)
70 struct timeval tv = { msec / 1000, (msec % 1000) * 1000};
71 select(0, NULL, NULL, NULL, &tv);
73 sleep(CEIL_DIV(msec, 1000));
77#define ONE_MILLION ((int64_t) (1000 * 1000))
78#define ONE_BILLION ((int64_t) (1000 * 1000 * 1000))
84#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
85static monotime_coarse_t initialized_at_coarse;
92static int monotime_mocking_enabled = 0;
95static int64_t mock_time_nsec = 0;
96#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
97static int64_t mock_time_nsec_coarse = 0;
98static monotime_coarse_t initialized_at_coarse_saved;
102monotime_enable_test_mocking(
void)
108 tor_assert_nonfatal(monotime_mocking_enabled == 0);
109 monotime_mocking_enabled = 1;
110 memcpy(&initialized_at_saved,
112 memset(&initialized_at, 0,
sizeof(
monotime_t));
113#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
114 memcpy(&initialized_at_coarse_saved,
115 &initialized_at_coarse,
sizeof(monotime_coarse_t));
116 memset(&initialized_at_coarse, 0,
sizeof(monotime_coarse_t));
121monotime_disable_test_mocking(
void)
123 tor_assert_nonfatal(monotime_mocking_enabled == 1);
124 monotime_mocking_enabled = 0;
126 memcpy(&initialized_at,
128#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
129 memcpy(&initialized_at_coarse,
130 &initialized_at_coarse_saved,
sizeof(monotime_coarse_t));
135monotime_set_mock_time_nsec(int64_t nsec)
137 tor_assert_nonfatal(monotime_mocking_enabled == 1);
138 mock_time_nsec = nsec;
141#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
143monotime_coarse_set_mock_time_nsec(int64_t nsec)
145 tor_assert_nonfatal(monotime_mocking_enabled == 1);
146 mock_time_nsec_coarse = nsec;
153#if defined(_WIN32) || defined(TOR_UNIT_TESTS)
156static int64_t last_pctr = 0;
158static int64_t pctr_offset = 0;
160static uint32_t rollover_count = 0;
162static int64_t last_tick_count = 0;
172ratchet_performance_counter(int64_t count_raw)
175 const int64_t count_adjusted = count_raw + pctr_offset;
177 if (PREDICT_UNLIKELY(count_adjusted < last_pctr)) {
179 pctr_offset = last_pctr - count_raw;
182 last_pctr = count_adjusted;
183 return count_adjusted;
188ratchet_coarse_performance_counter(
const int64_t count_raw)
190 int64_t count = count_raw + (((int64_t)rollover_count) << 32);
191 while (PREDICT_UNLIKELY(count < last_tick_count)) {
193 count = count_raw + (((int64_t)rollover_count) << 32);
195 last_tick_count = count;
200#if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS)
201static struct timeval last_timeofday = { 0, 0 };
202static struct timeval timeofday_offset = { 0, 0 };
212ratchet_timeval(
const struct timeval *timeval_raw,
struct timeval *out)
215 timeradd(timeval_raw, &timeofday_offset, out);
216 if (PREDICT_UNLIKELY(
timercmp(out, &last_timeofday, OP_LT))) {
218 timersub(&last_timeofday, timeval_raw, &timeofday_offset);
219 memcpy(out, &last_timeofday,
sizeof(
struct timeval));
221 memcpy(&last_timeofday, out,
sizeof(
struct timeval));
229monotime_reset_ratchets_for_testing(
void)
231 last_pctr = pctr_offset = last_tick_count = 0;
233 memset(&last_timeofday, 0,
sizeof(
struct timeval));
234 memset(&timeofday_offset, 0,
sizeof(
struct timeval));
243static struct mach_timebase_info mach_time_info;
244static struct mach_timebase_info mach_time_info_msec_cvt;
245static int32_t mach_time_msec_cvt_threshold;
246static int monotime_shift = 0;
249monotime_init_internal(
void)
252 int r = mach_timebase_info(&mach_time_info);
261 uint64_t ticks_per_ms = (ONE_MILLION * mach_time_info.denom)
262 / mach_time_info.numer;
264 monotime_shift =
tor_log2(ticks_per_ms);
271 mach_time_info_msec_cvt.numer = mach_time_info.numer * 2048;
272 mach_time_info_msec_cvt.denom = mach_time_info.denom * 1953;
276 mach_time_msec_cvt_threshold = INT32_MAX / mach_time_info_msec_cvt.numer;
289 if (monotime_mocking_enabled) {
290 out->abstime_ = (mock_time_nsec * mach_time_info.denom)
291 / mach_time_info.numer;
295 out->abstime_ = mach_absolute_time();
298#if defined(HAVE_MACH_APPROXIMATE_TIME)
300monotime_coarse_get(monotime_coarse_t *out)
303 if (monotime_mocking_enabled) {
304 out->abstime_ = (mock_time_nsec_coarse * mach_time_info.denom)
305 / mach_time_info.numer;
309 out->abstime_ = mach_approximate_time();
322 if (BUG(mach_time_info.denom == 0)) {
325 const int64_t diff_ticks = end->abstime_ - start->abstime_;
326 const int64_t diff_nsec =
327 (diff_ticks * mach_time_info.numer) / mach_time_info.denom;
333 const monotime_coarse_t *end)
335 if (BUG(mach_time_info.denom == 0)) {
338 const int64_t diff_ticks = end->abstime_ - start->abstime_;
341 const int32_t diff_microticks = (int32_t)(diff_ticks >> 20);
343 if (diff_microticks >= mach_time_msec_cvt_threshold) {
344 return (diff_microticks / mach_time_info_msec_cvt.denom) *
345 mach_time_info_msec_cvt.numer;
347 return (diff_microticks * mach_time_info_msec_cvt.numer) /
348 mach_time_info_msec_cvt.denom;
355 return (uint32_t)(t->abstime_ >> monotime_shift);
361 return val->abstime_ == 0;
367 const uint64_t nsec = msec * ONE_MILLION;
368 const uint64_t ticks = (nsec * mach_time_info.denom) / mach_time_info.numer;
369 out->abstime_ = val->abstime_ + ticks;
373#elif defined(HAVE_CLOCK_GETTIME)
375#ifdef CLOCK_MONOTONIC_COARSE
382static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
386monotime_init_internal(
void)
388#ifdef CLOCK_MONOTONIC_COARSE
390 if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) < 0) {
391 log_info(
LD_GENERAL,
"CLOCK_MONOTONIC_COARSE isn't working (%s); "
392 "falling back to CLOCK_MONOTONIC.", strerror(errno));
393 clock_monotonic_coarse = CLOCK_MONOTONIC;
402 if (monotime_mocking_enabled) {
403 out->ts_.tv_sec = (time_t) (mock_time_nsec / ONE_BILLION);
404 out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION);
408 int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
412#ifdef CLOCK_MONOTONIC_COARSE
414monotime_coarse_get(monotime_coarse_t *out)
417 if (monotime_mocking_enabled) {
418 out->ts_.tv_sec = (time_t) (mock_time_nsec_coarse / ONE_BILLION);
419 out->ts_.tv_nsec = (int) (mock_time_nsec_coarse % ONE_BILLION);
423 int r = clock_gettime(clock_monotonic_coarse, &out->ts_);
424 if (PREDICT_UNLIKELY(r < 0) &&
426 clock_monotonic_coarse == CLOCK_MONOTONIC_COARSE) {
429 log_warn(
LD_BUG,
"Falling back to non-coarse monotonic time %s initial "
431 clock_monotonic_coarse = CLOCK_MONOTONIC;
432 r = clock_gettime(clock_monotonic_coarse, &out->ts_);
443 const int64_t diff_sec = end->ts_.tv_sec - start->ts_.tv_sec;
444 const int64_t diff_nsec = diff_sec * ONE_BILLION +
445 (end->ts_.tv_nsec - start->ts_.tv_nsec);
452 const monotime_coarse_t *end)
454 const int32_t diff_sec = (int32_t)(end->ts_.tv_sec - start->ts_.tv_sec);
455 const int32_t diff_nsec = (int32_t)(end->ts_.tv_nsec - start->ts_.tv_nsec);
456 return diff_sec * 1000 + diff_nsec / ONE_MILLION;
460static const uint32_t STAMP_TICKS_PER_SECOND = 953;
465 uint32_t nsec = (uint32_t)t->ts_.tv_nsec;
466 uint32_t sec = (uint32_t)t->ts_.tv_sec;
468 return (sec * STAMP_TICKS_PER_SECOND) + (nsec >> 20);
474 return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0;
480 const uint32_t sec = msec / 1000;
481 const uint32_t msec_remainder = msec % 1000;
482 out->ts_.tv_sec = val->ts_.tv_sec + sec;
483 out->ts_.tv_nsec = val->ts_.tv_nsec + (msec_remainder * ONE_MILLION);
484 if (out->ts_.tv_nsec > ONE_BILLION) {
485 out->ts_.tv_nsec -= ONE_BILLION;
486 out->ts_.tv_sec += 1;
491#elif defined (_WIN32)
495static int64_t nsec_per_tick_numer = 1;
496static int64_t nsec_per_tick_denom = 1;
499static CRITICAL_SECTION monotime_lock;
501static CRITICAL_SECTION monotime_coarse_lock;
503typedef ULONGLONG (WINAPI *GetTickCount64_fn_t)(void);
504static GetTickCount64_fn_t GetTickCount64_fn = NULL;
507monotime_init_internal(
void)
510 BOOL ok = InitializeCriticalSectionAndSpinCount(&monotime_lock, 200);
512 ok = InitializeCriticalSectionAndSpinCount(&monotime_coarse_lock, 200);
515 ok = QueryPerformanceFrequency(&li);
519 uint64_t n = ONE_BILLION;
520 uint64_t d = li.QuadPart;
522 simplify_fraction64(&n, &d);
526 nsec_per_tick_numer = (int64_t) n;
527 nsec_per_tick_denom = (int64_t) d;
532 HANDLE h = load_windows_system_library(TEXT(
"kernel32.dll"));
534 GetTickCount64_fn = (GetTickCount64_fn_t) (
void(*)(void))
535 GetProcAddress(h,
"GetTickCount64");
550 if (monotime_mocking_enabled) {
551 out->pcount_ = (mock_time_nsec * nsec_per_tick_denom)
552 / nsec_per_tick_numer;
562 EnterCriticalSection(&monotime_lock);
564 BOOL ok = QueryPerformanceCounter(&res);
566 const int64_t count_raw = res.QuadPart;
567 out->pcount_ = ratchet_performance_counter(count_raw);
568 LeaveCriticalSection(&monotime_lock);
572monotime_coarse_get(monotime_coarse_t *out)
575 if (monotime_mocking_enabled) {
576 out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
581 if (GetTickCount64_fn) {
582 out->tick_count_ = (int64_t)GetTickCount64_fn();
584 EnterCriticalSection(&monotime_coarse_lock);
585 DWORD tick = GetTickCount();
586 out->tick_count_ = ratchet_coarse_performance_counter(tick);
587 LeaveCriticalSection(&monotime_coarse_lock);
598 const int64_t diff_ticks = end->pcount_ - start->pcount_;
599 return (diff_ticks * nsec_per_tick_numer) / nsec_per_tick_denom;
603monotime_coarse_diff_msec(
const monotime_coarse_t *start,
604 const monotime_coarse_t *end)
606 const int64_t diff_ticks = end->tick_count_ - start->tick_count_;
612 const monotime_coarse_t *end)
614 return (int32_t)monotime_coarse_diff_msec(start, end);
618monotime_coarse_diff_usec(
const monotime_coarse_t *start,
619 const monotime_coarse_t *end)
621 return monotime_coarse_diff_msec(start, end) * 1000;
625monotime_coarse_diff_nsec(
const monotime_coarse_t *start,
626 const monotime_coarse_t *end)
628 return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
631static const uint32_t STAMP_TICKS_PER_SECOND = 1000;
636 return (uint32_t) t->tick_count_;
642 return val->pcount_ == 0;
646monotime_coarse_is_zero(
const monotime_coarse_t *val)
648 return val->tick_count_ == 0;
654 const uint64_t nsec = msec * ONE_MILLION;
655 const uint64_t ticks = (nsec * nsec_per_tick_denom) / nsec_per_tick_numer;
656 out->pcount_ = val->pcount_ + ticks;
660monotime_coarse_add_msec(monotime_coarse_t *out,
const monotime_coarse_t *val,
663 out->tick_count_ = val->tick_count_ + msec;
667#elif defined(MONOTIME_USING_GETTIMEOFDAY)
673monotime_init_internal(
void)
689 ratchet_timeval(&timeval_raw, &out->tv_);
698 timersub(&end->tv_, &start->tv_, &diff);
699 return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
704 const monotime_coarse_t *end)
707 timersub(&end->tv_, &start->tv_, &diff);
708 return diff.tv_sec * 1000 + diff.tv_usec / 1000;
712static const uint32_t STAMP_TICKS_PER_SECOND = 976;
717 const uint32_t usec = (uint32_t)t->tv_.tv_usec;
718 const uint32_t sec = (uint32_t)t->tv_.tv_sec;
719 return (sec * STAMP_TICKS_PER_SECOND) | (nsec >> 10);
725 return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0;
731 const uint32_t sec = msec / 1000;
732 const uint32_t msec_remainder = msec % 1000;
733 out->tv_.tv_sec = val->tv_.tv_sec + sec;
734 out->tv_.tv_usec = val->tv_.tv_nsec + (msec_remainder * 1000);
735 if (out->tv_.tv_usec > ONE_MILLION) {
736 out->tv_.tv_usec -= ONE_MILLION;
737 out->tv_.tv_sec += 1;
743#error "No way to implement monotonic timers."
754 monotime_init_internal();
757#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
758 monotime_coarse_get(&initialized_at_coarse);
766 memset(out, 0,
sizeof(*out));
768#ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
770monotime_coarse_zero(monotime_coarse_t *out)
772 memset(out, 0,
sizeof(*out));
781 return CEIL_DIV(nsec, 1000);
789 return CEIL_DIV(nsec, ONE_MILLION);
822#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
824monotime_coarse_absolute_nsec(
void)
830 monotime_coarse_t now;
831 monotime_coarse_get(&now);
832 return monotime_coarse_diff_nsec(&initialized_at_coarse, &now);
836monotime_coarse_absolute_usec(
void)
838 return monotime_coarse_absolute_nsec() / 1000;
842monotime_coarse_absolute_msec(
void)
844 return monotime_coarse_absolute_nsec() / ONE_MILLION;
848monotime_coarse_absolute_sec(
void)
855 return monotime_coarse_absolute_nsec() / ONE_BILLION;
858#define initialized_at_coarse initialized_at
867 monotime_coarse_t now;
868 monotime_coarse_get(&now);
877 uint64_t abstime_diff = (units << monotime_shift);
878 return (abstime_diff * mach_time_info.numer) /
879 (mach_time_info.denom * ONE_MILLION);
882monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
884 uint64_t abstime_val =
885 (((uint64_t)msec) * ONE_MILLION * mach_time_info.denom) /
886 mach_time_info.numer;
887 return abstime_val >> monotime_shift;
893 return (units * 1000) / STAMP_TICKS_PER_SECOND;
896monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
898 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)
void tor_sleep_msec(int msec)
uint64_t monotime_absolute_nsec(void)
uint32_t monotime_coarse_get_stamp(void)
uint64_t monotime_absolute_sec(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.