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
13 #include "lib/time/compat_time.h"
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"
21 #include "lib/wallclock/timeval.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. */
58 void
tor_sleep_msec(int msec)59 tor_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. */
80 static int monotime_initialized = 0;
81
82 static monotime_t initialized_at;
83 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
84 static 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 */
91 static int monotime_mocking_enabled = 0;
92 static monotime_t initialized_at_saved;
93
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;
98 #endif
99
100 void
monotime_enable_test_mocking(void)101 monotime_enable_test_mocking(void)
102 {
103 if (BUG(monotime_initialized == 0)) {
104 monotime_init();
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
119 void
monotime_disable_test_mocking(void)120 monotime_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
133 void
monotime_set_mock_time_nsec(int64_t nsec)134 monotime_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
141 void
monotime_coarse_set_mock_time_nsec(int64_t nsec)142 monotime_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(). */
155 static int64_t last_pctr = 0;
156 /** Protected by lock: offset we must add to monotonic time values. */
157 static int64_t pctr_offset = 0;
158 /* If we are using GetTickCount(), how many times has it rolled over? */
159 static uint32_t rollover_count = 0;
160 /* If we are using GetTickCount(), what's the last value it returned? */
161 static 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. */
170 STATIC int64_t
ratchet_performance_counter(int64_t count_raw)171 ratchet_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
186 STATIC int64_t
ratchet_coarse_performance_counter(const int64_t count_raw)187 ratchet_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)
200 static struct timeval last_timeofday = { 0, 0 };
201 static 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. */
210 STATIC void
ratchet_timeval(const struct timeval * timeval_raw,struct timeval * out)211 ratchet_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 */
227 void
monotime_reset_ratchets_for_testing(void)228 monotime_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 */
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;
246
247 static void
monotime_init_internal(void)248 monotime_init_internal(void)
249 {
250 tor_assert(!monotime_initialized);
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 // approximate only.
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;
259 // requires that tor_log2(0) == 0.
260 monotime_shift = tor_log2(ms_per_tick);
261 }
262 {
263 // For converting ticks to milliseconds in a 32-bit-friendly way, we
264 // will first right-shift by 20, and then multiply by 2048/1953, since
265 // (1<<20) * 1953/2048 is about 1e6. We precompute a new numerator and
266 // denominator here to avoid multiple multiplies.
267 mach_time_info_msec_cvt.numer = mach_time_info.numer * 2048;
268 mach_time_info_msec_cvt.denom = mach_time_info.denom * 1953;
269 // For any value above this amount, we should divide before multiplying,
270 // to avoid overflow. For a value below this, we should multiply
271 // before dividing, to improve accuracy.
272 mach_time_msec_cvt_threshold = INT32_MAX / mach_time_info_msec_cvt.numer;
273 }
274 }
275
276 /**
277 * Set "out" to the most recent monotonic time value.
278 *
279 * The returned time may be the same as the previous returned time.
280 */
281 void
monotime_get(monotime_t * out)282 monotime_get(monotime_t *out)
283 {
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;
288 return;
289 }
290 #endif /* defined(TOR_UNIT_TESTS) */
291 out->abstime_ = mach_absolute_time();
292 }
293
294 #if defined(HAVE_MACH_APPROXIMATE_TIME)
295 void
monotime_coarse_get(monotime_coarse_t * out)296 monotime_coarse_get(monotime_coarse_t *out)
297 {
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;
302 return;
303 }
304 #endif /* defined(TOR_UNIT_TESTS) */
305 out->abstime_ = mach_approximate_time();
306 }
307 #endif /* defined(HAVE_MACH_APPROXIMATE_TIME) */
308
309 /**
310 * Return the number of nanoseconds between <b>start</b> and <b>end</b>.
311 *
312 * The returned value may be equal to zero.
313 */
314 int64_t
monotime_diff_nsec(const monotime_t * start,const monotime_t * end)315 monotime_diff_nsec(const monotime_t *start,
316 const monotime_t *end)
317 {
318 if (BUG(mach_time_info.denom == 0)) {
319 monotime_init();
320 }
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;
324 return diff_nsec;
325 }
326
327 int32_t
monotime_coarse_diff_msec32_(const monotime_coarse_t * start,const monotime_coarse_t * end)328 monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
329 const monotime_coarse_t *end)
330 {
331 if (BUG(mach_time_info.denom == 0)) {
332 monotime_init();
333 }
334 const int64_t diff_ticks = end->abstime_ - start->abstime_;
335
336 /* We already require in di_ops.c that right-shift performs a sign-extend. */
337 const int32_t diff_microticks = (int32_t)(diff_ticks >> 20);
338
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;
342 } else {
343 return (diff_microticks * mach_time_info_msec_cvt.numer) /
344 mach_time_info_msec_cvt.denom;
345 }
346 }
347
348 uint32_t
monotime_coarse_to_stamp(const monotime_coarse_t * t)349 monotime_coarse_to_stamp(const monotime_coarse_t *t)
350 {
351 return (uint32_t)(t->abstime_ >> monotime_shift);
352 }
353
354 int
monotime_is_zero(const monotime_t * val)355 monotime_is_zero(const monotime_t *val)
356 {
357 return val->abstime_ == 0;
358 }
359
360 void
monotime_add_msec(monotime_t * out,const monotime_t * val,uint32_t msec)361 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
362 {
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;
366 }
367
368 /* end of "__APPLE__" */
369 #elif defined(HAVE_CLOCK_GETTIME)
370
371 #ifdef CLOCK_MONOTONIC_COARSE
372 /**
373 * Which clock should we use for coarse-grained monotonic time? By default
374 * this is CLOCK_MONOTONIC_COARSE, but it might not work -- for example,
375 * if we're compiled with newer Linux headers and then we try to run on
376 * an old Linux kernel. In that case, we will fall back to CLOCK_MONOTONIC.
377 */
378 static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
379 #endif /* defined(CLOCK_MONOTONIC_COARSE) */
380
381 static void
monotime_init_internal(void)382 monotime_init_internal(void)
383 {
384 #ifdef CLOCK_MONOTONIC_COARSE
385 struct timespec ts;
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;
390 }
391 #endif /* defined(CLOCK_MONOTONIC_COARSE) */
392 }
393
394 void
monotime_get(monotime_t * out)395 monotime_get(monotime_t *out)
396 {
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);
401 return;
402 }
403 #endif /* defined(TOR_UNIT_TESTS) */
404 int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
405 tor_assert(r == 0);
406 }
407
408 #ifdef CLOCK_MONOTONIC_COARSE
409 void
monotime_coarse_get(monotime_coarse_t * out)410 monotime_coarse_get(monotime_coarse_t *out)
411 {
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);
416 return;
417 }
418 #endif /* defined(TOR_UNIT_TESTS) */
419 int r = clock_gettime(clock_monotonic_coarse, &out->ts_);
420 if (PREDICT_UNLIKELY(r < 0) &&
421 errno == EINVAL &&
422 clock_monotonic_coarse == CLOCK_MONOTONIC_COARSE) {
423 /* We should have caught this at startup in monotime_init_internal!
424 */
425 log_warn(LD_BUG, "Falling back to non-coarse monotonic time %s initial "
426 "system start?", monotime_initialized?"after":"without");
427 clock_monotonic_coarse = CLOCK_MONOTONIC;
428 r = clock_gettime(clock_monotonic_coarse, &out->ts_);
429 }
430
431 tor_assert(r == 0);
432 }
433 #endif /* defined(CLOCK_MONOTONIC_COARSE) */
434
435 int64_t
monotime_diff_nsec(const monotime_t * start,const monotime_t * end)436 monotime_diff_nsec(const monotime_t *start,
437 const monotime_t *end)
438 {
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);
442
443 return diff_nsec;
444 }
445
446 int32_t
monotime_coarse_diff_msec32_(const monotime_coarse_t * start,const monotime_coarse_t * end)447 monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
448 const monotime_coarse_t *end)
449 {
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;
453 }
454
455 /* This value is ONE_BILLION >> 20. */
456 static const uint32_t STAMP_TICKS_PER_SECOND = 953;
457
458 uint32_t
monotime_coarse_to_stamp(const monotime_coarse_t * t)459 monotime_coarse_to_stamp(const monotime_coarse_t *t)
460 {
461 uint32_t nsec = (uint32_t)t->ts_.tv_nsec;
462 uint32_t sec = (uint32_t)t->ts_.tv_sec;
463
464 return (sec * STAMP_TICKS_PER_SECOND) + (nsec >> 20);
465 }
466
467 int
monotime_is_zero(const monotime_t * val)468 monotime_is_zero(const monotime_t *val)
469 {
470 return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0;
471 }
472
473 void
monotime_add_msec(monotime_t * out,const monotime_t * val,uint32_t msec)474 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
475 {
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;
483 }
484 }
485
486 /* end of "HAVE_CLOCK_GETTIME" */
487 #elif defined (_WIN32)
488
489 /** Result of QueryPerformanceFrequency, in terms needed to
490 * convert ticks to nanoseconds. */
491 static int64_t nsec_per_tick_numer = 1;
492 static int64_t nsec_per_tick_denom = 1;
493
494 /** Lock to protect last_pctr and pctr_offset */
495 static CRITICAL_SECTION monotime_lock;
496 /** Lock to protect rollover_count and last_tick_count */
497 static CRITICAL_SECTION monotime_coarse_lock;
498
499 typedef ULONGLONG (WINAPI *GetTickCount64_fn_t)(void);
500 static GetTickCount64_fn_t GetTickCount64_fn = NULL;
501
502 static void
monotime_init_internal(void)503 monotime_init_internal(void)
504 {
505 tor_assert(!monotime_initialized);
506 BOOL ok = InitializeCriticalSectionAndSpinCount(&monotime_lock, 200);
507 tor_assert(ok);
508 ok = InitializeCriticalSectionAndSpinCount(&monotime_coarse_lock, 200);
509 tor_assert(ok);
510 LARGE_INTEGER li;
511 ok = QueryPerformanceFrequency(&li);
512 tor_assert(ok);
513 tor_assert(li.QuadPart);
514
515 uint64_t n = ONE_BILLION;
516 uint64_t d = li.QuadPart;
517 /* We need to simplify this or we'll probably overflow the int64. */
518 simplify_fraction64(&n, &d);
519 tor_assert(n <= INT64_MAX);
520 tor_assert(d <= INT64_MAX);
521
522 nsec_per_tick_numer = (int64_t) n;
523 nsec_per_tick_denom = (int64_t) d;
524
525 last_pctr = 0;
526 pctr_offset = 0;
527
528 HANDLE h = load_windows_system_library(TEXT("kernel32.dll"));
529 if (h) {
530 GetTickCount64_fn = (GetTickCount64_fn_t) (void(*)(void))
531 GetProcAddress(h, "GetTickCount64");
532 }
533 // We can't call FreeLibrary(h) here, because freeing the handle may
534 // unload the library, and cause future calls to GetTickCount64_fn()
535 // to fail. See 29642 for details.
536 }
537
538 void
monotime_get(monotime_t * out)539 monotime_get(monotime_t *out)
540 {
541 if (BUG(monotime_initialized == 0)) {
542 monotime_init();
543 }
544
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;
549 return;
550 }
551 #endif /* defined(TOR_UNIT_TESTS) */
552
553 /* Alas, QueryPerformanceCounter is not always monotonic: see bug list at
554
555 https://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter
556 */
557
558 EnterCriticalSection(&monotime_lock);
559 LARGE_INTEGER res;
560 BOOL ok = QueryPerformanceCounter(&res);
561 tor_assert(ok);
562 const int64_t count_raw = res.QuadPart;
563 out->pcount_ = ratchet_performance_counter(count_raw);
564 LeaveCriticalSection(&monotime_lock);
565 }
566
567 void
monotime_coarse_get(monotime_coarse_t * out)568 monotime_coarse_get(monotime_coarse_t *out)
569 {
570 #ifdef TOR_UNIT_TESTS
571 if (monotime_mocking_enabled) {
572 out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
573 return;
574 }
575 #endif /* defined(TOR_UNIT_TESTS) */
576
577 if (GetTickCount64_fn) {
578 out->tick_count_ = (int64_t)GetTickCount64_fn();
579 } else {
580 EnterCriticalSection(&monotime_coarse_lock);
581 DWORD tick = GetTickCount();
582 out->tick_count_ = ratchet_coarse_performance_counter(tick);
583 LeaveCriticalSection(&monotime_coarse_lock);
584 }
585 }
586
587 int64_t
monotime_diff_nsec(const monotime_t * start,const monotime_t * end)588 monotime_diff_nsec(const monotime_t *start,
589 const monotime_t *end)
590 {
591 if (BUG(monotime_initialized == 0)) {
592 monotime_init();
593 }
594 const int64_t diff_ticks = end->pcount_ - start->pcount_;
595 return (diff_ticks * nsec_per_tick_numer) / nsec_per_tick_denom;
596 }
597
598 int64_t
monotime_coarse_diff_msec(const monotime_coarse_t * start,const monotime_coarse_t * end)599 monotime_coarse_diff_msec(const monotime_coarse_t *start,
600 const monotime_coarse_t *end)
601 {
602 const int64_t diff_ticks = end->tick_count_ - start->tick_count_;
603 return diff_ticks;
604 }
605
606 int32_t
monotime_coarse_diff_msec32_(const monotime_coarse_t * start,const monotime_coarse_t * end)607 monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
608 const monotime_coarse_t *end)
609 {
610 return (int32_t)monotime_coarse_diff_msec(start, end);
611 }
612
613 int64_t
monotime_coarse_diff_usec(const monotime_coarse_t * start,const monotime_coarse_t * end)614 monotime_coarse_diff_usec(const monotime_coarse_t *start,
615 const monotime_coarse_t *end)
616 {
617 return monotime_coarse_diff_msec(start, end) * 1000;
618 }
619
620 int64_t
monotime_coarse_diff_nsec(const monotime_coarse_t * start,const monotime_coarse_t * end)621 monotime_coarse_diff_nsec(const monotime_coarse_t *start,
622 const monotime_coarse_t *end)
623 {
624 return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
625 }
626
627 static const uint32_t STAMP_TICKS_PER_SECOND = 1000;
628
629 uint32_t
monotime_coarse_to_stamp(const monotime_coarse_t * t)630 monotime_coarse_to_stamp(const monotime_coarse_t *t)
631 {
632 return (uint32_t) t->tick_count_;
633 }
634
635 int
monotime_is_zero(const monotime_t * val)636 monotime_is_zero(const monotime_t *val)
637 {
638 return val->pcount_ == 0;
639 }
640
641 int
monotime_coarse_is_zero(const monotime_coarse_t * val)642 monotime_coarse_is_zero(const monotime_coarse_t *val)
643 {
644 return val->tick_count_ == 0;
645 }
646
647 void
monotime_add_msec(monotime_t * out,const monotime_t * val,uint32_t msec)648 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
649 {
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;
653 }
654
655 void
monotime_coarse_add_msec(monotime_coarse_t * out,const monotime_coarse_t * val,uint32_t msec)656 monotime_coarse_add_msec(monotime_coarse_t *out, const monotime_coarse_t *val,
657 uint32_t msec)
658 {
659 out->tick_count_ = val->tick_count_ + msec;
660 }
661
662 /* end of "_WIN32" */
663 #elif defined(MONOTIME_USING_GETTIMEOFDAY)
664
665 static tor_mutex_t monotime_lock;
666
667 /** Initialize the monotonic timer subsystem. */
668 static void
monotime_init_internal(void)669 monotime_init_internal(void)
670 {
671 tor_assert(!monotime_initialized);
672 tor_mutex_init(&monotime_lock);
673 }
674
675 void
monotime_get(monotime_t * out)676 monotime_get(monotime_t *out)
677 {
678 if (BUG(monotime_initialized == 0)) {
679 monotime_init();
680 }
681
682 tor_mutex_acquire(&monotime_lock);
683 struct timeval timeval_raw;
684 tor_gettimeofday(&timeval_raw);
685 ratchet_timeval(&timeval_raw, &out->tv_);
686 tor_mutex_release(&monotime_lock);
687 }
688
689 int64_t
monotime_diff_nsec(const monotime_t * start,const monotime_t * end)690 monotime_diff_nsec(const monotime_t *start,
691 const monotime_t *end)
692 {
693 struct timeval diff;
694 timersub(&end->tv_, &start->tv_, &diff);
695 return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
696 }
697
698 int32_t
monotime_coarse_diff_msec32_(const monotime_coarse_t * start,const monotime_coarse_t * end)699 monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
700 const monotime_coarse_t *end)
701 {
702 struct timeval diff;
703 timersub(&end->tv_, &start->tv_, &diff);
704 return diff.tv_sec * 1000 + diff.tv_usec / 1000;
705 }
706
707 /* This value is ONE_MILLION >> 10. */
708 static const uint32_t STAMP_TICKS_PER_SECOND = 976;
709
710 uint32_t
monotime_coarse_to_stamp(const monotime_coarse_t * t)711 monotime_coarse_to_stamp(const monotime_coarse_t *t)
712 {
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);
716 }
717
718 int
monotime_is_zero(const monotime_t * val)719 monotime_is_zero(const monotime_t *val)
720 {
721 return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0;
722 }
723
724 void
monotime_add_msec(monotime_t * out,const monotime_t * val,uint32_t msec)725 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
726 {
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;
734 }
735 }
736
737 /* end of "MONOTIME_USING_GETTIMEOFDAY" */
738 #else
739 #error "No way to implement monotonic timers."
740 #endif /* defined(__APPLE__) || ... */
741
742 /**
743 * Initialize the monotonic timer subsystem. Must be called before any
744 * monotonic timer functions. This function is idempotent.
745 */
746 void
monotime_init(void)747 monotime_init(void)
748 {
749 if (!monotime_initialized) {
750 monotime_init_internal();
751 monotime_initialized = 1;
752 monotime_get(&initialized_at);
753 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
754 monotime_coarse_get(&initialized_at_coarse);
755 #endif
756 }
757 }
758
759 void
monotime_zero(monotime_t * out)760 monotime_zero(monotime_t *out)
761 {
762 memset(out, 0, sizeof(*out));
763 }
764 #ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
765 void
monotime_coarse_zero(monotime_coarse_t * out)766 monotime_coarse_zero(monotime_coarse_t *out)
767 {
768 memset(out, 0, sizeof(*out));
769 }
770 #endif /* defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT) */
771
772 int64_t
monotime_diff_usec(const monotime_t * start,const monotime_t * end)773 monotime_diff_usec(const monotime_t *start,
774 const monotime_t *end)
775 {
776 const int64_t nsec = monotime_diff_nsec(start, end);
777 return CEIL_DIV(nsec, 1000);
778 }
779
780 int64_t
monotime_diff_msec(const monotime_t * start,const monotime_t * end)781 monotime_diff_msec(const monotime_t *start,
782 const monotime_t *end)
783 {
784 const int64_t nsec = monotime_diff_nsec(start, end);
785 return CEIL_DIV(nsec, ONE_MILLION);
786 }
787
788 uint64_t
monotime_absolute_nsec(void)789 monotime_absolute_nsec(void)
790 {
791 monotime_t now;
792 if (BUG(monotime_initialized == 0)) {
793 monotime_init();
794 }
795
796 monotime_get(&now);
797 return monotime_diff_nsec(&initialized_at, &now);
798 }
799
800 MOCK_IMPL(uint64_t,
801 monotime_absolute_usec,(void))
802 {
803 return monotime_absolute_nsec() / 1000;
804 }
805
806 uint64_t
monotime_absolute_msec(void)807 monotime_absolute_msec(void)
808 {
809 return monotime_absolute_nsec() / ONE_MILLION;
810 }
811
812 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
813 uint64_t
monotime_coarse_absolute_nsec(void)814 monotime_coarse_absolute_nsec(void)
815 {
816 if (BUG(monotime_initialized == 0)) {
817 monotime_init();
818 }
819
820 monotime_coarse_t now;
821 monotime_coarse_get(&now);
822 return monotime_coarse_diff_nsec(&initialized_at_coarse, &now);
823 }
824
825 uint64_t
monotime_coarse_absolute_usec(void)826 monotime_coarse_absolute_usec(void)
827 {
828 return monotime_coarse_absolute_nsec() / 1000;
829 }
830
831 uint64_t
monotime_coarse_absolute_msec(void)832 monotime_coarse_absolute_msec(void)
833 {
834 return monotime_coarse_absolute_nsec() / ONE_MILLION;
835 }
836 #else /* !defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
837 #define initialized_at_coarse initialized_at
838 #endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
839
840 /**
841 * Return the current time "stamp" as described by monotime_coarse_to_stamp.
842 */
843 uint32_t
monotime_coarse_get_stamp(void)844 monotime_coarse_get_stamp(void)
845 {
846 monotime_coarse_t now;
847 monotime_coarse_get(&now);
848 return monotime_coarse_to_stamp(&now);
849 }
850
851 #ifdef __APPLE__
852 uint64_t
monotime_coarse_stamp_units_to_approx_msec(uint64_t units)853 monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
854 {
855 /* Recover as much precision as we can. */
856 uint64_t abstime_diff = (units << monotime_shift);
857 return (abstime_diff * mach_time_info.numer) /
858 (mach_time_info.denom * ONE_MILLION);
859 }
860 uint64_t
monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)861 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
862 {
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;
867 }
868 #else /* !defined(__APPLE__) */
869 uint64_t
monotime_coarse_stamp_units_to_approx_msec(uint64_t units)870 monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
871 {
872 return (units * 1000) / STAMP_TICKS_PER_SECOND;
873 }
874 uint64_t
monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)875 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
876 {
877 return (msec * STAMP_TICKS_PER_SECOND) / 1000;
878 }
879 #endif /* defined(__APPLE__) */
880