tor  0.4.0.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-2018, 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 
168 STATIC int64_t
169 ratchet_performance_counter(int64_t count_raw)
170 {
171  /* must hold lock */
172  const int64_t count_adjusted = count_raw + pctr_offset;
173 
174  if (PREDICT_UNLIKELY(count_adjusted < last_pctr)) {
175  /* Monotonicity failed! Pretend no time elapsed. */
176  pctr_offset = last_pctr - count_raw;
177  return last_pctr;
178  } else {
179  last_pctr = count_adjusted;
180  return count_adjusted;
181  }
182 }
183 
184 STATIC int64_t
185 ratchet_coarse_performance_counter(const int64_t count_raw)
186 {
187  int64_t count = count_raw + (((int64_t)rollover_count) << 32);
188  while (PREDICT_UNLIKELY(count < last_tick_count)) {
189  ++rollover_count;
190  count = count_raw + (((int64_t)rollover_count) << 32);
191  }
192  last_tick_count = count;
193  return count;
194 }
195 #endif /* defined(_WIN32) || defined(TOR_UNIT_TESTS) */
196 
197 #if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS)
198 static struct timeval last_timeofday = { 0, 0 };
199 static struct timeval timeofday_offset = { 0, 0 };
200 
206 STATIC void
207 ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out)
208 {
209  /* must hold lock */
210  timeradd(timeval_raw, &timeofday_offset, out);
211  if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, OP_LT))) {
212  /* time ran backwards. Instead, declare that no time occurred. */
213  timersub(&last_timeofday, timeval_raw, &timeofday_offset);
214  memcpy(out, &last_timeofday, sizeof(struct timeval));
215  } else {
216  memcpy(&last_timeofday, out, sizeof(struct timeval));
217  }
218 }
219 #endif /* defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS) */
220 
221 #ifdef TOR_UNIT_TESTS
222 
223 void
224 monotime_reset_ratchets_for_testing(void)
225 {
226  last_pctr = pctr_offset = last_tick_count = 0;
227  rollover_count = 0;
228  memset(&last_timeofday, 0, sizeof(struct timeval));
229  memset(&timeofday_offset, 0, sizeof(struct timeval));
230 }
231 #endif /* defined(TOR_UNIT_TESTS) */
232 
233 #ifdef __APPLE__
234 
238 static struct mach_timebase_info mach_time_info;
239 static struct mach_timebase_info mach_time_info_msec_cvt;
240 static int32_t mach_time_msec_cvt_threshold;
241 static int monotime_shift = 0;
242 
243 static void
244 monotime_init_internal(void)
245 {
247  int r = mach_timebase_info(&mach_time_info);
248  tor_assert(r == 0);
249  tor_assert(mach_time_info.denom != 0);
250 
251  {
252  // approximate only.
253  uint64_t ns_per_tick = mach_time_info.numer / mach_time_info.denom;
254  uint64_t ms_per_tick = ns_per_tick * ONE_MILLION;
255  // requires that tor_log2(0) == 0.
256  monotime_shift = tor_log2(ms_per_tick);
257  }
258  {
259  // For converting ticks to milliseconds in a 32-bit-friendly way, we
260  // will first right-shift by 20, and then multiply by 2048/1953, since
261  // (1<<20) * 1953/2048 is about 1e6. We precompute a new numerator and
262  // denominator here to avoid multiple multiplies.
263  mach_time_info_msec_cvt.numer = mach_time_info.numer * 2048;
264  mach_time_info_msec_cvt.denom = mach_time_info.denom * 1953;
265  // For any value above this amount, we should divide before multiplying,
266  // to avoid overflow. For a value below this, we should multiply
267  // before dividing, to improve accuracy.
268  mach_time_msec_cvt_threshold = INT32_MAX / mach_time_info_msec_cvt.numer;
269  }
270 }
271 
275 void
277 {
278 #ifdef TOR_UNIT_TESTS
279  if (monotime_mocking_enabled) {
280  out->abstime_ = (mock_time_nsec * mach_time_info.denom)
281  / mach_time_info.numer;
282  return;
283  }
284 #endif /* defined(TOR_UNIT_TESTS) */
285  out->abstime_ = mach_absolute_time();
286 }
287 
288 #if defined(HAVE_MACH_APPROXIMATE_TIME)
289 void
290 monotime_coarse_get(monotime_coarse_t *out)
291 {
292 #ifdef TOR_UNIT_TESTS
293  if (monotime_mocking_enabled) {
294  out->abstime_ = (mock_time_nsec_coarse * mach_time_info.denom)
295  / mach_time_info.numer;
296  return;
297  }
298 #endif /* defined(TOR_UNIT_TESTS) */
299  out->abstime_ = mach_approximate_time();
300 }
301 #endif
302 
306 int64_t
307 monotime_diff_nsec(const monotime_t *start,
308  const monotime_t *end)
309 {
310  if (BUG(mach_time_info.denom == 0)) {
311  monotime_init();
312  }
313  const int64_t diff_ticks = end->abstime_ - start->abstime_;
314  const int64_t diff_nsec =
315  (diff_ticks * mach_time_info.numer) / mach_time_info.denom;
316  return diff_nsec;
317 }
318 
319 int32_t
320 monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
321  const monotime_coarse_t *end)
322 {
323  if (BUG(mach_time_info.denom == 0)) {
324  monotime_init();
325  }
326  const int64_t diff_ticks = end->abstime_ - start->abstime_;
327 
328  /* We already require in di_ops.c that right-shift performs a sign-extend. */
329  const int32_t diff_microticks = (int32_t)(diff_ticks >> 20);
330 
331  if (diff_microticks >= mach_time_msec_cvt_threshold) {
332  return (diff_microticks / mach_time_info_msec_cvt.denom) *
333  mach_time_info_msec_cvt.numer;
334  } else {
335  return (diff_microticks * mach_time_info_msec_cvt.numer) /
336  mach_time_info_msec_cvt.denom;
337  }
338 }
339 
340 uint32_t
341 monotime_coarse_to_stamp(const monotime_coarse_t *t)
342 {
343  return (uint32_t)(t->abstime_ >> monotime_shift);
344 }
345 
346 int
347 monotime_is_zero(const monotime_t *val)
348 {
349  return val->abstime_ == 0;
350 }
351 
352 void
353 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
354 {
355  const uint64_t nsec = msec * ONE_MILLION;
356  const uint64_t ticks = (nsec * mach_time_info.denom) / mach_time_info.numer;
357  out->abstime_ = val->abstime_ + ticks;
358 }
359 
360 /* end of "__APPLE__" */
361 #elif defined(HAVE_CLOCK_GETTIME)
362 
363 #ifdef CLOCK_MONOTONIC_COARSE
364 
370 static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
371 #endif /* defined(CLOCK_MONOTONIC_COARSE) */
372 
373 static void
374 monotime_init_internal(void)
375 {
376 #ifdef CLOCK_MONOTONIC_COARSE
377  struct timespec ts;
378  if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) < 0) {
379  log_info(LD_GENERAL, "CLOCK_MONOTONIC_COARSE isn't working (%s); "
380  "falling back to CLOCK_MONOTONIC.", strerror(errno));
381  clock_monotonic_coarse = CLOCK_MONOTONIC;
382  }
383 #endif /* defined(CLOCK_MONOTONIC_COARSE) */
384 }
385 
386 void
388 {
389 #ifdef TOR_UNIT_TESTS
390  if (monotime_mocking_enabled) {
391  out->ts_.tv_sec = (time_t) (mock_time_nsec / ONE_BILLION);
392  out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION);
393  return;
394  }
395 #endif /* defined(TOR_UNIT_TESTS) */
396  int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
397  tor_assert(r == 0);
398 }
399 
400 #ifdef CLOCK_MONOTONIC_COARSE
401 void
402 monotime_coarse_get(monotime_coarse_t *out)
403 {
404 #ifdef TOR_UNIT_TESTS
405  if (monotime_mocking_enabled) {
406  out->ts_.tv_sec = (time_t) (mock_time_nsec_coarse / ONE_BILLION);
407  out->ts_.tv_nsec = (int) (mock_time_nsec_coarse % ONE_BILLION);
408  return;
409  }
410 #endif /* defined(TOR_UNIT_TESTS) */
411  int r = clock_gettime(clock_monotonic_coarse, &out->ts_);
412  if (PREDICT_UNLIKELY(r < 0) &&
413  errno == EINVAL &&
414  clock_monotonic_coarse == CLOCK_MONOTONIC_COARSE) {
415  /* We should have caught this at startup in monotime_init_internal!
416  */
417  log_warn(LD_BUG, "Falling back to non-coarse monotonic time %s initial "
418  "system start?", monotime_initialized?"after":"without");
419  clock_monotonic_coarse = CLOCK_MONOTONIC;
420  r = clock_gettime(clock_monotonic_coarse, &out->ts_);
421  }
422 
423  tor_assert(r == 0);
424 }
425 #endif /* defined(CLOCK_MONOTONIC_COARSE) */
426 
427 int64_t
428 monotime_diff_nsec(const monotime_t *start,
429  const monotime_t *end)
430 {
431  const int64_t diff_sec = end->ts_.tv_sec - start->ts_.tv_sec;
432  const int64_t diff_nsec = diff_sec * ONE_BILLION +
433  (end->ts_.tv_nsec - start->ts_.tv_nsec);
434 
435  return diff_nsec;
436 }
437 
438 int32_t
439 monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
440  const monotime_coarse_t *end)
441 {
442  const int32_t diff_sec = (int32_t)(end->ts_.tv_sec - start->ts_.tv_sec);
443  const int32_t diff_nsec = (int32_t)(end->ts_.tv_nsec - start->ts_.tv_nsec);
444  return diff_sec * 1000 + diff_nsec / ONE_MILLION;
445 }
446 
447 /* This value is ONE_BILLION >> 20. */
448 static const uint32_t STAMP_TICKS_PER_SECOND = 953;
449 
450 uint32_t
451 monotime_coarse_to_stamp(const monotime_coarse_t *t)
452 {
453  uint32_t nsec = (uint32_t)t->ts_.tv_nsec;
454  uint32_t sec = (uint32_t)t->ts_.tv_sec;
455 
456  return (sec * STAMP_TICKS_PER_SECOND) + (nsec >> 20);
457 }
458 
459 int
460 monotime_is_zero(const monotime_t *val)
461 {
462  return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0;
463 }
464 
465 void
466 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
467 {
468  const uint32_t sec = msec / 1000;
469  const uint32_t msec_remainder = msec % 1000;
470  out->ts_.tv_sec = val->ts_.tv_sec + sec;
471  out->ts_.tv_nsec = val->ts_.tv_nsec + (msec_remainder * ONE_MILLION);
472  if (out->ts_.tv_nsec > ONE_BILLION) {
473  out->ts_.tv_nsec -= ONE_BILLION;
474  out->ts_.tv_sec += 1;
475  }
476 }
477 
478 /* end of "HAVE_CLOCK_GETTIME" */
479 #elif defined (_WIN32)
480 
483 static int64_t nsec_per_tick_numer = 1;
484 static int64_t nsec_per_tick_denom = 1;
485 
487 static CRITICAL_SECTION monotime_lock;
489 static CRITICAL_SECTION monotime_coarse_lock;
490 
491 typedef ULONGLONG (WINAPI *GetTickCount64_fn_t)(void);
492 static GetTickCount64_fn_t GetTickCount64_fn = NULL;
493 
494 static void
495 monotime_init_internal(void)
496 {
498  BOOL ok = InitializeCriticalSectionAndSpinCount(&monotime_lock, 200);
499  tor_assert(ok);
500  ok = InitializeCriticalSectionAndSpinCount(&monotime_coarse_lock, 200);
501  tor_assert(ok);
502  LARGE_INTEGER li;
503  ok = QueryPerformanceFrequency(&li);
504  tor_assert(ok);
505  tor_assert(li.QuadPart);
506 
507  uint64_t n = ONE_BILLION;
508  uint64_t d = li.QuadPart;
509  /* We need to simplify this or we'll probably overflow the int64. */
510  simplify_fraction64(&n, &d);
511  tor_assert(n <= INT64_MAX);
512  tor_assert(d <= INT64_MAX);
513 
514  nsec_per_tick_numer = (int64_t) n;
515  nsec_per_tick_denom = (int64_t) d;
516 
517  last_pctr = 0;
518  pctr_offset = 0;
519 
520  HANDLE h = load_windows_system_library(TEXT("kernel32.dll"));
521  if (h) {
522  GetTickCount64_fn = (GetTickCount64_fn_t)
523  GetProcAddress(h, "GetTickCount64");
524  }
525  // FreeLibrary(h) ?
526 }
527 
528 void
530 {
531  if (BUG(monotime_initialized == 0)) {
532  monotime_init();
533  }
534 
535 #ifdef TOR_UNIT_TESTS
536  if (monotime_mocking_enabled) {
537  out->pcount_ = (mock_time_nsec * nsec_per_tick_denom)
538  / nsec_per_tick_numer;
539  return;
540  }
541 #endif /* defined(TOR_UNIT_TESTS) */
542 
543  /* Alas, QueryPerformanceCounter is not always monotonic: see bug list at
544 
545  https://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter
546  */
547 
548  EnterCriticalSection(&monotime_lock);
549  LARGE_INTEGER res;
550  BOOL ok = QueryPerformanceCounter(&res);
551  tor_assert(ok);
552  const int64_t count_raw = res.QuadPart;
553  out->pcount_ = ratchet_performance_counter(count_raw);
554  LeaveCriticalSection(&monotime_lock);
555 }
556 
557 void
558 monotime_coarse_get(monotime_coarse_t *out)
559 {
560 #ifdef TOR_UNIT_TESTS
561  if (monotime_mocking_enabled) {
562  out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
563  return;
564  }
565 #endif /* defined(TOR_UNIT_TESTS) */
566 
567  if (GetTickCount64_fn) {
568  out->tick_count_ = (int64_t)GetTickCount64_fn();
569  } else {
570  EnterCriticalSection(&monotime_coarse_lock);
571  DWORD tick = GetTickCount();
572  out->tick_count_ = ratchet_coarse_performance_counter(tick);
573  LeaveCriticalSection(&monotime_coarse_lock);
574  }
575 }
576 
577 int64_t
578 monotime_diff_nsec(const monotime_t *start,
579  const monotime_t *end)
580 {
581  if (BUG(monotime_initialized == 0)) {
582  monotime_init();
583  }
584  const int64_t diff_ticks = end->pcount_ - start->pcount_;
585  return (diff_ticks * nsec_per_tick_numer) / nsec_per_tick_denom;
586 }
587 
588 int64_t
589 monotime_coarse_diff_msec(const monotime_coarse_t *start,
590  const monotime_coarse_t *end)
591 {
592  const int64_t diff_ticks = end->tick_count_ - start->tick_count_;
593  return diff_ticks;
594 }
595 
596 int32_t
597 monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
598  const monotime_coarse_t *end)
599 {
600  return (int32_t)monotime_coarse_diff_msec(start, end);
601 }
602 
603 int64_t
604 monotime_coarse_diff_usec(const monotime_coarse_t *start,
605  const monotime_coarse_t *end)
606 {
607  return monotime_coarse_diff_msec(start, end) * 1000;
608 }
609 
610 int64_t
611 monotime_coarse_diff_nsec(const monotime_coarse_t *start,
612  const monotime_coarse_t *end)
613 {
614  return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
615 }
616 
617 static const uint32_t STAMP_TICKS_PER_SECOND = 1000;
618 
619 uint32_t
620 monotime_coarse_to_stamp(const monotime_coarse_t *t)
621 {
622  return (uint32_t) t->tick_count_;
623 }
624 
625 int
626 monotime_is_zero(const monotime_t *val)
627 {
628  return val->pcount_ == 0;
629 }
630 
631 int
632 monotime_coarse_is_zero(const monotime_coarse_t *val)
633 {
634  return val->tick_count_ == 0;
635 }
636 
637 void
638 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
639 {
640  const uint64_t nsec = msec * ONE_MILLION;
641  const uint64_t ticks = (nsec * nsec_per_tick_denom) / nsec_per_tick_numer;
642  out->pcount_ = val->pcount_ + ticks;
643 }
644 
645 void
646 monotime_coarse_add_msec(monotime_coarse_t *out, const monotime_coarse_t *val,
647  uint32_t msec)
648 {
649  out->tick_count_ = val->tick_count_ + msec;
650 }
651 
652 /* end of "_WIN32" */
653 #elif defined(MONOTIME_USING_GETTIMEOFDAY)
654 
655 static tor_mutex_t monotime_lock;
656 
658 static void
659 monotime_init_internal(void)
660 {
662  tor_mutex_init(&monotime_lock);
663 }
664 
665 void
667 {
668  if (BUG(monotime_initialized == 0)) {
669  monotime_init();
670  }
671 
672  tor_mutex_acquire(&monotime_lock);
673  struct timeval timeval_raw;
674  tor_gettimeofday(&timeval_raw);
675  ratchet_timeval(&timeval_raw, &out->tv_);
676  tor_mutex_release(&monotime_lock);
677 }
678 
679 int64_t
680 monotime_diff_nsec(const monotime_t *start,
681  const monotime_t *end)
682 {
683  struct timeval diff;
684  timersub(&end->tv_, &start->tv_, &diff);
685  return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
686 }
687 
688 int32_t
689 monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
690  const monotime_coarse_t *end)
691 {
692  struct timeval diff;
693  timersub(&end->tv_, &start->tv_, &diff);
694  return diff.tv_sec * 1000 + diff.tv_usec / 1000;
695 }
696 
697 /* This value is ONE_MILLION >> 10. */
698 static const uint32_t STAMP_TICKS_PER_SECOND = 976;
699 
700 uint32_t
701 monotime_coarse_to_stamp(const monotime_coarse_t *t)
702 {
703  const uint32_t usec = (uint32_t)t->tv_.tv_usec;
704  const uint32_t sec = (uint32_t)t->tv_.tv_sec;
705  return (sec * STAMP_TICKS_PER_SECOND) | (nsec >> 10);
706 }
707 
708 int
709 monotime_is_zero(const monotime_t *val)
710 {
711  return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0;
712 }
713 
714 void
715 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
716 {
717  const uint32_t sec = msec / 1000;
718  const uint32_t msec_remainder = msec % 1000;
719  out->tv_.tv_sec = val->tv_.tv_sec + sec;
720  out->tv_.tv_usec = val->tv_.tv_nsec + (msec_remainder * 1000);
721  if (out->tv_.tv_usec > ONE_MILLION) {
722  out->tv_.tv_usec -= ONE_MILLION;
723  out->tv_.tv_sec += 1;
724  }
725 }
726 
727 /* end of "MONOTIME_USING_GETTIMEOFDAY" */
728 #else
729 #error "No way to implement monotonic timers."
730 #endif /* defined(__APPLE__) || ... */
731 
736 void
738 {
739  if (!monotime_initialized) {
740  monotime_init_internal();
742  monotime_get(&initialized_at);
743 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
744  monotime_coarse_get(&initialized_at_coarse);
745 #endif
746  }
747 }
748 
749 void
751 {
752  memset(out, 0, sizeof(*out));
753 }
754 #ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
755 void
756 monotime_coarse_zero(monotime_coarse_t *out)
757 {
758  memset(out, 0, sizeof(*out));
759 }
760 #endif
761 
762 int64_t
764  const monotime_t *end)
765 {
766  const int64_t nsec = monotime_diff_nsec(start, end);
767  return CEIL_DIV(nsec, 1000);
768 }
769 
770 int64_t
772  const monotime_t *end)
773 {
774  const int64_t nsec = monotime_diff_nsec(start, end);
775  return CEIL_DIV(nsec, ONE_MILLION);
776 }
777 
778 uint64_t
780 {
781  monotime_t now;
782  if (BUG(monotime_initialized == 0)) {
783  monotime_init();
784  }
785 
786  monotime_get(&now);
787  return monotime_diff_nsec(&initialized_at, &now);
788 }
789 
790 MOCK_IMPL(uint64_t,
791 monotime_absolute_usec,(void))
792 {
793  return monotime_absolute_nsec() / 1000;
794 }
795 
796 uint64_t
798 {
799  return monotime_absolute_nsec() / ONE_MILLION;
800 }
801 
802 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
803 uint64_t
804 monotime_coarse_absolute_nsec(void)
805 {
806  if (BUG(monotime_initialized == 0)) {
807  monotime_init();
808  }
809 
810  monotime_coarse_t now;
811  monotime_coarse_get(&now);
812  return monotime_coarse_diff_nsec(&initialized_at_coarse, &now);
813 }
814 
815 uint64_t
816 monotime_coarse_absolute_usec(void)
817 {
818  return monotime_coarse_absolute_nsec() / 1000;
819 }
820 
821 uint64_t
822 monotime_coarse_absolute_msec(void)
823 {
824  return monotime_coarse_absolute_nsec() / ONE_MILLION;
825 }
826 #else
827 #define initialized_at_coarse initialized_at
828 #endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
829 
833 uint32_t
835 {
836  monotime_coarse_t now;
837  monotime_coarse_get(&now);
838  return monotime_coarse_to_stamp(&now);
839 }
840 
841 #ifdef __APPLE__
842 uint64_t
844 {
845  /* Recover as much precision as we can. */
846  uint64_t abstime_diff = (units << monotime_shift);
847  return (abstime_diff * mach_time_info.numer) /
848  (mach_time_info.denom * ONE_MILLION);
849 }
850 uint64_t
851 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
852 {
853  uint64_t abstime_val =
854  (((uint64_t)msec) * ONE_MILLION * mach_time_info.denom) /
855  mach_time_info.numer;
856  return abstime_val >> monotime_shift;
857 }
858 #else
859 uint64_t
861 {
862  return (units * 1000) / STAMP_TICKS_PER_SECOND;
863 }
864 uint64_t
865 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
866 {
867  return (msec * STAMP_TICKS_PER_SECOND) / 1000;
868 }
869 #endif
void monotime_init(void)
Definition: compat_time.c:737
#define timeradd(tv1, tv2, tvout)
Definition: timeval.h:26
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:860
#define LD_GENERAL
Definition: log.h:58
Functions and types for monotonic times.
int64_t monotime_diff_usec(const monotime_t *start, const monotime_t *end)
Definition: compat_time.c:763
#define timercmp(tv1, tv2, op)
Definition: timeval.h:59
void monotime_get(monotime_t *out)
uint64_t monotime_absolute_msec(void)
Definition: compat_time.c:797
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:779
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:771
void monotime_zero(monotime_t *out)
Definition: compat_time.c:750
Header for bits.c.
void tor_mutex_acquire(tor_mutex_t *m)
Headers for torerr.c.
#define timersub(tv1, tv2, tvout)
Definition: timeval.h:40
Headers for log.c.
Header for winlib.c.
Macros to manage assertions, fatal and non-fatal.
#define LD_BUG
Definition: log.h:82
uint32_t monotime_coarse_get_stamp(void)
Definition: compat_time.c:834