compat_time.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2016, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. /**
  6. * \file compat_time.c
  7. * \brief Portable wrappers for finding out the current time, running
  8. * timers, etc.
  9. **/
  10. #define COMPAT_TIME_PRIVATE
  11. #include "compat.h"
  12. #ifdef _WIN32
  13. #undef HAVE_CLOCK_GETTIME
  14. #include <winsock2.h>
  15. #include <windows.h>
  16. #endif
  17. #ifdef HAVE_SYS_TYPES_H
  18. #include <sys/types.h>
  19. #endif
  20. #ifdef HAVE_UNISTD_H
  21. #include <unistd.h>
  22. #endif
  23. #ifdef TOR_UNIT_TESTS
  24. #if !defined(HAVE_USLEEP) && defined(HAVE_SYS_SELECT_H)
  25. /* as fallback implementation for tor_sleep_msec */
  26. #include <sys/select.h>
  27. #endif
  28. #endif
  29. #ifdef __APPLE__
  30. #include <mach/mach_time.h>
  31. #endif
  32. #include "torlog.h"
  33. #include "util.h"
  34. #include "container.h"
  35. #ifndef HAVE_GETTIMEOFDAY
  36. #ifdef HAVE_FTIME
  37. #include <sys/timeb.h>
  38. #endif
  39. #endif
  40. #ifdef TOR_UNIT_TESTS
  41. /** Delay for <b>msec</b> milliseconds. Only used in tests. */
  42. void
  43. tor_sleep_msec(int msec)
  44. {
  45. #ifdef _WIN32
  46. Sleep(msec);
  47. #elif defined(HAVE_USLEEP)
  48. sleep(msec / 1000);
  49. /* Some usleep()s hate sleeping more than 1 sec */
  50. usleep((msec % 1000) * 1000);
  51. #elif defined(HAVE_SYS_SELECT_H)
  52. struct timeval tv = { msec / 1000, (msec % 1000) * 1000};
  53. select(0, NULL, NULL, NULL, &tv);
  54. #else
  55. sleep(CEIL_DIV(msec, 1000));
  56. #endif
  57. }
  58. #endif
  59. /** Set *timeval to the current time of day. On error, log and terminate.
  60. * (Same as gettimeofday(timeval,NULL), but never returns -1.)
  61. */
  62. void
  63. tor_gettimeofday(struct timeval *timeval)
  64. {
  65. #ifdef _WIN32
  66. /* Epoch bias copied from perl: number of units between windows epoch and
  67. * Unix epoch. */
  68. #define EPOCH_BIAS U64_LITERAL(116444736000000000)
  69. #define UNITS_PER_SEC U64_LITERAL(10000000)
  70. #define USEC_PER_SEC U64_LITERAL(1000000)
  71. #define UNITS_PER_USEC U64_LITERAL(10)
  72. union {
  73. uint64_t ft_64;
  74. FILETIME ft_ft;
  75. } ft;
  76. /* number of 100-nsec units since Jan 1, 1601 */
  77. GetSystemTimeAsFileTime(&ft.ft_ft);
  78. if (ft.ft_64 < EPOCH_BIAS) {
  79. /* LCOV_EXCL_START */
  80. log_err(LD_GENERAL,"System time is before 1970; failing.");
  81. exit(1);
  82. /* LCOV_EXCL_STOP */
  83. }
  84. ft.ft_64 -= EPOCH_BIAS;
  85. timeval->tv_sec = (unsigned) (ft.ft_64 / UNITS_PER_SEC);
  86. timeval->tv_usec = (unsigned) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
  87. #elif defined(HAVE_GETTIMEOFDAY)
  88. if (gettimeofday(timeval, NULL)) {
  89. /* LCOV_EXCL_START */
  90. log_err(LD_GENERAL,"gettimeofday failed.");
  91. /* If gettimeofday dies, we have either given a bad timezone (we didn't),
  92. or segfaulted.*/
  93. exit(1);
  94. /* LCOV_EXCL_STOP */
  95. }
  96. #elif defined(HAVE_FTIME)
  97. struct timeb tb;
  98. ftime(&tb);
  99. timeval->tv_sec = tb.time;
  100. timeval->tv_usec = tb.millitm * 1000;
  101. #else
  102. #error "No way to get time."
  103. #endif
  104. return;
  105. }
  106. #define ONE_MILLION ((int64_t) (1000 * 1000))
  107. #define ONE_BILLION ((int64_t) (1000 * 1000 * 1000))
  108. /** True iff monotime_init has been called. */
  109. static int monotime_initialized = 0;
  110. static monotime_t initialized_at;
  111. #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
  112. static monotime_coarse_t initialized_at_coarse;
  113. #endif
  114. #ifdef TOR_UNIT_TESTS
  115. /** True if we are running unit tests and overriding the current monotonic
  116. * time. Note that mocked monotonic time might not be monotonic.
  117. */
  118. static int monotime_mocking_enabled = 0;
  119. static monotime_t initialized_at_saved;
  120. static int64_t mock_time_nsec = 0;
  121. #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
  122. static int64_t mock_time_nsec_coarse = 0;
  123. static monotime_coarse_t initialized_at_coarse_saved;
  124. #endif
  125. void
  126. monotime_enable_test_mocking(void)
  127. {
  128. if (BUG(monotime_initialized == 0)) {
  129. monotime_init();
  130. }
  131. tor_assert_nonfatal(monotime_mocking_enabled == 0);
  132. monotime_mocking_enabled = 1;
  133. memcpy(&initialized_at_saved,
  134. &initialized_at, sizeof(monotime_t));
  135. memset(&initialized_at, 0, sizeof(monotime_t));
  136. #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
  137. memcpy(&initialized_at_coarse_saved,
  138. &initialized_at_coarse, sizeof(monotime_coarse_t));
  139. memset(&initialized_at_coarse, 0, sizeof(monotime_coarse_t));
  140. #endif
  141. }
  142. void
  143. monotime_disable_test_mocking(void)
  144. {
  145. tor_assert_nonfatal(monotime_mocking_enabled == 1);
  146. monotime_mocking_enabled = 0;
  147. memcpy(&initialized_at,
  148. &initialized_at_saved, sizeof(monotime_t));
  149. #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
  150. memcpy(&initialized_at_coarse,
  151. &initialized_at_coarse_saved, sizeof(monotime_coarse_t));
  152. #endif
  153. }
  154. void
  155. monotime_set_mock_time_nsec(int64_t nsec)
  156. {
  157. tor_assert_nonfatal(monotime_mocking_enabled == 1);
  158. mock_time_nsec = nsec;
  159. }
  160. #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
  161. void
  162. monotime_coarse_set_mock_time_nsec(int64_t nsec)
  163. {
  164. tor_assert_nonfatal(monotime_mocking_enabled == 1);
  165. mock_time_nsec_coarse = nsec;
  166. }
  167. #endif
  168. #endif
  169. /* "ratchet" functions for monotonic time. */
  170. #if defined(_WIN32) || defined(TOR_UNIT_TESTS)
  171. /** Protected by lock: last value returned by monotime_get(). */
  172. static int64_t last_pctr = 0;
  173. /** Protected by lock: offset we must add to monotonic time values. */
  174. static int64_t pctr_offset = 0;
  175. /* If we are using GetTickCount(), how many times has it rolled over? */
  176. static uint32_t rollover_count = 0;
  177. /* If we are using GetTickCount(), what's the last value it returned? */
  178. static int64_t last_tick_count = 0;
  179. /** Helper for windows: Called with a sequence of times that are supposed
  180. * to be monotonic; increments them as appropriate so that they actually
  181. * _are_ monotonic.
  182. *
  183. * Caller must hold lock. */
  184. STATIC int64_t
  185. ratchet_performance_counter(int64_t count_raw)
  186. {
  187. /* must hold lock */
  188. const int64_t count_adjusted = count_raw + pctr_offset;
  189. if (PREDICT_UNLIKELY(count_adjusted < last_pctr)) {
  190. /* Monotonicity failed! Pretend no time elapsed. */
  191. pctr_offset = last_pctr - count_raw;
  192. return last_pctr;
  193. } else {
  194. last_pctr = count_adjusted;
  195. return count_adjusted;
  196. }
  197. }
  198. STATIC int64_t
  199. ratchet_coarse_performance_counter(const int64_t count_raw)
  200. {
  201. int64_t count = count_raw + (((int64_t)rollover_count) << 32);
  202. while (PREDICT_UNLIKELY(count < last_tick_count)) {
  203. ++rollover_count;
  204. count = count_raw + (((int64_t)rollover_count) << 32);
  205. }
  206. last_tick_count = count;
  207. return count;
  208. }
  209. #endif
  210. #if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS)
  211. static struct timeval last_timeofday = { 0, 0 };
  212. static struct timeval timeofday_offset = { 0, 0 };
  213. /** Helper for gettimeofday(): Called with a sequence of times that are
  214. * supposed to be monotonic; increments them as appropriate so that they
  215. * actually _are_ monotonic.
  216. *
  217. * Caller must hold lock. */
  218. STATIC void
  219. ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out)
  220. {
  221. /* must hold lock */
  222. timeradd(timeval_raw, &timeofday_offset, out);
  223. if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, <))) {
  224. /* time ran backwards. Instead, declare that no time occurred. */
  225. timersub(&last_timeofday, timeval_raw, &timeofday_offset);
  226. memcpy(out, &last_timeofday, sizeof(struct timeval));
  227. } else {
  228. memcpy(&last_timeofday, out, sizeof(struct timeval));
  229. }
  230. }
  231. #endif
  232. #ifdef TOR_UNIT_TESTS
  233. /** For testing: reset all the ratchets */
  234. void
  235. monotime_reset_ratchets_for_testing(void)
  236. {
  237. last_pctr = pctr_offset = last_tick_count = 0;
  238. rollover_count = 0;
  239. memset(&last_timeofday, 0, sizeof(struct timeval));
  240. memset(&timeofday_offset, 0, sizeof(struct timeval));
  241. }
  242. #endif
  243. #ifdef __APPLE__
  244. /** Initialized on startup: tells is how to convert from ticks to
  245. * nanoseconds.
  246. */
  247. static struct mach_timebase_info mach_time_info;
  248. static void
  249. monotime_init_internal(void)
  250. {
  251. tor_assert(!monotime_initialized);
  252. int r = mach_timebase_info(&mach_time_info);
  253. tor_assert(r == 0);
  254. tor_assert(mach_time_info.denom != 0);
  255. }
  256. /**
  257. * Set "out" to the most recent monotonic time value
  258. */
  259. void
  260. monotime_get(monotime_t *out)
  261. {
  262. #ifdef TOR_UNIT_TESTS
  263. if (monotime_mocking_enabled) {
  264. out->abstime_ = (mock_time_nsec * mach_time_info.denom)
  265. / mach_time_info.numer;
  266. return;
  267. }
  268. #endif
  269. out->abstime_ = mach_absolute_time();
  270. }
  271. /**
  272. * Return the number of nanoseconds between <b>start</b> and <b>end</b>.
  273. */
  274. int64_t
  275. monotime_diff_nsec(const monotime_t *start,
  276. const monotime_t *end)
  277. {
  278. if (BUG(mach_time_info.denom == 0)) {
  279. monotime_init();
  280. }
  281. const int64_t diff_ticks = end->abstime_ - start->abstime_;
  282. const int64_t diff_nsec =
  283. (diff_ticks * mach_time_info.numer) / mach_time_info.denom;
  284. return diff_nsec;
  285. }
  286. /* end of "__APPLE__" */
  287. #elif defined(HAVE_CLOCK_GETTIME)
  288. static void
  289. monotime_init_internal(void)
  290. {
  291. /* no action needed. */
  292. }
  293. void
  294. monotime_get(monotime_t *out)
  295. {
  296. #ifdef TOR_UNIT_TESTS
  297. if (monotime_mocking_enabled) {
  298. out->ts_.tv_sec = (time_t) (mock_time_nsec / ONE_BILLION);
  299. out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION);
  300. return;
  301. }
  302. #endif
  303. int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
  304. tor_assert(r == 0);
  305. }
  306. #ifdef CLOCK_MONOTONIC_COARSE
  307. void
  308. monotime_coarse_get(monotime_coarse_t *out)
  309. {
  310. #ifdef TOR_UNIT_TESTS
  311. if (monotime_mocking_enabled) {
  312. out->ts_.tv_sec = mock_time_nsec_coarse / ONE_BILLION;
  313. out->ts_.tv_nsec = mock_time_nsec_coarse % ONE_BILLION;
  314. return;
  315. }
  316. #endif
  317. int r = clock_gettime(CLOCK_MONOTONIC_COARSE, &out->ts_);
  318. tor_assert(r == 0);
  319. }
  320. #endif
  321. int64_t
  322. monotime_diff_nsec(const monotime_t *start,
  323. const monotime_t *end)
  324. {
  325. const int64_t diff_sec = end->ts_.tv_sec - start->ts_.tv_sec;
  326. const int64_t diff_nsec = diff_sec * ONE_BILLION +
  327. (end->ts_.tv_nsec - start->ts_.tv_nsec);
  328. return diff_nsec;
  329. }
  330. /* end of "HAVE_CLOCK_GETTIME" */
  331. #elif defined (_WIN32)
  332. /** Result of QueryPerformanceFrequency, as an int64_t. */
  333. static int64_t ticks_per_second = 0;
  334. /** Lock to protect last_pctr and pctr_offset */
  335. static CRITICAL_SECTION monotime_lock;
  336. /** Lock to protect rollover_count and last_tick_count */
  337. static CRITICAL_SECTION monotime_coarse_lock;
  338. typedef ULONGLONG (WINAPI *GetTickCount64_fn_t)(void);
  339. static GetTickCount64_fn_t GetTickCount64_fn = NULL;
  340. static void
  341. monotime_init_internal(void)
  342. {
  343. tor_assert(!monotime_initialized);
  344. BOOL ok = InitializeCriticalSectionAndSpinCount(&monotime_lock, 200);
  345. tor_assert(ok);
  346. ok = InitializeCriticalSectionAndSpinCount(&monotime_coarse_lock, 200);
  347. tor_assert(ok);
  348. LARGE_INTEGER li;
  349. ok = QueryPerformanceFrequency(&li);
  350. tor_assert(ok);
  351. tor_assert(li.QuadPart);
  352. ticks_per_second = li.QuadPart;
  353. last_pctr = 0;
  354. pctr_offset = 0;
  355. HANDLE h = load_windows_system_library(TEXT("kernel32.dll"));
  356. if (h) {
  357. GetTickCount64_fn = (GetTickCount64_fn_t)
  358. GetProcAddress(h, "GetTickCount64");
  359. }
  360. // FreeLibrary(h) ?
  361. }
  362. void
  363. monotime_get(monotime_t *out)
  364. {
  365. if (BUG(monotime_initialized == 0)) {
  366. monotime_init();
  367. }
  368. #ifdef TOR_UNIT_TESTS
  369. if (monotime_mocking_enabled) {
  370. out->pcount_ = (mock_time_nsec * ticks_per_second) / ONE_BILLION;
  371. return;
  372. }
  373. #endif
  374. /* Alas, QueryPerformanceCounter is not always monotonic: see bug list at
  375. https://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter
  376. */
  377. EnterCriticalSection(&monotime_lock);
  378. LARGE_INTEGER res;
  379. BOOL ok = QueryPerformanceCounter(&res);
  380. tor_assert(ok);
  381. const int64_t count_raw = res.QuadPart;
  382. out->pcount_ = ratchet_performance_counter(count_raw);
  383. LeaveCriticalSection(&monotime_lock);
  384. }
  385. void
  386. monotime_coarse_get(monotime_coarse_t *out)
  387. {
  388. #ifdef TOR_UNIT_TESTS
  389. if (monotime_mocking_enabled) {
  390. out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
  391. return;
  392. }
  393. #endif
  394. if (GetTickCount64_fn) {
  395. out->tick_count_ = (int64_t)GetTickCount64_fn();
  396. } else {
  397. EnterCriticalSection(&monotime_coarse_lock);
  398. DWORD tick = GetTickCount();
  399. out->tick_count_ = ratchet_coarse_performance_counter(tick);
  400. LeaveCriticalSection(&monotime_coarse_lock);
  401. }
  402. }
  403. int64_t
  404. monotime_diff_nsec(const monotime_t *start,
  405. const monotime_t *end)
  406. {
  407. if (BUG(monotime_initialized == 0)) {
  408. monotime_init();
  409. }
  410. const int64_t diff_ticks = end->pcount_ - start->pcount_;
  411. return (diff_ticks * ONE_BILLION) / ticks_per_second;
  412. }
  413. int64_t
  414. monotime_coarse_diff_msec(const monotime_coarse_t *start,
  415. const monotime_coarse_t *end)
  416. {
  417. const int64_t diff_ticks = end->tick_count_ - start->tick_count_;
  418. return diff_ticks;
  419. }
  420. int64_t
  421. monotime_coarse_diff_usec(const monotime_coarse_t *start,
  422. const monotime_coarse_t *end)
  423. {
  424. return monotime_coarse_diff_msec(start, end) * 1000;
  425. }
  426. int64_t
  427. monotime_coarse_diff_nsec(const monotime_coarse_t *start,
  428. const monotime_coarse_t *end)
  429. {
  430. return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
  431. }
  432. /* end of "_WIN32" */
  433. #elif defined(MONOTIME_USING_GETTIMEOFDAY)
  434. static tor_mutex_t monotime_lock;
  435. /** Initialize the monotonic timer subsystem. */
  436. static void
  437. monotime_init_internal(void)
  438. {
  439. tor_assert(!monotime_initialized);
  440. tor_mutex_init(&monotime_lock);
  441. }
  442. void
  443. monotime_get(monotime_t *out)
  444. {
  445. if (BUG(monotime_initialized == 0)) {
  446. monotime_init();
  447. }
  448. tor_mutex_acquire(&monotime_lock);
  449. struct timeval timeval_raw;
  450. tor_gettimeofday(&timeval_raw);
  451. ratchet_timeval(&timeval_raw, &out->tv_);
  452. tor_mutex_release(&monotime_lock);
  453. }
  454. int64_t
  455. monotime_diff_nsec(const monotime_t *start,
  456. const monotime_t *end)
  457. {
  458. struct timeval diff;
  459. timersub(&end->tv_, &start->tv_, &diff);
  460. return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
  461. }
  462. /* end of "MONOTIME_USING_GETTIMEOFDAY" */
  463. #else
  464. #error "No way to implement monotonic timers."
  465. #endif
  466. /**
  467. * Initialize the monotonic timer subsystem. Must be called before any
  468. * monotonic timer functions. This function is idempotent.
  469. */
  470. void
  471. monotime_init(void)
  472. {
  473. if (!monotime_initialized) {
  474. monotime_init_internal();
  475. monotime_get(&initialized_at);
  476. #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
  477. monotime_coarse_get(&initialized_at_coarse);
  478. #endif
  479. monotime_initialized = 1;
  480. }
  481. }
  482. int64_t
  483. monotime_diff_usec(const monotime_t *start,
  484. const monotime_t *end)
  485. {
  486. const int64_t nsec = monotime_diff_nsec(start, end);
  487. return CEIL_DIV(nsec, 1000);
  488. }
  489. int64_t
  490. monotime_diff_msec(const monotime_t *start,
  491. const monotime_t *end)
  492. {
  493. const int64_t nsec = monotime_diff_nsec(start, end);
  494. return CEIL_DIV(nsec, ONE_MILLION);
  495. }
  496. uint64_t
  497. monotime_absolute_nsec(void)
  498. {
  499. monotime_t now;
  500. if (BUG(monotime_initialized == 0)) {
  501. monotime_init();
  502. }
  503. monotime_get(&now);
  504. return monotime_diff_nsec(&initialized_at, &now);
  505. }
  506. uint64_t
  507. monotime_absolute_usec(void)
  508. {
  509. return monotime_absolute_nsec() / 1000;
  510. }
  511. uint64_t
  512. monotime_absolute_msec(void)
  513. {
  514. return monotime_absolute_nsec() / ONE_MILLION;
  515. }
  516. #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
  517. uint64_t
  518. monotime_coarse_absolute_nsec(void)
  519. {
  520. if (BUG(monotime_initialized == 0)) {
  521. monotime_init();
  522. }
  523. monotime_coarse_t now;
  524. monotime_coarse_get(&now);
  525. return monotime_coarse_diff_nsec(&initialized_at_coarse, &now);
  526. }
  527. uint64_t
  528. monotime_coarse_absolute_usec(void)
  529. {
  530. return monotime_coarse_absolute_nsec() / 1000;
  531. }
  532. uint64_t
  533. monotime_coarse_absolute_msec(void)
  534. {
  535. return monotime_coarse_absolute_nsec() / ONE_MILLION;
  536. }
  537. #endif