tor  0.4.2.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-2019, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
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 
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 
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 
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 
155 static int64_t last_pctr = 0;
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 
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 
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 
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 
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  // 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 
281 void
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 
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 
378 static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
379 #endif /* defined(CLOCK_MONOTONIC_COARSE) */
380 
381 static 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
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
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
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
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
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
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
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 
491 static int64_t nsec_per_tick_numer = 1;
492 static int64_t nsec_per_tick_denom = 1;
493 
495 static CRITICAL_SECTION monotime_lock;
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 {
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)
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
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 
668 static void
669 monotime_init_internal(void)
670 {
672  tor_mutex_init(&monotime_lock);
673 }
674 
675 void
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 
746 void
748 {
749  if (!monotime_initialized) {
750  monotime_init_internal();
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
761 {
762  memset(out, 0, sizeof(*out));
763 }
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
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
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
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
808 {
809  return monotime_absolute_nsec() / ONE_MILLION;
810 }
811 
812 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
813 uint64_t
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
826 monotime_coarse_absolute_usec(void)
827 {
828  return monotime_coarse_absolute_nsec() / 1000;
829 }
830 
831 uint64_t
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 
843 uint32_t
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
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
871 {
872  return (units * 1000) / STAMP_TICKS_PER_SECOND;
873 }
874 uint64_t
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__) */
void monotime_init(void)
Definition: compat_time.c:747
#define timeradd(tv1, tv2, tvout)
Definition: timeval.h:47
void tor_mutex_release(tor_mutex_t *m)
void monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
uint64_t monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
Definition: compat_time.c:870
#define LD_GENERAL
Definition: log.h:59
Functions and types for monotonic times.
int64_t monotime_diff_usec(const monotime_t *start, const monotime_t *end)
Definition: compat_time.c:773
#define timercmp(tv1, tv2, op)
Definition: timeval.h:80
void monotime_get(monotime_t *out)
uint64_t monotime_absolute_msec(void)
Definition: compat_time.c:807
Declarations for timeval-related macros that some platforms are missing.
tor_assert(buffer)
uint32_t monotime_coarse_to_stamp(const monotime_coarse_t *t)
void tor_mutex_init(tor_mutex_t *m)
uint64_t monotime_absolute_nsec(void)
Definition: compat_time.c:789
int32_t monotime_coarse_diff_msec32_(const monotime_coarse_t *start, const monotime_coarse_t *end)
int tor_log2(uint64_t u64)
Definition: bits.c:16
int monotime_is_zero(const monotime_t *out)
Header for muldiv.c.
static int monotime_initialized
Definition: compat_time.c:80
int64_t monotime_diff_nsec(const monotime_t *start, const monotime_t *end)
int64_t monotime_diff_msec(const monotime_t *start, const monotime_t *end)
Definition: compat_time.c:781
void monotime_zero(monotime_t *out)
Definition: compat_time.c:760
Header for bits.c.
void tor_mutex_acquire(tor_mutex_t *m)
Headers for torerr.c.
#define timersub(tv1, tv2, tvout)
Definition: timeval.h:61
Headers for log.c.
Header for winlib.c.
Macros to manage assertions, fatal and non-fatal.
#define LD_BUG
Definition: log.h:83
uint32_t monotime_coarse_get_stamp(void)
Definition: compat_time.c:844