Tor 0.4.9.0-alpha-dev
compat_time.c
Go to the documentation of this file.
1/* Copyright (c) 2003-2004, Roger Dingledine
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4/* See LICENSE for licensing information */
5
6/**
7 * \file compat_time.c
8 * \brief Portable wrappers for finding out the current time, running
9 * timers, etc.
10 **/
11
12#define COMPAT_TIME_PRIVATE
14
15#include "lib/err/torerr.h"
16#include "lib/log/log.h"
17#include "lib/log/util_bug.h"
18#include "lib/intmath/muldiv.h"
19#include "lib/intmath/bits.h"
20#include "lib/fs/winlib.h"
22
23#ifdef _WIN32
24#include <winsock2.h>
25#include <windows.h>
26#endif
27
28#ifdef HAVE_SYS_TYPES_H
29#include <sys/types.h>
30#endif
31#ifdef HAVE_SYS_TIME_H
32#include <sys/time.h>
33#endif
34#ifdef HAVE_UNISTD_H
35#include <unistd.h>
36#endif
37#ifdef TOR_UNIT_TESTS
38#if !defined(HAVE_USLEEP) && defined(HAVE_SYS_SELECT_H)
39/* as fallback implementation for tor_sleep_msec */
40#include <sys/select.h>
41#endif
42#endif /* defined(TOR_UNIT_TESTS) */
43
44#ifdef __APPLE__
45#include <mach/mach_time.h>
46#endif
47
48#include <errno.h>
49#include <stdlib.h>
50#include <string.h>
51
52#ifdef _WIN32
53#undef HAVE_CLOCK_GETTIME
54#endif
55
56#ifdef TOR_UNIT_TESTS
57/** Delay for <b>msec</b> milliseconds. Only used in tests. */
58void
59tor_sleep_msec(int msec)
60{
61#ifdef _WIN32
62 Sleep(msec);
63#elif defined(HAVE_USLEEP)
64 sleep(msec / 1000);
65 /* Some usleep()s hate sleeping more than 1 sec */
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);
70#else
71 sleep(CEIL_DIV(msec, 1000));
72#endif /* defined(_WIN32) || ... */
73}
74#endif /* defined(TOR_UNIT_TESTS) */
75
76#define ONE_MILLION ((int64_t) (1000 * 1000))
77#define ONE_BILLION ((int64_t) (1000 * 1000 * 1000))
78
79/** True iff monotime_init has been called. */
80static int monotime_initialized = 0;
81
82static monotime_t initialized_at;
83#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
84static monotime_coarse_t initialized_at_coarse;
85#endif
86
87#ifdef TOR_UNIT_TESTS
88/** True if we are running unit tests and overriding the current monotonic
89 * time. Note that mocked monotonic time might not be monotonic.
90 */
91static int monotime_mocking_enabled = 0;
92static monotime_t initialized_at_saved;
93
94static int64_t mock_time_nsec = 0;
95#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
96static int64_t mock_time_nsec_coarse = 0;
97static monotime_coarse_t initialized_at_coarse_saved;
98#endif
99
100void
101monotime_enable_test_mocking(void)
102{
103 if (BUG(monotime_initialized == 0)) {
105 }
106
107 tor_assert_nonfatal(monotime_mocking_enabled == 0);
108 monotime_mocking_enabled = 1;
109 memcpy(&initialized_at_saved,
110 &initialized_at, sizeof(monotime_t));
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));
116#endif
117}
118
119void
120monotime_disable_test_mocking(void)
121{
122 tor_assert_nonfatal(monotime_mocking_enabled == 1);
123 monotime_mocking_enabled = 0;
124
125 memcpy(&initialized_at,
126 &initialized_at_saved, sizeof(monotime_t));
127#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
128 memcpy(&initialized_at_coarse,
129 &initialized_at_coarse_saved, sizeof(monotime_coarse_t));
130#endif
131}
132
133void
134monotime_set_mock_time_nsec(int64_t nsec)
135{
136 tor_assert_nonfatal(monotime_mocking_enabled == 1);
137 mock_time_nsec = nsec;
138}
139
140#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
141void
142monotime_coarse_set_mock_time_nsec(int64_t nsec)
143{
144 tor_assert_nonfatal(monotime_mocking_enabled == 1);
145 mock_time_nsec_coarse = nsec;
146}
147#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
148#endif /* defined(TOR_UNIT_TESTS) */
149
150/* "ratchet" functions for monotonic time. */
151
152#if defined(_WIN32) || defined(TOR_UNIT_TESTS)
153
154/** Protected by lock: last value returned by monotime_get(). */
155static int64_t last_pctr = 0;
156/** Protected by lock: offset we must add to monotonic time values. */
157static int64_t pctr_offset = 0;
158/* If we are using GetTickCount(), how many times has it rolled over? */
159static uint32_t rollover_count = 0;
160/* If we are using GetTickCount(), what's the last value it returned? */
161static int64_t last_tick_count = 0;
162
163/** Helper for windows: Called with a sequence of times that are supposed
164 * to be monotonic; increments them as appropriate so that they actually
165 * _are_ monotonic.
166 *
167 * The returned time may be the same as the previous returned time.
168 *
169 * Caller must hold lock. */
170STATIC int64_t
171ratchet_performance_counter(int64_t count_raw)
172{
173 /* must hold lock */
174 const int64_t count_adjusted = count_raw + pctr_offset;
175
176 if (PREDICT_UNLIKELY(count_adjusted < last_pctr)) {
177 /* Monotonicity failed! Pretend no time elapsed. */
178 pctr_offset = last_pctr - count_raw;
179 return last_pctr;
180 } else {
181 last_pctr = count_adjusted;
182 return count_adjusted;
183 }
184}
185
186STATIC int64_t
187ratchet_coarse_performance_counter(const int64_t count_raw)
188{
189 int64_t count = count_raw + (((int64_t)rollover_count) << 32);
190 while (PREDICT_UNLIKELY(count < last_tick_count)) {
191 ++rollover_count;
192 count = count_raw + (((int64_t)rollover_count) << 32);
193 }
194 last_tick_count = count;
195 return count;
196}
197#endif /* defined(_WIN32) || defined(TOR_UNIT_TESTS) */
198
199#if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS)
200static struct timeval last_timeofday = { 0, 0 };
201static struct timeval timeofday_offset = { 0, 0 };
202
203/** Helper for gettimeofday(): Called with a sequence of times that are
204 * supposed to be monotonic; increments them as appropriate so that they
205 * actually _are_ monotonic.
206 *
207 * The returned time may be the same as the previous returned time.
208 *
209 * Caller must hold lock. */
210STATIC void
211ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out)
212{
213 /* must hold lock */
214 timeradd(timeval_raw, &timeofday_offset, out);
215 if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, OP_LT))) {
216 /* time ran backwards. Instead, declare that no time occurred. */
217 timersub(&last_timeofday, timeval_raw, &timeofday_offset);
218 memcpy(out, &last_timeofday, sizeof(struct timeval));
219 } else {
220 memcpy(&last_timeofday, out, sizeof(struct timeval));
221 }
222}
223#endif /* defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS) */
224
225#ifdef TOR_UNIT_TESTS
226/** For testing: reset all the ratchets */
227void
228monotime_reset_ratchets_for_testing(void)
229{
230 last_pctr = pctr_offset = last_tick_count = 0;
231 rollover_count = 0;
232 memset(&last_timeofday, 0, sizeof(struct timeval));
233 memset(&timeofday_offset, 0, sizeof(struct timeval));
234}
235#endif /* defined(TOR_UNIT_TESTS) */
236
237#ifdef __APPLE__
238
239/** Initialized on startup: tells is how to convert from ticks to
240 * nanoseconds.
241 */
242static struct mach_timebase_info mach_time_info;
243static struct mach_timebase_info mach_time_info_msec_cvt;
244static int32_t mach_time_msec_cvt_threshold;
245static int monotime_shift = 0;
246
247static void
248monotime_init_internal(void)
249{
251 int r = mach_timebase_info(&mach_time_info);
252 tor_assert(r == 0);
253 tor_assert(mach_time_info.denom != 0);
254
255 {
256 // We want to compute this, approximately:
257 // uint64_t ns_per_tick = mach_time_info.numer / mach_time_info.denom;
258 // uint64_t ticks_per_ms = ONE_MILLION / ns_per_tick;
259 // This calculation multiplies first, though, to improve accuracy.
260 uint64_t ticks_per_ms = (ONE_MILLION * mach_time_info.denom)
261 / mach_time_info.numer;
262 // requires that tor_log2(0) == 0.
263 monotime_shift = tor_log2(ticks_per_ms);
264 }
265 {
266 // For converting ticks to milliseconds in a 32-bit-friendly way, we
267 // will first right-shift by 20, and then multiply by 2048/1953, since
268 // (1<<20) * 1953/2048 is about 1e6. We precompute a new numerator and
269 // denominator here to avoid multiple multiplies.
270 mach_time_info_msec_cvt.numer = mach_time_info.numer * 2048;
271 mach_time_info_msec_cvt.denom = mach_time_info.denom * 1953;
272 // For any value above this amount, we should divide before multiplying,
273 // to avoid overflow. For a value below this, we should multiply
274 // before dividing, to improve accuracy.
275 mach_time_msec_cvt_threshold = INT32_MAX / mach_time_info_msec_cvt.numer;
276 }
277}
278
279/**
280 * Set "out" to the most recent monotonic time value.
281 *
282 * The returned time may be the same as the previous returned time.
283 */
284void
286{
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;
291 return;
292 }
293#endif /* defined(TOR_UNIT_TESTS) */
294 out->abstime_ = mach_absolute_time();
295}
296
297#if defined(HAVE_MACH_APPROXIMATE_TIME)
298void
299monotime_coarse_get(monotime_coarse_t *out)
300{
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;
305 return;
306 }
307#endif /* defined(TOR_UNIT_TESTS) */
308 out->abstime_ = mach_approximate_time();
309}
310#endif /* defined(HAVE_MACH_APPROXIMATE_TIME) */
311
312/**
313 * Return the number of nanoseconds between <b>start</b> and <b>end</b>.
314 *
315 * The returned value may be equal to zero.
316 */
317int64_t
318monotime_diff_nsec(const monotime_t *start,
319 const monotime_t *end)
320{
321 if (BUG(mach_time_info.denom == 0)) {
323 }
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;
327 return diff_nsec;
328}
329
330int32_t
331monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
332 const monotime_coarse_t *end)
333{
334 if (BUG(mach_time_info.denom == 0)) {
336 }
337 const int64_t diff_ticks = end->abstime_ - start->abstime_;
338
339 /* We already require in di_ops.c that right-shift performs a sign-extend. */
340 const int32_t diff_microticks = (int32_t)(diff_ticks >> 20);
341
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;
345 } else {
346 return (diff_microticks * mach_time_info_msec_cvt.numer) /
347 mach_time_info_msec_cvt.denom;
348 }
349}
350
351uint32_t
352monotime_coarse_to_stamp(const monotime_coarse_t *t)
353{
354 return (uint32_t)(t->abstime_ >> monotime_shift);
355}
356
357int
359{
360 return val->abstime_ == 0;
361}
362
363void
364monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
365{
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;
369}
370
371/* end of "__APPLE__" */
372#elif defined(HAVE_CLOCK_GETTIME)
373
374#ifdef CLOCK_MONOTONIC_COARSE
375/**
376 * Which clock should we use for coarse-grained monotonic time? By default
377 * this is CLOCK_MONOTONIC_COARSE, but it might not work -- for example,
378 * if we're compiled with newer Linux headers and then we try to run on
379 * an old Linux kernel. In that case, we will fall back to CLOCK_MONOTONIC.
380 */
381static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
382#endif /* defined(CLOCK_MONOTONIC_COARSE) */
383
384static void
385monotime_init_internal(void)
386{
387#ifdef CLOCK_MONOTONIC_COARSE
388 struct timespec ts;
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;
393 }
394#endif /* defined(CLOCK_MONOTONIC_COARSE) */
395}
396
397void
399{
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);
404 return;
405 }
406#endif /* defined(TOR_UNIT_TESTS) */
407 int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
408 tor_assert(r == 0);
409}
410
411#ifdef CLOCK_MONOTONIC_COARSE
412void
413monotime_coarse_get(monotime_coarse_t *out)
414{
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);
419 return;
420 }
421#endif /* defined(TOR_UNIT_TESTS) */
422 int r = clock_gettime(clock_monotonic_coarse, &out->ts_);
423 if (PREDICT_UNLIKELY(r < 0) &&
424 errno == EINVAL &&
425 clock_monotonic_coarse == CLOCK_MONOTONIC_COARSE) {
426 /* We should have caught this at startup in monotime_init_internal!
427 */
428 log_warn(LD_BUG, "Falling back to non-coarse monotonic time %s initial "
429 "system start?", monotime_initialized?"after":"without");
430 clock_monotonic_coarse = CLOCK_MONOTONIC;
431 r = clock_gettime(clock_monotonic_coarse, &out->ts_);
432 }
433
434 tor_assert(r == 0);
435}
436#endif /* defined(CLOCK_MONOTONIC_COARSE) */
437
438int64_t
439monotime_diff_nsec(const monotime_t *start,
440 const monotime_t *end)
441{
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);
445
446 return diff_nsec;
447}
448
449int32_t
450monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
451 const monotime_coarse_t *end)
452{
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;
456}
457
458/* This value is ONE_BILLION >> 20. */
459static const uint32_t STAMP_TICKS_PER_SECOND = 953;
460
461uint32_t
462monotime_coarse_to_stamp(const monotime_coarse_t *t)
463{
464 uint32_t nsec = (uint32_t)t->ts_.tv_nsec;
465 uint32_t sec = (uint32_t)t->ts_.tv_sec;
466
467 return (sec * STAMP_TICKS_PER_SECOND) + (nsec >> 20);
468}
469
470int
472{
473 return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0;
474}
475
476void
477monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
478{
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;
486 }
487}
488
489/* end of "HAVE_CLOCK_GETTIME" */
490#elif defined (_WIN32)
491
492/** Result of QueryPerformanceFrequency, in terms needed to
493 * convert ticks to nanoseconds. */
494static int64_t nsec_per_tick_numer = 1;
495static int64_t nsec_per_tick_denom = 1;
496
497/** Lock to protect last_pctr and pctr_offset */
498static CRITICAL_SECTION monotime_lock;
499/** Lock to protect rollover_count and last_tick_count */
500static CRITICAL_SECTION monotime_coarse_lock;
501
502typedef ULONGLONG (WINAPI *GetTickCount64_fn_t)(void);
503static GetTickCount64_fn_t GetTickCount64_fn = NULL;
504
505static void
506monotime_init_internal(void)
507{
509 BOOL ok = InitializeCriticalSectionAndSpinCount(&monotime_lock, 200);
510 tor_assert(ok);
511 ok = InitializeCriticalSectionAndSpinCount(&monotime_coarse_lock, 200);
512 tor_assert(ok);
513 LARGE_INTEGER li;
514 ok = QueryPerformanceFrequency(&li);
515 tor_assert(ok);
516 tor_assert(li.QuadPart);
517
518 uint64_t n = ONE_BILLION;
519 uint64_t d = li.QuadPart;
520 /* We need to simplify this or we'll probably overflow the int64. */
521 simplify_fraction64(&n, &d);
522 tor_assert(n <= INT64_MAX);
523 tor_assert(d <= INT64_MAX);
524
525 nsec_per_tick_numer = (int64_t) n;
526 nsec_per_tick_denom = (int64_t) d;
527
528 last_pctr = 0;
529 pctr_offset = 0;
530
531 HANDLE h = load_windows_system_library(TEXT("kernel32.dll"));
532 if (h) {
533 GetTickCount64_fn = (GetTickCount64_fn_t) (void(*)(void))
534 GetProcAddress(h, "GetTickCount64");
535 }
536 // We can't call FreeLibrary(h) here, because freeing the handle may
537 // unload the library, and cause future calls to GetTickCount64_fn()
538 // to fail. See 29642 for details.
539}
540
541void
543{
544 if (BUG(monotime_initialized == 0)) {
546 }
547
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;
552 return;
553 }
554#endif /* defined(TOR_UNIT_TESTS) */
555
556 /* Alas, QueryPerformanceCounter is not always monotonic: see bug list at
557
558 https://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter
559 */
560
561 EnterCriticalSection(&monotime_lock);
562 LARGE_INTEGER res;
563 BOOL ok = QueryPerformanceCounter(&res);
564 tor_assert(ok);
565 const int64_t count_raw = res.QuadPart;
566 out->pcount_ = ratchet_performance_counter(count_raw);
567 LeaveCriticalSection(&monotime_lock);
568}
569
570void
571monotime_coarse_get(monotime_coarse_t *out)
572{
573#ifdef TOR_UNIT_TESTS
574 if (monotime_mocking_enabled) {
575 out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
576 return;
577 }
578#endif /* defined(TOR_UNIT_TESTS) */
579
580 if (GetTickCount64_fn) {
581 out->tick_count_ = (int64_t)GetTickCount64_fn();
582 } else {
583 EnterCriticalSection(&monotime_coarse_lock);
584 DWORD tick = GetTickCount();
585 out->tick_count_ = ratchet_coarse_performance_counter(tick);
586 LeaveCriticalSection(&monotime_coarse_lock);
587 }
588}
589
590int64_t
591monotime_diff_nsec(const monotime_t *start,
592 const monotime_t *end)
593{
594 if (BUG(monotime_initialized == 0)) {
596 }
597 const int64_t diff_ticks = end->pcount_ - start->pcount_;
598 return (diff_ticks * nsec_per_tick_numer) / nsec_per_tick_denom;
599}
600
601int64_t
602monotime_coarse_diff_msec(const monotime_coarse_t *start,
603 const monotime_coarse_t *end)
604{
605 const int64_t diff_ticks = end->tick_count_ - start->tick_count_;
606 return diff_ticks;
607}
608
609int32_t
610monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
611 const monotime_coarse_t *end)
612{
613 return (int32_t)monotime_coarse_diff_msec(start, end);
614}
615
616int64_t
617monotime_coarse_diff_usec(const monotime_coarse_t *start,
618 const monotime_coarse_t *end)
619{
620 return monotime_coarse_diff_msec(start, end) * 1000;
621}
622
623int64_t
624monotime_coarse_diff_nsec(const monotime_coarse_t *start,
625 const monotime_coarse_t *end)
626{
627 return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
628}
629
630static const uint32_t STAMP_TICKS_PER_SECOND = 1000;
631
632uint32_t
633monotime_coarse_to_stamp(const monotime_coarse_t *t)
634{
635 return (uint32_t) t->tick_count_;
636}
637
638int
640{
641 return val->pcount_ == 0;
642}
643
644int
645monotime_coarse_is_zero(const monotime_coarse_t *val)
646{
647 return val->tick_count_ == 0;
648}
649
650void
651monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
652{
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;
656}
657
658void
659monotime_coarse_add_msec(monotime_coarse_t *out, const monotime_coarse_t *val,
660 uint32_t msec)
661{
662 out->tick_count_ = val->tick_count_ + msec;
663}
664
665/* end of "_WIN32" */
666#elif defined(MONOTIME_USING_GETTIMEOFDAY)
667
668static tor_mutex_t monotime_lock;
669
670/** Initialize the monotonic timer subsystem. */
671static void
672monotime_init_internal(void)
673{
675 tor_mutex_init(&monotime_lock);
676}
677
678void
680{
681 if (BUG(monotime_initialized == 0)) {
683 }
684
685 tor_mutex_acquire(&monotime_lock);
686 struct timeval timeval_raw;
687 tor_gettimeofday(&timeval_raw);
688 ratchet_timeval(&timeval_raw, &out->tv_);
689 tor_mutex_release(&monotime_lock);
690}
691
692int64_t
693monotime_diff_nsec(const monotime_t *start,
694 const monotime_t *end)
695{
696 struct timeval diff;
697 timersub(&end->tv_, &start->tv_, &diff);
698 return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
699}
700
701int32_t
702monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
703 const monotime_coarse_t *end)
704{
705 struct timeval diff;
706 timersub(&end->tv_, &start->tv_, &diff);
707 return diff.tv_sec * 1000 + diff.tv_usec / 1000;
708}
709
710/* This value is ONE_MILLION >> 10. */
711static const uint32_t STAMP_TICKS_PER_SECOND = 976;
712
713uint32_t
714monotime_coarse_to_stamp(const monotime_coarse_t *t)
715{
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);
719}
720
721int
723{
724 return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0;
725}
726
727void
728monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
729{
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;
737 }
738}
739
740/* end of "MONOTIME_USING_GETTIMEOFDAY" */
741#else
742#error "No way to implement monotonic timers."
743#endif /* defined(__APPLE__) || ... */
744
745/**
746 * Initialize the monotonic timer subsystem. Must be called before any
747 * monotonic timer functions. This function is idempotent.
748 */
749void
751{
753 monotime_init_internal();
755 monotime_get(&initialized_at);
756#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
757 monotime_coarse_get(&initialized_at_coarse);
758#endif
759 }
760}
761
762void
764{
765 memset(out, 0, sizeof(*out));
766}
767#ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
768void
769monotime_coarse_zero(monotime_coarse_t *out)
770{
771 memset(out, 0, sizeof(*out));
772}
773#endif /* defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT) */
774
775int64_t
777 const monotime_t *end)
778{
779 const int64_t nsec = monotime_diff_nsec(start, end);
780 return CEIL_DIV(nsec, 1000);
781}
782
783int64_t
785 const monotime_t *end)
786{
787 const int64_t nsec = monotime_diff_nsec(start, end);
788 return CEIL_DIV(nsec, ONE_MILLION);
789}
790
791uint64_t
793{
794 monotime_t now;
795 if (BUG(monotime_initialized == 0)) {
797 }
798
799 monotime_get(&now);
800 return monotime_diff_nsec(&initialized_at, &now);
801}
802
803MOCK_IMPL(uint64_t,
805{
806 return monotime_absolute_nsec() / 1000;
807}
808
809uint64_t
811{
812 return monotime_absolute_nsec() / ONE_MILLION;
813}
814
815uint64_t
817{
818 return monotime_absolute_nsec() / ONE_BILLION;
819}
820
821#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
822uint64_t
823monotime_coarse_absolute_nsec(void)
824{
825 if (BUG(monotime_initialized == 0)) {
827 }
828
829 monotime_coarse_t now;
830 monotime_coarse_get(&now);
831 return monotime_coarse_diff_nsec(&initialized_at_coarse, &now);
832}
833
834uint64_t
835monotime_coarse_absolute_usec(void)
836{
837 return monotime_coarse_absolute_nsec() / 1000;
838}
839
840uint64_t
841monotime_coarse_absolute_msec(void)
842{
843 return monotime_coarse_absolute_nsec() / ONE_MILLION;
844}
845
846uint64_t
847monotime_coarse_absolute_sec(void)
848{
849 /* Note: Right now I'm not too concerned about 64-bit division, but if this
850 * ever becomes a hotspot we need to optimize, we can modify this to grab
851 * tv_sec directly from CLOCK_MONOTONIC_COARSE on linux at least. Right now
852 * I'm choosing to make this simpler and easier to test, but this
853 * optimization is available easily if we need it. */
854 return monotime_coarse_absolute_nsec() / ONE_BILLION;
855}
856#else /* !defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
857#define initialized_at_coarse initialized_at
858#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
859
860/**
861 * Return the current time "stamp" as described by monotime_coarse_to_stamp.
862 */
863uint32_t
865{
866 monotime_coarse_t now;
867 monotime_coarse_get(&now);
868 return monotime_coarse_to_stamp(&now);
869}
870
871#ifdef __APPLE__
872uint64_t
874{
875 /* Recover as much precision as we can. */
876 uint64_t abstime_diff = (units << monotime_shift);
877 return (abstime_diff * mach_time_info.numer) /
878 (mach_time_info.denom * ONE_MILLION);
879}
880uint64_t
881monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
882{
883 uint64_t abstime_val =
884 (((uint64_t)msec) * ONE_MILLION * mach_time_info.denom) /
885 mach_time_info.numer;
886 return abstime_val >> monotime_shift;
887}
888#else /* !defined(__APPLE__) */
889uint64_t
891{
892 return (units * 1000) / STAMP_TICKS_PER_SECOND;
893}
894uint64_t
895monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
896{
897 return (msec * STAMP_TICKS_PER_SECOND) / 1000;
898}
899#endif /* defined(__APPLE__) */
int tor_log2(uint64_t u64)
Definition: bits.c:16
Header for bits.c.
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
Definition: compat_time.c:80
int64_t monotime_diff_msec(const monotime_t *start, const monotime_t *end)
Definition: compat_time.c:784
uint64_t monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
Definition: compat_time.c:890
void monotime_zero(monotime_t *out)
Definition: compat_time.c:763
uint64_t monotime_absolute_nsec(void)
Definition: compat_time.c:792
uint32_t monotime_coarse_get_stamp(void)
Definition: compat_time.c:864
void monotime_init(void)
Definition: compat_time.c:750
uint64_t monotime_absolute_sec(void)
Definition: compat_time.c:816
int64_t monotime_diff_usec(const monotime_t *start, const monotime_t *end)
Definition: compat_time.c:776
uint64_t monotime_absolute_msec(void)
Definition: compat_time.c:810
uint64_t monotime_absolute_usec(void)
Definition: compat_time.c:804
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)
Headers for log.c.
#define LD_BUG
Definition: log.h:86
#define LD_GENERAL
Definition: log.h:62
Header for muldiv.c.
#define STATIC
Definition: testsupport.h:32
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
Declarations for timeval-related macros that some platforms are missing.
#define timercmp(tv1, tv2, op)
Definition: timeval.h:81
#define timeradd(tv1, tv2, tvout)
Definition: timeval.h:47
#define timersub(tv1, tv2, tvout)
Definition: timeval.h:61
void tor_gettimeofday(struct timeval *timeval)
Headers for torerr.c.
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:103
Header for winlib.c.