compat_time.c 12 KB

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