LCOV - code coverage report
Current view: top level - lib/time - compat_time.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 139 149 93.3 %
Date: 2021-11-24 03:28:48 Functions: 30 30 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2003-2004, Roger Dingledine
       2             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       3             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       4             : /* See LICENSE for licensing information */
       5             : 
       6             : /**
       7             :  * \file compat_time.c
       8             :  * \brief Portable wrappers for finding out the current time, running
       9             :  *   timers, etc.
      10             :  **/
      11             : 
      12             : #define COMPAT_TIME_PRIVATE
      13             : #include "lib/time/compat_time.h"
      14             : 
      15             : #include "lib/err/torerr.h"
      16             : #include "lib/log/log.h"
      17             : #include "lib/log/util_bug.h"
      18             : #include "lib/intmath/muldiv.h"
      19             : #include "lib/intmath/bits.h"
      20             : #include "lib/fs/winlib.h"
      21             : #include "lib/wallclock/timeval.h"
      22             : 
      23             : #ifdef _WIN32
      24             : #include <winsock2.h>
      25             : #include <windows.h>
      26             : #endif
      27             : 
      28             : #ifdef HAVE_SYS_TYPES_H
      29             : #include <sys/types.h>
      30             : #endif
      31             : #ifdef HAVE_SYS_TIME_H
      32             : #include <sys/time.h>
      33             : #endif
      34             : #ifdef HAVE_UNISTD_H
      35             : #include <unistd.h>
      36             : #endif
      37             : #ifdef TOR_UNIT_TESTS
      38             : #if !defined(HAVE_USLEEP) && defined(HAVE_SYS_SELECT_H)
      39             : /* as fallback implementation for tor_sleep_msec */
      40             : #include <sys/select.h>
      41             : #endif
      42             : #endif /* defined(TOR_UNIT_TESTS) */
      43             : 
      44             : #ifdef __APPLE__
      45             : #include <mach/mach_time.h>
      46             : #endif
      47             : 
      48             : #include <errno.h>
      49             : #include <stdlib.h>
      50             : #include <string.h>
      51             : 
      52             : #ifdef _WIN32
      53             : #undef HAVE_CLOCK_GETTIME
      54             : #endif
      55             : 
      56             : #ifdef TOR_UNIT_TESTS
      57             : /** Delay for <b>msec</b> milliseconds.  Only used in tests. */
      58             : void
      59          23 : tor_sleep_msec(int msec)
      60             : {
      61             : #ifdef _WIN32
      62             :   Sleep(msec);
      63             : #elif defined(HAVE_USLEEP)
      64          23 :   sleep(msec / 1000);
      65             :   /* Some usleep()s hate sleeping more than 1 sec */
      66          23 :   usleep((msec % 1000) * 1000);
      67             : #elif defined(HAVE_SYS_SELECT_H)
      68             :   struct timeval tv = { msec / 1000, (msec % 1000) * 1000};
      69             :   select(0, NULL, NULL, NULL, &tv);
      70             : #else
      71             :   sleep(CEIL_DIV(msec, 1000));
      72             : #endif /* defined(_WIN32) || ... */
      73          23 : }
      74             : #endif /* defined(TOR_UNIT_TESTS) */
      75             : 
      76             : #define ONE_MILLION ((int64_t) (1000 * 1000))
      77             : #define ONE_BILLION ((int64_t) (1000 * 1000 * 1000))
      78             : 
      79             : /** True iff monotime_init has been called. */
      80             : static int monotime_initialized = 0;
      81             : 
      82             : static monotime_t initialized_at;
      83             : #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
      84             : static monotime_coarse_t initialized_at_coarse;
      85             : #endif
      86             : 
      87             : #ifdef TOR_UNIT_TESTS
      88             : /** True if we are running unit tests and overriding the current monotonic
      89             :  * time.  Note that mocked monotonic time might not be monotonic.
      90             :  */
      91             : static int monotime_mocking_enabled = 0;
      92             : static monotime_t initialized_at_saved;
      93             : 
      94             : static int64_t mock_time_nsec = 0;
      95             : #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
      96             : static int64_t mock_time_nsec_coarse = 0;
      97             : static monotime_coarse_t initialized_at_coarse_saved;
      98             : #endif
      99             : 
     100             : void
     101          27 : monotime_enable_test_mocking(void)
     102             : {
     103          27 :   if (BUG(monotime_initialized == 0)) {
     104           0 :     monotime_init();
     105             :   }
     106             : 
     107          27 :   tor_assert_nonfatal(monotime_mocking_enabled == 0);
     108          27 :   monotime_mocking_enabled = 1;
     109          27 :   memcpy(&initialized_at_saved,
     110             :          &initialized_at, sizeof(monotime_t));
     111          27 :   memset(&initialized_at, 0, sizeof(monotime_t));
     112             : #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
     113          27 :   memcpy(&initialized_at_coarse_saved,
     114             :          &initialized_at_coarse, sizeof(monotime_coarse_t));
     115          27 :   memset(&initialized_at_coarse, 0, sizeof(monotime_coarse_t));
     116             : #endif
     117          27 : }
     118             : 
     119             : void
     120          23 : monotime_disable_test_mocking(void)
     121             : {
     122          23 :   tor_assert_nonfatal(monotime_mocking_enabled == 1);
     123          23 :   monotime_mocking_enabled = 0;
     124             : 
     125          23 :   memcpy(&initialized_at,
     126             :          &initialized_at_saved, sizeof(monotime_t));
     127             : #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
     128          23 :   memcpy(&initialized_at_coarse,
     129             :          &initialized_at_coarse_saved, sizeof(monotime_coarse_t));
     130             : #endif
     131          23 : }
     132             : 
     133             : void
     134         223 : monotime_set_mock_time_nsec(int64_t nsec)
     135             : {
     136         223 :   tor_assert_nonfatal(monotime_mocking_enabled == 1);
     137         223 :   mock_time_nsec = nsec;
     138         223 : }
     139             : 
     140             : #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
     141             : void
     142         266 : monotime_coarse_set_mock_time_nsec(int64_t nsec)
     143             : {
     144         266 :   tor_assert_nonfatal(monotime_mocking_enabled == 1);
     145         266 :   mock_time_nsec_coarse = nsec;
     146         266 : }
     147             : #endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
     148             : #endif /* defined(TOR_UNIT_TESTS) */
     149             : 
     150             : /* "ratchet" functions for monotonic time. */
     151             : 
     152             : #if defined(_WIN32) || defined(TOR_UNIT_TESTS)
     153             : 
     154             : /** Protected by lock: last value returned by monotime_get(). */
     155             : static int64_t last_pctr = 0;
     156             : /** Protected by lock: offset we must add to monotonic time values. */
     157             : static int64_t pctr_offset = 0;
     158             : /* If we are using GetTickCount(), how many times has it rolled over? */
     159             : static uint32_t rollover_count = 0;
     160             : /* If we are using GetTickCount(), what's the last value it returned? */
     161             : static int64_t last_tick_count = 0;
     162             : 
     163             : /** Helper for windows: Called with a sequence of times that are supposed
     164             :  * to be monotonic; increments them as appropriate so that they actually
     165             :  * _are_ monotonic.
     166             :  *
     167             :  * The returned time may be the same as the previous returned time.
     168             :  *
     169             :  * Caller must hold lock. */
     170             : STATIC int64_t
     171           8 : ratchet_performance_counter(int64_t count_raw)
     172             : {
     173             :   /* must hold lock */
     174           8 :   const int64_t count_adjusted = count_raw + pctr_offset;
     175             : 
     176           8 :   if (PREDICT_UNLIKELY(count_adjusted < last_pctr)) {
     177             :     /* Monotonicity failed! Pretend no time elapsed. */
     178           2 :     pctr_offset = last_pctr - count_raw;
     179           2 :     return last_pctr;
     180             :   } else {
     181           6 :     last_pctr = count_adjusted;
     182           6 :     return count_adjusted;
     183             :   }
     184             : }
     185             : 
     186             : STATIC int64_t
     187           5 : ratchet_coarse_performance_counter(const int64_t count_raw)
     188             : {
     189           5 :   int64_t count = count_raw + (((int64_t)rollover_count) << 32);
     190           7 :   while (PREDICT_UNLIKELY(count < last_tick_count)) {
     191           2 :     ++rollover_count;
     192           2 :     count = count_raw + (((int64_t)rollover_count) << 32);
     193             :   }
     194           5 :   last_tick_count = count;
     195           5 :   return count;
     196             : }
     197             : #endif /* defined(_WIN32) || defined(TOR_UNIT_TESTS) */
     198             : 
     199             : #if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS)
     200             : static struct timeval last_timeofday = { 0, 0 };
     201             : static struct timeval timeofday_offset = { 0, 0 };
     202             : 
     203             : /** Helper for gettimeofday(): Called with a sequence of times that are
     204             :  * supposed to be monotonic; increments them as appropriate so that they
     205             :  * actually _are_ monotonic.
     206             :  *
     207             :  * The returned time may be the same as the previous returned time.
     208             :  *
     209             :  * Caller must hold lock. */
     210             : STATIC void
     211           7 : ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out)
     212             : {
     213             :   /* must hold lock */
     214           7 :   timeradd(timeval_raw, &timeofday_offset, out);
     215           7 :   if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, OP_LT))) {
     216             :     /* time ran backwards. Instead, declare that no time occurred. */
     217           2 :     timersub(&last_timeofday, timeval_raw, &timeofday_offset);
     218           2 :     memcpy(out, &last_timeofday, sizeof(struct timeval));
     219             :   } else {
     220           5 :     memcpy(&last_timeofday, out, sizeof(struct timeval));
     221             :   }
     222           7 : }
     223             : #endif /* defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS) */
     224             : 
     225             : #ifdef TOR_UNIT_TESTS
     226             : /** For testing: reset all the ratchets */
     227             : void
     228           1 : monotime_reset_ratchets_for_testing(void)
     229             : {
     230           1 :   last_pctr = pctr_offset = last_tick_count = 0;
     231           1 :   rollover_count = 0;
     232           1 :   memset(&last_timeofday, 0, sizeof(struct timeval));
     233           1 :   memset(&timeofday_offset, 0, sizeof(struct timeval));
     234           1 : }
     235             : #endif /* defined(TOR_UNIT_TESTS) */
     236             : 
     237             : #ifdef __APPLE__
     238             : 
     239             : /** Initialized on startup: tells is how to convert from ticks to
     240             :  * nanoseconds.
     241             :  */
     242             : static struct mach_timebase_info mach_time_info;
     243             : static struct mach_timebase_info mach_time_info_msec_cvt;
     244             : static int32_t mach_time_msec_cvt_threshold;
     245             : static int monotime_shift = 0;
     246             : 
     247             : static void
     248             : monotime_init_internal(void)
     249             : {
     250             :   tor_assert(!monotime_initialized);
     251             :   int r = mach_timebase_info(&mach_time_info);
     252             :   tor_assert(r == 0);
     253             :   tor_assert(mach_time_info.denom != 0);
     254             : 
     255             :   {
     256             :     // approximate only.
     257             :     uint64_t ns_per_tick = mach_time_info.numer / mach_time_info.denom;
     258             :     uint64_t ms_per_tick = ns_per_tick * ONE_MILLION;
     259             :     // requires that tor_log2(0) == 0.
     260             :     monotime_shift = tor_log2(ms_per_tick);
     261             :   }
     262             :   {
     263             :     // For converting ticks to milliseconds in a 32-bit-friendly way, we
     264             :     // will first right-shift by 20, and then multiply by 2048/1953, since
     265             :     // (1<<20) * 1953/2048 is about 1e6.  We precompute a new numerator and
     266             :     // denominator here to avoid multiple multiplies.
     267             :     mach_time_info_msec_cvt.numer = mach_time_info.numer * 2048;
     268             :     mach_time_info_msec_cvt.denom = mach_time_info.denom * 1953;
     269             :     // For any value above this amount, we should divide before multiplying,
     270             :     // to avoid overflow.  For a value below this, we should multiply
     271             :     // before dividing, to improve accuracy.
     272             :     mach_time_msec_cvt_threshold = INT32_MAX / mach_time_info_msec_cvt.numer;
     273             :   }
     274             : }
     275             : 
     276             : /**
     277             :  * Set "out" to the most recent monotonic time value.
     278             :  *
     279             :  * The returned time may be the same as the previous returned time.
     280             :  */
     281             : void
     282             : monotime_get(monotime_t *out)
     283             : {
     284             : #ifdef TOR_UNIT_TESTS
     285             :   if (monotime_mocking_enabled) {
     286             :     out->abstime_ = (mock_time_nsec * mach_time_info.denom)
     287             :       / mach_time_info.numer;
     288             :     return;
     289             :   }
     290             : #endif /* defined(TOR_UNIT_TESTS) */
     291             :   out->abstime_ = mach_absolute_time();
     292             : }
     293             : 
     294             : #if defined(HAVE_MACH_APPROXIMATE_TIME)
     295             : void
     296             : monotime_coarse_get(monotime_coarse_t *out)
     297             : {
     298             : #ifdef TOR_UNIT_TESTS
     299             :   if (monotime_mocking_enabled) {
     300             :     out->abstime_ = (mock_time_nsec_coarse * mach_time_info.denom)
     301             :       / mach_time_info.numer;
     302             :     return;
     303             :   }
     304             : #endif /* defined(TOR_UNIT_TESTS) */
     305             :   out->abstime_ = mach_approximate_time();
     306             : }
     307             : #endif /* defined(HAVE_MACH_APPROXIMATE_TIME) */
     308             : 
     309             : /**
     310             :  * Return the number of nanoseconds between <b>start</b> and <b>end</b>.
     311             :  *
     312             :  * The returned value may be equal to zero.
     313             :  */
     314             : int64_t
     315             : monotime_diff_nsec(const monotime_t *start,
     316             :                    const monotime_t *end)
     317             : {
     318             :   if (BUG(mach_time_info.denom == 0)) {
     319             :     monotime_init();
     320             :   }
     321             :   const int64_t diff_ticks = end->abstime_ - start->abstime_;
     322             :   const int64_t diff_nsec =
     323             :     (diff_ticks * mach_time_info.numer) / mach_time_info.denom;
     324             :   return diff_nsec;
     325             : }
     326             : 
     327             : int32_t
     328             : monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
     329             :                              const monotime_coarse_t *end)
     330             : {
     331             :   if (BUG(mach_time_info.denom == 0)) {
     332             :     monotime_init();
     333             :   }
     334             :   const int64_t diff_ticks = end->abstime_ - start->abstime_;
     335             : 
     336             :   /* We already require in di_ops.c that right-shift performs a sign-extend. */
     337             :   const int32_t diff_microticks = (int32_t)(diff_ticks >> 20);
     338             : 
     339             :   if (diff_microticks >= mach_time_msec_cvt_threshold) {
     340             :     return (diff_microticks / mach_time_info_msec_cvt.denom) *
     341             :       mach_time_info_msec_cvt.numer;
     342             :   } else {
     343             :     return (diff_microticks * mach_time_info_msec_cvt.numer) /
     344             :       mach_time_info_msec_cvt.denom;
     345             :   }
     346             : }
     347             : 
     348             : uint32_t
     349             : monotime_coarse_to_stamp(const monotime_coarse_t *t)
     350             : {
     351             :   return (uint32_t)(t->abstime_ >> monotime_shift);
     352             : }
     353             : 
     354             : int
     355             : monotime_is_zero(const monotime_t *val)
     356             : {
     357             :   return val->abstime_ == 0;
     358             : }
     359             : 
     360             : void
     361             : monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
     362             : {
     363             :   const uint64_t nsec = msec * ONE_MILLION;
     364             :   const uint64_t ticks = (nsec * mach_time_info.denom) / mach_time_info.numer;
     365             :   out->abstime_ = val->abstime_ + ticks;
     366             : }
     367             : 
     368             : /* end of "__APPLE__" */
     369             : #elif defined(HAVE_CLOCK_GETTIME)
     370             : 
     371             : #ifdef CLOCK_MONOTONIC_COARSE
     372             : /**
     373             :  * Which clock should we use for coarse-grained monotonic time? By default
     374             :  * this is CLOCK_MONOTONIC_COARSE, but it might not work -- for example,
     375             :  * if we're compiled with newer Linux headers and then we try to run on
     376             :  * an old Linux kernel. In that case, we will fall back to CLOCK_MONOTONIC.
     377             :  */
     378             : static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
     379             : #endif /* defined(CLOCK_MONOTONIC_COARSE) */
     380             : 
     381             : static void
     382        5554 : monotime_init_internal(void)
     383             : {
     384             : #ifdef CLOCK_MONOTONIC_COARSE
     385        5554 :   struct timespec ts;
     386        5554 :   if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) < 0) {
     387           0 :     log_info(LD_GENERAL, "CLOCK_MONOTONIC_COARSE isn't working (%s); "
     388             :              "falling back to CLOCK_MONOTONIC.", strerror(errno));
     389           0 :     clock_monotonic_coarse = CLOCK_MONOTONIC;
     390             :   }
     391             : #endif /* defined(CLOCK_MONOTONIC_COARSE) */
     392        5554 : }
     393             : 
     394             : void
     395       10650 : monotime_get(monotime_t *out)
     396             : {
     397             : #ifdef TOR_UNIT_TESTS
     398       10650 :   if (monotime_mocking_enabled) {
     399         512 :     out->ts_.tv_sec = (time_t) (mock_time_nsec / ONE_BILLION);
     400         512 :     out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION);
     401         512 :     return;
     402             :   }
     403             : #endif /* defined(TOR_UNIT_TESTS) */
     404       10138 :   int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
     405       10138 :   tor_assert(r == 0);
     406             : }
     407             : 
     408             : #ifdef CLOCK_MONOTONIC_COARSE
     409             : void
     410       10532 : monotime_coarse_get(monotime_coarse_t *out)
     411             : {
     412             : #ifdef TOR_UNIT_TESTS
     413       10532 :   if (monotime_mocking_enabled) {
     414        1170 :     out->ts_.tv_sec = (time_t) (mock_time_nsec_coarse / ONE_BILLION);
     415        1170 :     out->ts_.tv_nsec = (int) (mock_time_nsec_coarse % ONE_BILLION);
     416        1170 :     return;
     417             :   }
     418             : #endif /* defined(TOR_UNIT_TESTS) */
     419        9362 :   int r = clock_gettime(clock_monotonic_coarse, &out->ts_);
     420        9362 :   if (PREDICT_UNLIKELY(r < 0) &&
     421           0 :       errno == EINVAL &&
     422           0 :       clock_monotonic_coarse == CLOCK_MONOTONIC_COARSE) {
     423             :     /* We should have caught this at startup in monotime_init_internal!
     424             :      */
     425           0 :     log_warn(LD_BUG, "Falling back to non-coarse monotonic time %s initial "
     426             :              "system start?", monotime_initialized?"after":"without");
     427           0 :     clock_monotonic_coarse = CLOCK_MONOTONIC;
     428           0 :     r = clock_gettime(clock_monotonic_coarse, &out->ts_);
     429             :   }
     430             : 
     431        9362 :   tor_assert(r == 0);
     432             : }
     433             : #endif /* defined(CLOCK_MONOTONIC_COARSE) */
     434             : 
     435             : int64_t
     436        6931 : monotime_diff_nsec(const monotime_t *start,
     437             :                    const monotime_t *end)
     438             : {
     439        6931 :   const int64_t diff_sec = end->ts_.tv_sec - start->ts_.tv_sec;
     440        6931 :   const int64_t diff_nsec = diff_sec * ONE_BILLION +
     441        6931 :     (end->ts_.tv_nsec - start->ts_.tv_nsec);
     442             : 
     443        6931 :   return diff_nsec;
     444             : }
     445             : 
     446             : int32_t
     447           4 : monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
     448             :                              const monotime_coarse_t *end)
     449             : {
     450           4 :   const int32_t diff_sec = (int32_t)(end->ts_.tv_sec - start->ts_.tv_sec);
     451           4 :   const int32_t diff_nsec = (int32_t)(end->ts_.tv_nsec - start->ts_.tv_nsec);
     452           4 :   return diff_sec * 1000 + diff_nsec / ONE_MILLION;
     453             : }
     454             : 
     455             : /* This value is ONE_BILLION >> 20. */
     456             : static const uint32_t STAMP_TICKS_PER_SECOND = 953;
     457             : 
     458             : uint32_t
     459        4149 : monotime_coarse_to_stamp(const monotime_coarse_t *t)
     460             : {
     461        4149 :   uint32_t nsec = (uint32_t)t->ts_.tv_nsec;
     462        4149 :   uint32_t sec = (uint32_t)t->ts_.tv_sec;
     463             : 
     464        4149 :   return (sec * STAMP_TICKS_PER_SECOND) + (nsec >> 20);
     465             : }
     466             : 
     467             : int
     468         445 : monotime_is_zero(const monotime_t *val)
     469             : {
     470         445 :   return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0;
     471             : }
     472             : 
     473             : void
     474         227 : monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
     475             : {
     476         227 :   const uint32_t sec = msec / 1000;
     477         227 :   const uint32_t msec_remainder = msec % 1000;
     478         227 :   out->ts_.tv_sec = val->ts_.tv_sec + sec;
     479         227 :   out->ts_.tv_nsec = val->ts_.tv_nsec + (msec_remainder * ONE_MILLION);
     480         227 :   if (out->ts_.tv_nsec > ONE_BILLION) {
     481           2 :     out->ts_.tv_nsec -= ONE_BILLION;
     482           2 :     out->ts_.tv_sec += 1;
     483             :   }
     484         227 : }
     485             : 
     486             : /* end of "HAVE_CLOCK_GETTIME" */
     487             : #elif defined (_WIN32)
     488             : 
     489             : /** Result of QueryPerformanceFrequency, in terms needed to
     490             :  * convert ticks to nanoseconds. */
     491             : static int64_t nsec_per_tick_numer = 1;
     492             : static int64_t nsec_per_tick_denom = 1;
     493             : 
     494             : /** Lock to protect last_pctr and pctr_offset */
     495             : static CRITICAL_SECTION monotime_lock;
     496             : /** Lock to protect rollover_count and last_tick_count */
     497             : static CRITICAL_SECTION monotime_coarse_lock;
     498             : 
     499             : typedef ULONGLONG (WINAPI *GetTickCount64_fn_t)(void);
     500             : static GetTickCount64_fn_t GetTickCount64_fn = NULL;
     501             : 
     502             : static void
     503             : monotime_init_internal(void)
     504             : {
     505             :   tor_assert(!monotime_initialized);
     506             :   BOOL ok = InitializeCriticalSectionAndSpinCount(&monotime_lock, 200);
     507             :   tor_assert(ok);
     508             :   ok = InitializeCriticalSectionAndSpinCount(&monotime_coarse_lock, 200);
     509             :   tor_assert(ok);
     510             :   LARGE_INTEGER li;
     511             :   ok = QueryPerformanceFrequency(&li);
     512             :   tor_assert(ok);
     513             :   tor_assert(li.QuadPart);
     514             : 
     515             :   uint64_t n = ONE_BILLION;
     516             :   uint64_t d = li.QuadPart;
     517             :   /* We need to simplify this or we'll probably overflow the int64. */
     518             :   simplify_fraction64(&n, &d);
     519             :   tor_assert(n <= INT64_MAX);
     520             :   tor_assert(d <= INT64_MAX);
     521             : 
     522             :   nsec_per_tick_numer = (int64_t) n;
     523             :   nsec_per_tick_denom = (int64_t) d;
     524             : 
     525             :   last_pctr = 0;
     526             :   pctr_offset = 0;
     527             : 
     528             :   HANDLE h = load_windows_system_library(TEXT("kernel32.dll"));
     529             :   if (h) {
     530             :     GetTickCount64_fn = (GetTickCount64_fn_t) (void(*)(void))
     531             :       GetProcAddress(h, "GetTickCount64");
     532             :   }
     533             :   // We can't call FreeLibrary(h) here, because freeing the handle may
     534             :   // unload the library, and cause future calls to GetTickCount64_fn()
     535             :   // to fail. See 29642 for details.
     536             : }
     537             : 
     538             : void
     539             : monotime_get(monotime_t *out)
     540             : {
     541             :   if (BUG(monotime_initialized == 0)) {
     542             :     monotime_init();
     543             :   }
     544             : 
     545             : #ifdef TOR_UNIT_TESTS
     546             :   if (monotime_mocking_enabled) {
     547             :     out->pcount_ = (mock_time_nsec * nsec_per_tick_denom)
     548             :       / nsec_per_tick_numer;
     549             :     return;
     550             :   }
     551             : #endif /* defined(TOR_UNIT_TESTS) */
     552             : 
     553             :   /* Alas, QueryPerformanceCounter is not always monotonic: see bug list at
     554             : 
     555             :     https://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter
     556             :    */
     557             : 
     558             :   EnterCriticalSection(&monotime_lock);
     559             :   LARGE_INTEGER res;
     560             :   BOOL ok = QueryPerformanceCounter(&res);
     561             :   tor_assert(ok);
     562             :   const int64_t count_raw = res.QuadPart;
     563             :   out->pcount_ = ratchet_performance_counter(count_raw);
     564             :   LeaveCriticalSection(&monotime_lock);
     565             : }
     566             : 
     567             : void
     568             : monotime_coarse_get(monotime_coarse_t *out)
     569             : {
     570             : #ifdef TOR_UNIT_TESTS
     571             :   if (monotime_mocking_enabled) {
     572             :     out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
     573             :     return;
     574             :   }
     575             : #endif /* defined(TOR_UNIT_TESTS) */
     576             : 
     577             :   if (GetTickCount64_fn) {
     578             :     out->tick_count_ = (int64_t)GetTickCount64_fn();
     579             :   } else {
     580             :     EnterCriticalSection(&monotime_coarse_lock);
     581             :     DWORD tick = GetTickCount();
     582             :     out->tick_count_ = ratchet_coarse_performance_counter(tick);
     583             :     LeaveCriticalSection(&monotime_coarse_lock);
     584             :   }
     585             : }
     586             : 
     587             : int64_t
     588             : monotime_diff_nsec(const monotime_t *start,
     589             :                    const monotime_t *end)
     590             : {
     591             :   if (BUG(monotime_initialized == 0)) {
     592             :     monotime_init();
     593             :   }
     594             :   const int64_t diff_ticks = end->pcount_ - start->pcount_;
     595             :   return (diff_ticks * nsec_per_tick_numer) / nsec_per_tick_denom;
     596             : }
     597             : 
     598             : int64_t
     599             : monotime_coarse_diff_msec(const monotime_coarse_t *start,
     600             :                           const monotime_coarse_t *end)
     601             : {
     602             :   const int64_t diff_ticks = end->tick_count_ - start->tick_count_;
     603             :   return diff_ticks;
     604             : }
     605             : 
     606             : int32_t
     607             : monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
     608             :                              const monotime_coarse_t *end)
     609             : {
     610             :   return (int32_t)monotime_coarse_diff_msec(start, end);
     611             : }
     612             : 
     613             : int64_t
     614             : monotime_coarse_diff_usec(const monotime_coarse_t *start,
     615             :                           const monotime_coarse_t *end)
     616             : {
     617             :   return monotime_coarse_diff_msec(start, end) * 1000;
     618             : }
     619             : 
     620             : int64_t
     621             : monotime_coarse_diff_nsec(const monotime_coarse_t *start,
     622             :                           const monotime_coarse_t *end)
     623             : {
     624             :   return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
     625             : }
     626             : 
     627             : static const uint32_t STAMP_TICKS_PER_SECOND = 1000;
     628             : 
     629             : uint32_t
     630             : monotime_coarse_to_stamp(const monotime_coarse_t *t)
     631             : {
     632             :   return (uint32_t) t->tick_count_;
     633             : }
     634             : 
     635             : int
     636             : monotime_is_zero(const monotime_t *val)
     637             : {
     638             :   return val->pcount_ == 0;
     639             : }
     640             : 
     641             : int
     642             : monotime_coarse_is_zero(const monotime_coarse_t *val)
     643             : {
     644             :   return val->tick_count_ == 0;
     645             : }
     646             : 
     647             : void
     648             : monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
     649             : {
     650             :   const uint64_t nsec = msec * ONE_MILLION;
     651             :   const uint64_t ticks = (nsec * nsec_per_tick_denom) / nsec_per_tick_numer;
     652             :   out->pcount_ = val->pcount_ + ticks;
     653             : }
     654             : 
     655             : void
     656             : monotime_coarse_add_msec(monotime_coarse_t *out, const monotime_coarse_t *val,
     657             :                          uint32_t msec)
     658             : {
     659             :   out->tick_count_ = val->tick_count_ + msec;
     660             : }
     661             : 
     662             : /* end of "_WIN32" */
     663             : #elif defined(MONOTIME_USING_GETTIMEOFDAY)
     664             : 
     665             : static tor_mutex_t monotime_lock;
     666             : 
     667             : /** Initialize the monotonic timer subsystem. */
     668             : static void
     669             : monotime_init_internal(void)
     670             : {
     671             :   tor_assert(!monotime_initialized);
     672             :   tor_mutex_init(&monotime_lock);
     673             : }
     674             : 
     675             : void
     676             : monotime_get(monotime_t *out)
     677             : {
     678             :   if (BUG(monotime_initialized == 0)) {
     679             :     monotime_init();
     680             :   }
     681             : 
     682             :   tor_mutex_acquire(&monotime_lock);
     683             :   struct timeval timeval_raw;
     684             :   tor_gettimeofday(&timeval_raw);
     685             :   ratchet_timeval(&timeval_raw, &out->tv_);
     686             :   tor_mutex_release(&monotime_lock);
     687             : }
     688             : 
     689             : int64_t
     690             : monotime_diff_nsec(const monotime_t *start,
     691             :                    const monotime_t *end)
     692             : {
     693             :   struct timeval diff;
     694             :   timersub(&end->tv_, &start->tv_, &diff);
     695             :   return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
     696             : }
     697             : 
     698             : int32_t
     699             : monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
     700             :                              const monotime_coarse_t *end)
     701             : {
     702             :   struct timeval diff;
     703             :   timersub(&end->tv_, &start->tv_, &diff);
     704             :   return diff.tv_sec * 1000 + diff.tv_usec / 1000;
     705             : }
     706             : 
     707             : /* This value is ONE_MILLION >> 10. */
     708             : static const uint32_t STAMP_TICKS_PER_SECOND = 976;
     709             : 
     710             : uint32_t
     711             : monotime_coarse_to_stamp(const monotime_coarse_t *t)
     712             : {
     713             :   const uint32_t usec = (uint32_t)t->tv_.tv_usec;
     714             :   const uint32_t sec = (uint32_t)t->tv_.tv_sec;
     715             :   return (sec * STAMP_TICKS_PER_SECOND) | (nsec >> 10);
     716             : }
     717             : 
     718             : int
     719             : monotime_is_zero(const monotime_t *val)
     720             : {
     721             :   return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0;
     722             : }
     723             : 
     724             : void
     725             : monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
     726             : {
     727             :   const uint32_t sec = msec / 1000;
     728             :   const uint32_t msec_remainder = msec % 1000;
     729             :   out->tv_.tv_sec = val->tv_.tv_sec + sec;
     730             :   out->tv_.tv_usec = val->tv_.tv_nsec + (msec_remainder * 1000);
     731             :   if (out->tv_.tv_usec > ONE_MILLION) {
     732             :     out->tv_.tv_usec -= ONE_MILLION;
     733             :     out->tv_.tv_sec += 1;
     734             :   }
     735             : }
     736             : 
     737             : /* end of "MONOTIME_USING_GETTIMEOFDAY" */
     738             : #else
     739             : #error "No way to implement monotonic timers."
     740             : #endif /* defined(__APPLE__) || ... */
     741             : 
     742             : /**
     743             :  * Initialize the monotonic timer subsystem. Must be called before any
     744             :  * monotonic timer functions. This function is idempotent.
     745             :  */
     746             : void
     747        5585 : monotime_init(void)
     748             : {
     749        5585 :   if (!monotime_initialized) {
     750        5554 :     monotime_init_internal();
     751        5554 :     monotime_initialized = 1;
     752        5554 :     monotime_get(&initialized_at);
     753             : #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
     754        5554 :     monotime_coarse_get(&initialized_at_coarse);
     755             : #endif
     756             :   }
     757        5585 : }
     758             : 
     759             : void
     760         328 : monotime_zero(monotime_t *out)
     761             : {
     762         328 :   memset(out, 0, sizeof(*out));
     763         328 : }
     764             : #ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
     765             : void
     766             : monotime_coarse_zero(monotime_coarse_t *out)
     767             : {
     768             :   memset(out, 0, sizeof(*out));
     769             : }
     770             : #endif /* defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT) */
     771             : 
     772             : int64_t
     773        5992 : monotime_diff_usec(const monotime_t *start,
     774             :                    const monotime_t *end)
     775             : {
     776        5992 :   const int64_t nsec = monotime_diff_nsec(start, end);
     777        5992 :   return CEIL_DIV(nsec, 1000);
     778             : }
     779             : 
     780             : int64_t
     781         892 : monotime_diff_msec(const monotime_t *start,
     782             :                    const monotime_t *end)
     783             : {
     784         892 :   const int64_t nsec = monotime_diff_nsec(start, end);
     785         892 :   return CEIL_DIV(nsec, ONE_MILLION);
     786             : }
     787             : 
     788             : uint64_t
     789          43 : monotime_absolute_nsec(void)
     790             : {
     791          43 :   monotime_t now;
     792          43 :   if (BUG(monotime_initialized == 0)) {
     793           0 :     monotime_init();
     794             :   }
     795             : 
     796          43 :   monotime_get(&now);
     797          43 :   return monotime_diff_nsec(&initialized_at, &now);
     798             : }
     799             : 
     800          32 : MOCK_IMPL(uint64_t,
     801             : monotime_absolute_usec,(void))
     802             : {
     803          32 :   return monotime_absolute_nsec() / 1000;
     804             : }
     805             : 
     806             : uint64_t
     807           1 : monotime_absolute_msec(void)
     808             : {
     809           1 :   return monotime_absolute_nsec() / ONE_MILLION;
     810             : }
     811             : 
     812             : #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
     813             : uint64_t
     814           4 : monotime_coarse_absolute_nsec(void)
     815             : {
     816           4 :   if (BUG(monotime_initialized == 0)) {
     817           0 :     monotime_init();
     818             :   }
     819             : 
     820           4 :   monotime_coarse_t now;
     821           4 :   monotime_coarse_get(&now);
     822           4 :   return monotime_coarse_diff_nsec(&initialized_at_coarse, &now);
     823             : }
     824             : 
     825             : uint64_t
     826           1 : monotime_coarse_absolute_usec(void)
     827             : {
     828           1 :   return monotime_coarse_absolute_nsec() / 1000;
     829             : }
     830             : 
     831             : uint64_t
     832           1 : monotime_coarse_absolute_msec(void)
     833             : {
     834           1 :   return monotime_coarse_absolute_nsec() / ONE_MILLION;
     835             : }
     836             : #else /* !defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
     837             : #define initialized_at_coarse initialized_at
     838             : #endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
     839             : 
     840             : /**
     841             :  * Return the current time "stamp" as described by monotime_coarse_to_stamp.
     842             :  */
     843             : uint32_t
     844        4147 : monotime_coarse_get_stamp(void)
     845             : {
     846        4147 :   monotime_coarse_t now;
     847        4147 :   monotime_coarse_get(&now);
     848        4147 :   return monotime_coarse_to_stamp(&now);
     849             : }
     850             : 
     851             : #ifdef __APPLE__
     852             : uint64_t
     853             : monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
     854             : {
     855             :   /* Recover as much precision as we can. */
     856             :   uint64_t abstime_diff = (units << monotime_shift);
     857             :   return (abstime_diff * mach_time_info.numer) /
     858             :     (mach_time_info.denom * ONE_MILLION);
     859             : }
     860             : uint64_t
     861             : monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
     862             : {
     863             :   uint64_t abstime_val =
     864             :     (((uint64_t)msec) * ONE_MILLION * mach_time_info.denom) /
     865             :     mach_time_info.numer;
     866             :   return abstime_val >> monotime_shift;
     867             : }
     868             : #else /* !defined(__APPLE__) */
     869             : uint64_t
     870          31 : monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
     871             : {
     872          31 :   return (units * 1000) / STAMP_TICKS_PER_SECOND;
     873             : }
     874             : uint64_t
     875           3 : monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
     876             : {
     877           3 :   return (msec * STAMP_TICKS_PER_SECOND) / 1000;
     878             : }
     879             : #endif /* defined(__APPLE__) */

Generated by: LCOV version 1.14