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