tor  0.4.1.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 
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  // We can't call FreeLibrary(h) here, because freeing the handle may
526  // unload the library, and cause future calls to GetTickCount64_fn()
527  // to fail. See 29642 for details.
528 }
529 
530 void
532 {
533  if (BUG(monotime_initialized == 0)) {
534  monotime_init();
535  }
536 
537 #ifdef TOR_UNIT_TESTS
538  if (monotime_mocking_enabled) {
539  out->pcount_ = (mock_time_nsec * nsec_per_tick_denom)
540  / nsec_per_tick_numer;
541  return;
542  }
543 #endif /* defined(TOR_UNIT_TESTS) */
544 
545  /* Alas, QueryPerformanceCounter is not always monotonic: see bug list at
546 
547  https://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter
548  */
549 
550  EnterCriticalSection(&monotime_lock);
551  LARGE_INTEGER res;
552  BOOL ok = QueryPerformanceCounter(&res);
553  tor_assert(ok);
554  const int64_t count_raw = res.QuadPart;
555  out->pcount_ = ratchet_performance_counter(count_raw);
556  LeaveCriticalSection(&monotime_lock);
557 }
558 
559 void
560 monotime_coarse_get(monotime_coarse_t *out)
561 {
562 #ifdef TOR_UNIT_TESTS
563  if (monotime_mocking_enabled) {
564  out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
565  return;
566  }
567 #endif /* defined(TOR_UNIT_TESTS) */
568 
569  if (GetTickCount64_fn) {
570  out->tick_count_ = (int64_t)GetTickCount64_fn();
571  } else {
572  EnterCriticalSection(&monotime_coarse_lock);
573  DWORD tick = GetTickCount();
574  out->tick_count_ = ratchet_coarse_performance_counter(tick);
575  LeaveCriticalSection(&monotime_coarse_lock);
576  }
577 }
578 
579 int64_t
580 monotime_diff_nsec(const monotime_t *start,
581  const monotime_t *end)
582 {
583  if (BUG(monotime_initialized == 0)) {
584  monotime_init();
585  }
586  const int64_t diff_ticks = end->pcount_ - start->pcount_;
587  return (diff_ticks * nsec_per_tick_numer) / nsec_per_tick_denom;
588 }
589 
590 int64_t
591 monotime_coarse_diff_msec(const monotime_coarse_t *start,
592  const monotime_coarse_t *end)
593 {
594  const int64_t diff_ticks = end->tick_count_ - start->tick_count_;
595  return diff_ticks;
596 }
597 
598 int32_t
599 monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
600  const monotime_coarse_t *end)
601 {
602  return (int32_t)monotime_coarse_diff_msec(start, end);
603 }
604 
605 int64_t
606 monotime_coarse_diff_usec(const monotime_coarse_t *start,
607  const monotime_coarse_t *end)
608 {
609  return monotime_coarse_diff_msec(start, end) * 1000;
610 }
611 
612 int64_t
613 monotime_coarse_diff_nsec(const monotime_coarse_t *start,
614  const monotime_coarse_t *end)
615 {
616  return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
617 }
618 
619 static const uint32_t STAMP_TICKS_PER_SECOND = 1000;
620 
621 uint32_t
622 monotime_coarse_to_stamp(const monotime_coarse_t *t)
623 {
624  return (uint32_t) t->tick_count_;
625 }
626 
627 int
628 monotime_is_zero(const monotime_t *val)
629 {
630  return val->pcount_ == 0;
631 }
632 
633 int
634 monotime_coarse_is_zero(const monotime_coarse_t *val)
635 {
636  return val->tick_count_ == 0;
637 }
638 
639 void
640 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
641 {
642  const uint64_t nsec = msec * ONE_MILLION;
643  const uint64_t ticks = (nsec * nsec_per_tick_denom) / nsec_per_tick_numer;
644  out->pcount_ = val->pcount_ + ticks;
645 }
646 
647 void
648 monotime_coarse_add_msec(monotime_coarse_t *out, const monotime_coarse_t *val,
649  uint32_t msec)
650 {
651  out->tick_count_ = val->tick_count_ + msec;
652 }
653 
654 /* end of "_WIN32" */
655 #elif defined(MONOTIME_USING_GETTIMEOFDAY)
656 
657 static tor_mutex_t monotime_lock;
658 
660 static void
661 monotime_init_internal(void)
662 {
664  tor_mutex_init(&monotime_lock);
665 }
666 
667 void
669 {
670  if (BUG(monotime_initialized == 0)) {
671  monotime_init();
672  }
673 
674  tor_mutex_acquire(&monotime_lock);
675  struct timeval timeval_raw;
676  tor_gettimeofday(&timeval_raw);
677  ratchet_timeval(&timeval_raw, &out->tv_);
678  tor_mutex_release(&monotime_lock);
679 }
680 
681 int64_t
682 monotime_diff_nsec(const monotime_t *start,
683  const monotime_t *end)
684 {
685  struct timeval diff;
686  timersub(&end->tv_, &start->tv_, &diff);
687  return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
688 }
689 
690 int32_t
691 monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
692  const monotime_coarse_t *end)
693 {
694  struct timeval diff;
695  timersub(&end->tv_, &start->tv_, &diff);
696  return diff.tv_sec * 1000 + diff.tv_usec / 1000;
697 }
698 
699 /* This value is ONE_MILLION >> 10. */
700 static const uint32_t STAMP_TICKS_PER_SECOND = 976;
701 
702 uint32_t
703 monotime_coarse_to_stamp(const monotime_coarse_t *t)
704 {
705  const uint32_t usec = (uint32_t)t->tv_.tv_usec;
706  const uint32_t sec = (uint32_t)t->tv_.tv_sec;
707  return (sec * STAMP_TICKS_PER_SECOND) | (nsec >> 10);
708 }
709 
710 int
711 monotime_is_zero(const monotime_t *val)
712 {
713  return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0;
714 }
715 
716 void
717 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
718 {
719  const uint32_t sec = msec / 1000;
720  const uint32_t msec_remainder = msec % 1000;
721  out->tv_.tv_sec = val->tv_.tv_sec + sec;
722  out->tv_.tv_usec = val->tv_.tv_nsec + (msec_remainder * 1000);
723  if (out->tv_.tv_usec > ONE_MILLION) {
724  out->tv_.tv_usec -= ONE_MILLION;
725  out->tv_.tv_sec += 1;
726  }
727 }
728 
729 /* end of "MONOTIME_USING_GETTIMEOFDAY" */
730 #else
731 #error "No way to implement monotonic timers."
732 #endif /* defined(__APPLE__) || ... */
733 
738 void
740 {
741  if (!monotime_initialized) {
742  monotime_init_internal();
744  monotime_get(&initialized_at);
745 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
746  monotime_coarse_get(&initialized_at_coarse);
747 #endif
748  }
749 }
750 
751 void
753 {
754  memset(out, 0, sizeof(*out));
755 }
756 #ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
757 void
758 monotime_coarse_zero(monotime_coarse_t *out)
759 {
760  memset(out, 0, sizeof(*out));
761 }
762 #endif
763 
764 int64_t
766  const monotime_t *end)
767 {
768  const int64_t nsec = monotime_diff_nsec(start, end);
769  return CEIL_DIV(nsec, 1000);
770 }
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, ONE_MILLION);
778 }
779 
780 uint64_t
782 {
783  monotime_t now;
784  if (BUG(monotime_initialized == 0)) {
785  monotime_init();
786  }
787 
788  monotime_get(&now);
789  return monotime_diff_nsec(&initialized_at, &now);
790 }
791 
792 MOCK_IMPL(uint64_t,
793 monotime_absolute_usec,(void))
794 {
795  return monotime_absolute_nsec() / 1000;
796 }
797 
798 uint64_t
800 {
801  return monotime_absolute_nsec() / ONE_MILLION;
802 }
803 
804 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
805 uint64_t
806 monotime_coarse_absolute_nsec(void)
807 {
808  if (BUG(monotime_initialized == 0)) {
809  monotime_init();
810  }
811 
812  monotime_coarse_t now;
813  monotime_coarse_get(&now);
814  return monotime_coarse_diff_nsec(&initialized_at_coarse, &now);
815 }
816 
817 uint64_t
818 monotime_coarse_absolute_usec(void)
819 {
820  return monotime_coarse_absolute_nsec() / 1000;
821 }
822 
823 uint64_t
824 monotime_coarse_absolute_msec(void)
825 {
826  return monotime_coarse_absolute_nsec() / ONE_MILLION;
827 }
828 #else
829 #define initialized_at_coarse initialized_at
830 #endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
831 
835 uint32_t
837 {
838  monotime_coarse_t now;
839  monotime_coarse_get(&now);
840  return monotime_coarse_to_stamp(&now);
841 }
842 
843 #ifdef __APPLE__
844 uint64_t
846 {
847  /* Recover as much precision as we can. */
848  uint64_t abstime_diff = (units << monotime_shift);
849  return (abstime_diff * mach_time_info.numer) /
850  (mach_time_info.denom * ONE_MILLION);
851 }
852 uint64_t
853 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
854 {
855  uint64_t abstime_val =
856  (((uint64_t)msec) * ONE_MILLION * mach_time_info.denom) /
857  mach_time_info.numer;
858  return abstime_val >> monotime_shift;
859 }
860 #else
861 uint64_t
863 {
864  return (units * 1000) / STAMP_TICKS_PER_SECOND;
865 }
866 uint64_t
867 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
868 {
869  return (msec * STAMP_TICKS_PER_SECOND) / 1000;
870 }
871 #endif
void monotime_init(void)
Definition: compat_time.c:739
#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:862
#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:765
#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:799
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:781
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:773
void monotime_zero(monotime_t *out)
Definition: compat_time.c:752
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:83
uint32_t monotime_coarse_get_stamp(void)
Definition: compat_time.c:836