Tor  0.4.8.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
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 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
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
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
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
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
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
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
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
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
248 monotime_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  */
284 void
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)
298 void
299 monotime_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  */
317 int64_t
318 monotime_diff_nsec(const monotime_t *start,
319  const monotime_t *end)
320 {
321  if (BUG(mach_time_info.denom == 0)) {
322  monotime_init();
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 
330 int32_t
331 monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
332  const monotime_coarse_t *end)
333 {
334  if (BUG(mach_time_info.denom == 0)) {
335  monotime_init();
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 
351 uint32_t
352 monotime_coarse_to_stamp(const monotime_coarse_t *t)
353 {
354  return (uint32_t)(t->abstime_ >> monotime_shift);
355 }
356 
357 int
358 monotime_is_zero(const monotime_t *val)
359 {
360  return val->abstime_ == 0;
361 }
362 
363 void
364 monotime_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  */
381 static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
382 #endif /* defined(CLOCK_MONOTONIC_COARSE) */
383 
384 static void
385 monotime_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 
397 void
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
412 void
413 monotime_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 
438 int64_t
439 monotime_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 
449 int32_t
450 monotime_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. */
459 static const uint32_t STAMP_TICKS_PER_SECOND = 953;
460 
461 uint32_t
462 monotime_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 
470 int
471 monotime_is_zero(const monotime_t *val)
472 {
473  return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0;
474 }
475 
476 void
477 monotime_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. */
494 static int64_t nsec_per_tick_numer = 1;
495 static int64_t nsec_per_tick_denom = 1;
496 
497 /** Lock to protect last_pctr and pctr_offset */
498 static CRITICAL_SECTION monotime_lock;
499 /** Lock to protect rollover_count and last_tick_count */
500 static CRITICAL_SECTION monotime_coarse_lock;
501 
502 typedef ULONGLONG (WINAPI *GetTickCount64_fn_t)(void);
503 static GetTickCount64_fn_t GetTickCount64_fn = NULL;
504 
505 static void
506 monotime_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 
541 void
543 {
544  if (BUG(monotime_initialized == 0)) {
545  monotime_init();
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 
570 void
571 monotime_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 
590 int64_t
591 monotime_diff_nsec(const monotime_t *start,
592  const monotime_t *end)
593 {
594  if (BUG(monotime_initialized == 0)) {
595  monotime_init();
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 
601 int64_t
602 monotime_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 
609 int32_t
610 monotime_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 
616 int64_t
617 monotime_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 
623 int64_t
624 monotime_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 
630 static const uint32_t STAMP_TICKS_PER_SECOND = 1000;
631 
632 uint32_t
633 monotime_coarse_to_stamp(const monotime_coarse_t *t)
634 {
635  return (uint32_t) t->tick_count_;
636 }
637 
638 int
639 monotime_is_zero(const monotime_t *val)
640 {
641  return val->pcount_ == 0;
642 }
643 
644 int
645 monotime_coarse_is_zero(const monotime_coarse_t *val)
646 {
647  return val->tick_count_ == 0;
648 }
649 
650 void
651 monotime_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 
658 void
659 monotime_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 
668 static tor_mutex_t monotime_lock;
669 
670 /** Initialize the monotonic timer subsystem. */
671 static void
672 monotime_init_internal(void)
673 {
675  tor_mutex_init(&monotime_lock);
676 }
677 
678 void
680 {
681  if (BUG(monotime_initialized == 0)) {
682  monotime_init();
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 
692 int64_t
693 monotime_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 
701 int32_t
702 monotime_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. */
711 static const uint32_t STAMP_TICKS_PER_SECOND = 976;
712 
713 uint32_t
714 monotime_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 
721 int
722 monotime_is_zero(const monotime_t *val)
723 {
724  return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0;
725 }
726 
727 void
728 monotime_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  */
749 void
751 {
752  if (!monotime_initialized) {
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 
762 void
764 {
765  memset(out, 0, sizeof(*out));
766 }
767 #ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
768 void
769 monotime_coarse_zero(monotime_coarse_t *out)
770 {
771  memset(out, 0, sizeof(*out));
772 }
773 #endif /* defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT) */
774 
775 int64_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 
783 int64_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 
791 uint64_t
793 {
794  monotime_t now;
795  if (BUG(monotime_initialized == 0)) {
796  monotime_init();
797  }
798 
799  monotime_get(&now);
800  return monotime_diff_nsec(&initialized_at, &now);
801 }
802 
803 MOCK_IMPL(uint64_t,
805 {
806  return monotime_absolute_nsec() / 1000;
807 }
808 
809 uint64_t
811 {
812  return monotime_absolute_nsec() / ONE_MILLION;
813 }
814 
815 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
816 uint64_t
817 monotime_coarse_absolute_nsec(void)
818 {
819  if (BUG(monotime_initialized == 0)) {
820  monotime_init();
821  }
822 
823  monotime_coarse_t now;
824  monotime_coarse_get(&now);
825  return monotime_coarse_diff_nsec(&initialized_at_coarse, &now);
826 }
827 
828 uint64_t
829 monotime_coarse_absolute_usec(void)
830 {
831  return monotime_coarse_absolute_nsec() / 1000;
832 }
833 
834 uint64_t
835 monotime_coarse_absolute_msec(void)
836 {
837  return monotime_coarse_absolute_nsec() / ONE_MILLION;
838 }
839 #else /* !defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
840 #define initialized_at_coarse initialized_at
841 #endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
842 
843 /**
844  * Return the current time "stamp" as described by monotime_coarse_to_stamp.
845  */
846 uint32_t
848 {
849  monotime_coarse_t now;
850  monotime_coarse_get(&now);
851  return monotime_coarse_to_stamp(&now);
852 }
853 
854 #ifdef __APPLE__
855 uint64_t
857 {
858  /* Recover as much precision as we can. */
859  uint64_t abstime_diff = (units << monotime_shift);
860  return (abstime_diff * mach_time_info.numer) /
861  (mach_time_info.denom * ONE_MILLION);
862 }
863 uint64_t
864 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
865 {
866  uint64_t abstime_val =
867  (((uint64_t)msec) * ONE_MILLION * mach_time_info.denom) /
868  mach_time_info.numer;
869  return abstime_val >> monotime_shift;
870 }
871 #else /* !defined(__APPLE__) */
872 uint64_t
874 {
875  return (units * 1000) / STAMP_TICKS_PER_SECOND;
876 }
877 uint64_t
878 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
879 {
880  return (msec * STAMP_TICKS_PER_SECOND) / 1000;
881 }
882 #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:873
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:847
void monotime_init(void)
Definition: compat_time.c:750
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:102
Header for winlib.c.