Line data Source code
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
59 23 : tor_sleep_msec(int msec)
60 : {
61 : #ifdef _WIN32
62 : Sleep(msec);
63 : #elif defined(HAVE_USLEEP)
64 23 : sleep(msec / 1000);
65 : /* Some usleep()s hate sleeping more than 1 sec */
66 23 : 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 23 : }
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
101 27 : monotime_enable_test_mocking(void)
102 : {
103 27 : if (BUG(monotime_initialized == 0)) {
104 0 : monotime_init();
105 : }
106 :
107 27 : tor_assert_nonfatal(monotime_mocking_enabled == 0);
108 27 : monotime_mocking_enabled = 1;
109 27 : memcpy(&initialized_at_saved,
110 : &initialized_at, sizeof(monotime_t));
111 27 : memset(&initialized_at, 0, sizeof(monotime_t));
112 : #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
113 27 : memcpy(&initialized_at_coarse_saved,
114 : &initialized_at_coarse, sizeof(monotime_coarse_t));
115 27 : memset(&initialized_at_coarse, 0, sizeof(monotime_coarse_t));
116 : #endif
117 27 : }
118 :
119 : void
120 23 : monotime_disable_test_mocking(void)
121 : {
122 23 : tor_assert_nonfatal(monotime_mocking_enabled == 1);
123 23 : monotime_mocking_enabled = 0;
124 :
125 23 : memcpy(&initialized_at,
126 : &initialized_at_saved, sizeof(monotime_t));
127 : #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
128 23 : memcpy(&initialized_at_coarse,
129 : &initialized_at_coarse_saved, sizeof(monotime_coarse_t));
130 : #endif
131 23 : }
132 :
133 : void
134 223 : monotime_set_mock_time_nsec(int64_t nsec)
135 : {
136 223 : tor_assert_nonfatal(monotime_mocking_enabled == 1);
137 223 : mock_time_nsec = nsec;
138 223 : }
139 :
140 : #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
141 : void
142 266 : monotime_coarse_set_mock_time_nsec(int64_t nsec)
143 : {
144 266 : tor_assert_nonfatal(monotime_mocking_enabled == 1);
145 266 : mock_time_nsec_coarse = nsec;
146 266 : }
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
171 8 : ratchet_performance_counter(int64_t count_raw)
172 : {
173 : /* must hold lock */
174 8 : const int64_t count_adjusted = count_raw + pctr_offset;
175 :
176 8 : if (PREDICT_UNLIKELY(count_adjusted < last_pctr)) {
177 : /* Monotonicity failed! Pretend no time elapsed. */
178 2 : pctr_offset = last_pctr - count_raw;
179 2 : return last_pctr;
180 : } else {
181 6 : last_pctr = count_adjusted;
182 6 : return count_adjusted;
183 : }
184 : }
185 :
186 : STATIC int64_t
187 5 : ratchet_coarse_performance_counter(const int64_t count_raw)
188 : {
189 5 : int64_t count = count_raw + (((int64_t)rollover_count) << 32);
190 7 : while (PREDICT_UNLIKELY(count < last_tick_count)) {
191 2 : ++rollover_count;
192 2 : count = count_raw + (((int64_t)rollover_count) << 32);
193 : }
194 5 : last_tick_count = count;
195 5 : 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
211 7 : ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out)
212 : {
213 : /* must hold lock */
214 7 : timeradd(timeval_raw, &timeofday_offset, out);
215 7 : if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, OP_LT))) {
216 : /* time ran backwards. Instead, declare that no time occurred. */
217 2 : timersub(&last_timeofday, timeval_raw, &timeofday_offset);
218 2 : memcpy(out, &last_timeofday, sizeof(struct timeval));
219 : } else {
220 5 : memcpy(&last_timeofday, out, sizeof(struct timeval));
221 : }
222 7 : }
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
228 1 : monotime_reset_ratchets_for_testing(void)
229 : {
230 1 : last_pctr = pctr_offset = last_tick_count = 0;
231 1 : rollover_count = 0;
232 1 : memset(&last_timeofday, 0, sizeof(struct timeval));
233 1 : memset(&timeofday_offset, 0, sizeof(struct timeval));
234 1 : }
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
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
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
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
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
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
349 : monotime_coarse_to_stamp(const monotime_coarse_t *t)
350 : {
351 : return (uint32_t)(t->abstime_ >> monotime_shift);
352 : }
353 :
354 : int
355 : monotime_is_zero(const monotime_t *val)
356 : {
357 : return val->abstime_ == 0;
358 : }
359 :
360 : void
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
382 5554 : monotime_init_internal(void)
383 : {
384 : #ifdef CLOCK_MONOTONIC_COARSE
385 5554 : struct timespec ts;
386 5554 : if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) < 0) {
387 0 : log_info(LD_GENERAL, "CLOCK_MONOTONIC_COARSE isn't working (%s); "
388 : "falling back to CLOCK_MONOTONIC.", strerror(errno));
389 0 : clock_monotonic_coarse = CLOCK_MONOTONIC;
390 : }
391 : #endif /* defined(CLOCK_MONOTONIC_COARSE) */
392 5554 : }
393 :
394 : void
395 10650 : monotime_get(monotime_t *out)
396 : {
397 : #ifdef TOR_UNIT_TESTS
398 10650 : if (monotime_mocking_enabled) {
399 512 : out->ts_.tv_sec = (time_t) (mock_time_nsec / ONE_BILLION);
400 512 : out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION);
401 512 : return;
402 : }
403 : #endif /* defined(TOR_UNIT_TESTS) */
404 10138 : int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
405 10138 : tor_assert(r == 0);
406 : }
407 :
408 : #ifdef CLOCK_MONOTONIC_COARSE
409 : void
410 10532 : monotime_coarse_get(monotime_coarse_t *out)
411 : {
412 : #ifdef TOR_UNIT_TESTS
413 10532 : if (monotime_mocking_enabled) {
414 1170 : out->ts_.tv_sec = (time_t) (mock_time_nsec_coarse / ONE_BILLION);
415 1170 : out->ts_.tv_nsec = (int) (mock_time_nsec_coarse % ONE_BILLION);
416 1170 : return;
417 : }
418 : #endif /* defined(TOR_UNIT_TESTS) */
419 9362 : int r = clock_gettime(clock_monotonic_coarse, &out->ts_);
420 9362 : if (PREDICT_UNLIKELY(r < 0) &&
421 0 : errno == EINVAL &&
422 0 : clock_monotonic_coarse == CLOCK_MONOTONIC_COARSE) {
423 : /* We should have caught this at startup in monotime_init_internal!
424 : */
425 0 : log_warn(LD_BUG, "Falling back to non-coarse monotonic time %s initial "
426 : "system start?", monotime_initialized?"after":"without");
427 0 : clock_monotonic_coarse = CLOCK_MONOTONIC;
428 0 : r = clock_gettime(clock_monotonic_coarse, &out->ts_);
429 : }
430 :
431 9362 : tor_assert(r == 0);
432 : }
433 : #endif /* defined(CLOCK_MONOTONIC_COARSE) */
434 :
435 : int64_t
436 6931 : monotime_diff_nsec(const monotime_t *start,
437 : const monotime_t *end)
438 : {
439 6931 : const int64_t diff_sec = end->ts_.tv_sec - start->ts_.tv_sec;
440 6931 : const int64_t diff_nsec = diff_sec * ONE_BILLION +
441 6931 : (end->ts_.tv_nsec - start->ts_.tv_nsec);
442 :
443 6931 : return diff_nsec;
444 : }
445 :
446 : int32_t
447 4 : monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
448 : const monotime_coarse_t *end)
449 : {
450 4 : const int32_t diff_sec = (int32_t)(end->ts_.tv_sec - start->ts_.tv_sec);
451 4 : const int32_t diff_nsec = (int32_t)(end->ts_.tv_nsec - start->ts_.tv_nsec);
452 4 : 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
459 4149 : monotime_coarse_to_stamp(const monotime_coarse_t *t)
460 : {
461 4149 : uint32_t nsec = (uint32_t)t->ts_.tv_nsec;
462 4149 : uint32_t sec = (uint32_t)t->ts_.tv_sec;
463 :
464 4149 : return (sec * STAMP_TICKS_PER_SECOND) + (nsec >> 20);
465 : }
466 :
467 : int
468 445 : monotime_is_zero(const monotime_t *val)
469 : {
470 445 : return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0;
471 : }
472 :
473 : void
474 227 : monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
475 : {
476 227 : const uint32_t sec = msec / 1000;
477 227 : const uint32_t msec_remainder = msec % 1000;
478 227 : out->ts_.tv_sec = val->ts_.tv_sec + sec;
479 227 : out->ts_.tv_nsec = val->ts_.tv_nsec + (msec_remainder * ONE_MILLION);
480 227 : if (out->ts_.tv_nsec > ONE_BILLION) {
481 2 : out->ts_.tv_nsec -= ONE_BILLION;
482 2 : out->ts_.tv_sec += 1;
483 : }
484 227 : }
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
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
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
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
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
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
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
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
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
630 : monotime_coarse_to_stamp(const monotime_coarse_t *t)
631 : {
632 : return (uint32_t) t->tick_count_;
633 : }
634 :
635 : int
636 : monotime_is_zero(const monotime_t *val)
637 : {
638 : return val->pcount_ == 0;
639 : }
640 :
641 : int
642 : monotime_coarse_is_zero(const monotime_coarse_t *val)
643 : {
644 : return val->tick_count_ == 0;
645 : }
646 :
647 : void
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
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
669 : monotime_init_internal(void)
670 : {
671 : tor_assert(!monotime_initialized);
672 : tor_mutex_init(&monotime_lock);
673 : }
674 :
675 : void
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
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
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
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
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
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
747 5585 : monotime_init(void)
748 : {
749 5585 : if (!monotime_initialized) {
750 5554 : monotime_init_internal();
751 5554 : monotime_initialized = 1;
752 5554 : monotime_get(&initialized_at);
753 : #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
754 5554 : monotime_coarse_get(&initialized_at_coarse);
755 : #endif
756 : }
757 5585 : }
758 :
759 : void
760 328 : monotime_zero(monotime_t *out)
761 : {
762 328 : memset(out, 0, sizeof(*out));
763 328 : }
764 : #ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
765 : void
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
773 5992 : monotime_diff_usec(const monotime_t *start,
774 : const monotime_t *end)
775 : {
776 5992 : const int64_t nsec = monotime_diff_nsec(start, end);
777 5992 : return CEIL_DIV(nsec, 1000);
778 : }
779 :
780 : int64_t
781 892 : monotime_diff_msec(const monotime_t *start,
782 : const monotime_t *end)
783 : {
784 892 : const int64_t nsec = monotime_diff_nsec(start, end);
785 892 : return CEIL_DIV(nsec, ONE_MILLION);
786 : }
787 :
788 : uint64_t
789 43 : monotime_absolute_nsec(void)
790 : {
791 43 : monotime_t now;
792 43 : if (BUG(monotime_initialized == 0)) {
793 0 : monotime_init();
794 : }
795 :
796 43 : monotime_get(&now);
797 43 : return monotime_diff_nsec(&initialized_at, &now);
798 : }
799 :
800 32 : MOCK_IMPL(uint64_t,
801 : monotime_absolute_usec,(void))
802 : {
803 32 : return monotime_absolute_nsec() / 1000;
804 : }
805 :
806 : uint64_t
807 1 : monotime_absolute_msec(void)
808 : {
809 1 : return monotime_absolute_nsec() / ONE_MILLION;
810 : }
811 :
812 : #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
813 : uint64_t
814 4 : monotime_coarse_absolute_nsec(void)
815 : {
816 4 : if (BUG(monotime_initialized == 0)) {
817 0 : monotime_init();
818 : }
819 :
820 4 : monotime_coarse_t now;
821 4 : monotime_coarse_get(&now);
822 4 : return monotime_coarse_diff_nsec(&initialized_at_coarse, &now);
823 : }
824 :
825 : uint64_t
826 1 : monotime_coarse_absolute_usec(void)
827 : {
828 1 : return monotime_coarse_absolute_nsec() / 1000;
829 : }
830 :
831 : uint64_t
832 1 : monotime_coarse_absolute_msec(void)
833 : {
834 1 : 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
844 4147 : monotime_coarse_get_stamp(void)
845 : {
846 4147 : monotime_coarse_t now;
847 4147 : monotime_coarse_get(&now);
848 4147 : return monotime_coarse_to_stamp(&now);
849 : }
850 :
851 : #ifdef __APPLE__
852 : uint64_t
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
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
870 31 : monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
871 : {
872 31 : return (units * 1000) / STAMP_TICKS_PER_SECOND;
873 : }
874 : uint64_t
875 3 : monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
876 : {
877 3 : return (msec * STAMP_TICKS_PER_SECOND) / 1000;
878 : }
879 : #endif /* defined(__APPLE__) */
|