evutil_time.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. /*
  2. * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * 3. The name of the author may not be used to endorse or promote products
  13. * derived from this software without specific prior written permission.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  18. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  19. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  24. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include "event2/event-config.h"
  27. #include "evconfig-private.h"
  28. #ifdef _WIN32
  29. #include <winsock2.h>
  30. #define WIN32_LEAN_AND_MEAN
  31. #include <windows.h>
  32. #undef WIN32_LEAN_AND_MEAN
  33. #endif
  34. #include <sys/types.h>
  35. #ifdef EVENT__HAVE_STDLIB_H
  36. #include <stdlib.h>
  37. #endif
  38. #include <errno.h>
  39. #include <limits.h>
  40. #ifndef EVENT__HAVE_GETTIMEOFDAY
  41. #include <sys/timeb.h>
  42. #endif
  43. #if !defined(EVENT__HAVE_NANOSLEEP) && !defined(EVENT__HAVE_USLEEP) && \
  44. !defined(_WIN32)
  45. #include <sys/select.h>
  46. #endif
  47. #include <time.h>
  48. #include <sys/stat.h>
  49. #include <string.h>
  50. /** evutil_usleep_() */
  51. #if defined(_WIN32)
  52. #elif defined(EVENT__HAVE_NANOSLEEP)
  53. #elif defined(EVENT__HAVE_USLEEP)
  54. #include <unistd.h>
  55. #endif
  56. #include "event2/util.h"
  57. #include "util-internal.h"
  58. #include "log-internal.h"
  59. #include "mm-internal.h"
  60. #ifndef EVENT__HAVE_GETTIMEOFDAY
  61. /* No gettimeofday; this must be windows. */
  62. typedef void (WINAPI *GetSystemTimePreciseAsFileTime_fn_t) (LPFILETIME);
  63. int
  64. evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
  65. {
  66. #ifdef _MSC_VER
  67. #define U64_LITERAL(n) n##ui64
  68. #else
  69. #define U64_LITERAL(n) n##llu
  70. #endif
  71. /* Conversion logic taken from Tor, which in turn took it
  72. * from Perl. GetSystemTimeAsFileTime returns its value as
  73. * an unaligned (!) 64-bit value containing the number of
  74. * 100-nanosecond intervals since 1 January 1601 UTC. */
  75. #define EPOCH_BIAS U64_LITERAL(116444736000000000)
  76. #define UNITS_PER_SEC U64_LITERAL(10000000)
  77. #define USEC_PER_SEC U64_LITERAL(1000000)
  78. #define UNITS_PER_USEC U64_LITERAL(10)
  79. union {
  80. FILETIME ft_ft;
  81. ev_uint64_t ft_64;
  82. } ft;
  83. if (tv == NULL)
  84. return -1;
  85. static GetSystemTimePreciseAsFileTime_fn_t GetSystemTimePreciseAsFileTime_fn = NULL;
  86. static int check_precise = 1;
  87. if (EVUTIL_UNLIKELY(check_precise)) {
  88. HMODULE h = evutil_load_windows_system_library_(TEXT("kernel32.dll"));
  89. if (h != NULL)
  90. GetSystemTimePreciseAsFileTime_fn =
  91. (GetSystemTimePreciseAsFileTime_fn_t)
  92. GetProcAddress(h, "GetSystemTimePreciseAsFileTime");
  93. check_precise = 0;
  94. }
  95. if (GetSystemTimePreciseAsFileTime_fn != NULL)
  96. GetSystemTimePreciseAsFileTime_fn(&ft.ft_ft);
  97. else
  98. GetSystemTimeAsFileTime(&ft.ft_ft);
  99. if (EVUTIL_UNLIKELY(ft.ft_64 < EPOCH_BIAS)) {
  100. /* Time before the unix epoch. */
  101. return -1;
  102. }
  103. ft.ft_64 -= EPOCH_BIAS;
  104. tv->tv_sec = (long) (ft.ft_64 / UNITS_PER_SEC);
  105. tv->tv_usec = (long) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
  106. return 0;
  107. }
  108. #endif
  109. #define MAX_SECONDS_IN_MSEC_LONG \
  110. (((LONG_MAX) - 999) / 1000)
  111. long
  112. evutil_tv_to_msec_(const struct timeval *tv)
  113. {
  114. if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG)
  115. return -1;
  116. return (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000);
  117. }
  118. /*
  119. Replacement for usleep on platforms that don't have one. Not guaranteed to
  120. be any more finegrained than 1 msec.
  121. */
  122. void
  123. evutil_usleep_(const struct timeval *tv)
  124. {
  125. if (!tv)
  126. return;
  127. #if defined(_WIN32)
  128. {
  129. __int64 usec;
  130. LARGE_INTEGER li;
  131. HANDLE timer;
  132. usec = tv->tv_sec * 1000000LL + tv->tv_usec;
  133. if (!usec)
  134. return;
  135. li.QuadPart = -10LL * usec;
  136. timer = CreateWaitableTimer(NULL, TRUE, NULL);
  137. if (!timer)
  138. return;
  139. SetWaitableTimer(timer, &li, 0, NULL, NULL, 0);
  140. WaitForSingleObject(timer, INFINITE);
  141. CloseHandle(timer);
  142. }
  143. #elif defined(EVENT__HAVE_NANOSLEEP)
  144. {
  145. struct timespec ts;
  146. ts.tv_sec = tv->tv_sec;
  147. ts.tv_nsec = tv->tv_usec*1000;
  148. nanosleep(&ts, NULL);
  149. }
  150. #elif defined(EVENT__HAVE_USLEEP)
  151. /* Some systems don't like to usleep more than 999999 usec */
  152. sleep(tv->tv_sec);
  153. usleep(tv->tv_usec);
  154. #else
  155. {
  156. struct timeval tv2 = *tv;
  157. select(0, NULL, NULL, NULL, &tv2);
  158. }
  159. #endif
  160. }
  161. int
  162. evutil_date_rfc1123(char *date, const size_t datelen, const struct tm *tm)
  163. {
  164. static const char *DAYS[] =
  165. { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
  166. static const char *MONTHS[] =
  167. { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  168. time_t t = time(NULL);
  169. #if defined(EVENT__HAVE__GMTIME64_S) || !defined(_WIN32)
  170. struct tm sys;
  171. #endif
  172. /* If `tm` is null, set system's current time. */
  173. if (tm == NULL) {
  174. #if !defined(_WIN32)
  175. gmtime_r(&t, &sys);
  176. tm = &sys;
  177. /** detect _gmtime64()/_gmtime64_s() */
  178. #elif defined(EVENT__HAVE__GMTIME64_S)
  179. errno_t err;
  180. err = _gmtime64_s(&sys, &t);
  181. if (err) {
  182. event_errx(1, "Invalid argument to _gmtime64_s");
  183. } else {
  184. tm = &sys;
  185. }
  186. #elif defined(EVENT__HAVE__GMTIME64)
  187. tm = _gmtime64(&t);
  188. #else
  189. tm = gmtime(&t);
  190. #endif
  191. }
  192. return evutil_snprintf(
  193. date, datelen, "%s, %02d %s %4d %02d:%02d:%02d GMT",
  194. DAYS[tm->tm_wday], tm->tm_mday, MONTHS[tm->tm_mon],
  195. 1900 + tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec);
  196. }
  197. /*
  198. This function assumes it's called repeatedly with a
  199. not-actually-so-monotonic time source whose outputs are in 'tv'. It
  200. implements a trivial ratcheting mechanism so that the values never go
  201. backwards.
  202. */
  203. static void
  204. adjust_monotonic_time(struct evutil_monotonic_timer *base,
  205. struct timeval *tv)
  206. {
  207. evutil_timeradd(tv, &base->adjust_monotonic_clock, tv);
  208. if (evutil_timercmp(tv, &base->last_time, <)) {
  209. /* Guess it wasn't monotonic after all. */
  210. struct timeval adjust;
  211. evutil_timersub(&base->last_time, tv, &adjust);
  212. evutil_timeradd(&adjust, &base->adjust_monotonic_clock,
  213. &base->adjust_monotonic_clock);
  214. *tv = base->last_time;
  215. }
  216. base->last_time = *tv;
  217. }
  218. /*
  219. Allocate a new struct evutil_monotonic_timer
  220. */
  221. struct evutil_monotonic_timer *
  222. evutil_monotonic_timer_new(void)
  223. {
  224. struct evutil_monotonic_timer *p = NULL;
  225. p = mm_malloc(sizeof(*p));
  226. if (!p) goto done;
  227. memset(p, 0, sizeof(*p));
  228. done:
  229. return p;
  230. }
  231. /*
  232. Free a struct evutil_monotonic_timer
  233. */
  234. void
  235. evutil_monotonic_timer_free(struct evutil_monotonic_timer *timer)
  236. {
  237. if (timer) {
  238. mm_free(timer);
  239. }
  240. }
  241. /*
  242. Set up a struct evutil_monotonic_timer for initial use
  243. */
  244. int
  245. evutil_configure_monotonic_time(struct evutil_monotonic_timer *timer,
  246. int flags)
  247. {
  248. return evutil_configure_monotonic_time_(timer, flags);
  249. }
  250. /*
  251. Query the current monotonic time
  252. */
  253. int
  254. evutil_gettime_monotonic(struct evutil_monotonic_timer *timer,
  255. struct timeval *tp)
  256. {
  257. return evutil_gettime_monotonic_(timer, tp);
  258. }
  259. #if defined(HAVE_POSIX_MONOTONIC)
  260. /* =====
  261. The POSIX clock_gettime() interface provides a few ways to get at a
  262. monotonic clock. CLOCK_MONOTONIC is most widely supported. Linux also
  263. provides a CLOCK_MONOTONIC_COARSE with accuracy of about 1-4 msec.
  264. On all platforms I'm aware of, CLOCK_MONOTONIC really is monotonic.
  265. Platforms don't agree about whether it should jump on a sleep/resume.
  266. */
  267. int
  268. evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
  269. int flags)
  270. {
  271. /* CLOCK_MONOTONIC exists on FreeBSD, Linux, and Solaris. You need to
  272. * check for it at runtime, because some older kernel versions won't
  273. * have it working. */
  274. #ifdef CLOCK_MONOTONIC_COARSE
  275. const int precise = flags & EV_MONOT_PRECISE;
  276. #endif
  277. const int fallback = flags & EV_MONOT_FALLBACK;
  278. struct timespec ts;
  279. #ifdef CLOCK_MONOTONIC_COARSE
  280. if (CLOCK_MONOTONIC_COARSE < 0) {
  281. /* Technically speaking, nothing keeps CLOCK_* from being
  282. * negative (as far as I know). This check and the one below
  283. * make sure that it's safe for us to use -1 as an "unset"
  284. * value. */
  285. event_errx(1,"I didn't expect CLOCK_MONOTONIC_COARSE to be < 0");
  286. }
  287. if (! precise && ! fallback) {
  288. if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) == 0) {
  289. base->monotonic_clock = CLOCK_MONOTONIC_COARSE;
  290. return 0;
  291. }
  292. }
  293. #endif
  294. if (!fallback && clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
  295. base->monotonic_clock = CLOCK_MONOTONIC;
  296. return 0;
  297. }
  298. if (CLOCK_MONOTONIC < 0) {
  299. event_errx(1,"I didn't expect CLOCK_MONOTONIC to be < 0");
  300. }
  301. base->monotonic_clock = -1;
  302. return 0;
  303. }
  304. int
  305. evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
  306. struct timeval *tp)
  307. {
  308. struct timespec ts;
  309. if (base->monotonic_clock < 0) {
  310. if (evutil_gettimeofday(tp, NULL) < 0)
  311. return -1;
  312. adjust_monotonic_time(base, tp);
  313. return 0;
  314. }
  315. if (clock_gettime(base->monotonic_clock, &ts) == -1)
  316. return -1;
  317. tp->tv_sec = ts.tv_sec;
  318. tp->tv_usec = ts.tv_nsec / 1000;
  319. return 0;
  320. }
  321. #endif
  322. #if defined(HAVE_MACH_MONOTONIC)
  323. /* ======
  324. Apple is a little late to the POSIX party. And why not? Instead of
  325. clock_gettime(), they provide mach_absolute_time(). Its units are not
  326. fixed; we need to use mach_timebase_info() to get the right functions to
  327. convert its units into nanoseconds.
  328. To all appearances, mach_absolute_time() seems to be honest-to-goodness
  329. monotonic. Whether it stops during sleep or not is unspecified in
  330. principle, and dependent on CPU architecture in practice.
  331. */
  332. int
  333. evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
  334. int flags)
  335. {
  336. const int fallback = flags & EV_MONOT_FALLBACK;
  337. struct mach_timebase_info mi;
  338. memset(base, 0, sizeof(*base));
  339. /* OSX has mach_absolute_time() */
  340. if (!fallback &&
  341. mach_timebase_info(&mi) == 0 &&
  342. mach_absolute_time() != 0) {
  343. /* mach_timebase_info tells us how to convert
  344. * mach_absolute_time() into nanoseconds, but we
  345. * want to use microseconds instead. */
  346. mi.denom *= 1000;
  347. memcpy(&base->mach_timebase_units, &mi, sizeof(mi));
  348. } else {
  349. base->mach_timebase_units.numer = 0;
  350. }
  351. return 0;
  352. }
  353. int
  354. evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
  355. struct timeval *tp)
  356. {
  357. ev_uint64_t abstime, usec;
  358. if (base->mach_timebase_units.numer == 0) {
  359. if (evutil_gettimeofday(tp, NULL) < 0)
  360. return -1;
  361. adjust_monotonic_time(base, tp);
  362. return 0;
  363. }
  364. abstime = mach_absolute_time();
  365. usec = (abstime * base->mach_timebase_units.numer)
  366. / (base->mach_timebase_units.denom);
  367. tp->tv_sec = usec / 1000000;
  368. tp->tv_usec = usec % 1000000;
  369. return 0;
  370. }
  371. #endif
  372. #if defined(HAVE_WIN32_MONOTONIC)
  373. /* =====
  374. Turn we now to Windows. Want monontonic time on Windows?
  375. Windows has QueryPerformanceCounter(), which gives time most high-
  376. resolution time. It's a pity it's not so monotonic in practice; it's
  377. also got some fun bugs, especially: with older Windowses, under
  378. virtualizations, with funny hardware, on multiprocessor systems, and so
  379. on. PEP418 [1] has a nice roundup of the issues here.
  380. There's GetTickCount64() on Vista and later, which gives a number of 1-msec
  381. ticks since startup. The accuracy here might be as bad as 10-20 msec, I
  382. hear. There's an undocumented function (NtSetTimerResolution) that
  383. allegedly increases the accuracy. Good luck!
  384. There's also GetTickCount(), which is only 32 bits, but seems to be
  385. supported on pre-Vista versions of Windows. Apparently, you can coax
  386. another 14 bits out of it, giving you 2231 years before rollover.
  387. The less said about timeGetTime() the better.
  388. "We don't care. We don't have to. We're the Phone Company."
  389. -- Lily Tomlin, SNL
  390. Our strategy, if precise timers are turned off, is to just use the best
  391. GetTickCount equivalent available. If we've been asked for precise timing,
  392. then we mostly[2] assume that GetTickCount is monotonic, and correct
  393. GetPerformanceCounter to approximate it.
  394. [1] http://www.python.org/dev/peps/pep-0418
  395. [2] Of course, we feed the Windows stuff into adjust_monotonic_time()
  396. anyway, just in case it isn't.
  397. */
  398. /*
  399. Parts of our logic in the win32 timer code here are closely based on
  400. BitTorrent's libUTP library. That code is subject to the following
  401. license:
  402. Copyright (c) 2010 BitTorrent, Inc.
  403. Permission is hereby granted, free of charge, to any person obtaining a
  404. copy of this software and associated documentation files (the
  405. "Software"), to deal in the Software without restriction, including
  406. without limitation the rights to use, copy, modify, merge, publish,
  407. distribute, sublicense, and/or sell copies of the Software, and to
  408. permit persons to whom the Software is furnished to do so, subject to
  409. the following conditions:
  410. The above copyright notice and this permission notice shall be included
  411. in all copies or substantial portions of the Software.
  412. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  413. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  414. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  415. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  416. LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  417. OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  418. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  419. */
  420. static ev_uint64_t
  421. evutil_GetTickCount_(struct evutil_monotonic_timer *base)
  422. {
  423. if (base->GetTickCount64_fn) {
  424. /* Let's just use GetTickCount64 if we can. */
  425. return base->GetTickCount64_fn();
  426. } else if (base->GetTickCount_fn) {
  427. /* Greg Hazel assures me that this works, that BitTorrent has
  428. * done it for years, and this it won't turn around and
  429. * bite us. He says they found it on some game programmers'
  430. * forum some time around 2007.
  431. */
  432. ev_uint64_t v = base->GetTickCount_fn();
  433. return (DWORD)v | ((v >> 18) & 0xFFFFFFFF00000000);
  434. } else {
  435. /* Here's the fallback implementation. We have to use
  436. * GetTickCount() with its given signature, so we only get
  437. * 32 bits worth of milliseconds, which will roll ove every
  438. * 49 days or so. */
  439. DWORD ticks = GetTickCount();
  440. if (ticks < base->last_tick_count) {
  441. base->adjust_tick_count += ((ev_uint64_t)1) << 32;
  442. }
  443. base->last_tick_count = ticks;
  444. return ticks + base->adjust_tick_count;
  445. }
  446. }
  447. int
  448. evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
  449. int flags)
  450. {
  451. const int precise = flags & EV_MONOT_PRECISE;
  452. const int fallback = flags & EV_MONOT_FALLBACK;
  453. HANDLE h;
  454. memset(base, 0, sizeof(*base));
  455. h = evutil_load_windows_system_library_(TEXT("kernel32.dll"));
  456. if (h != NULL && !fallback) {
  457. base->GetTickCount64_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount64");
  458. base->GetTickCount_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount");
  459. }
  460. base->first_tick = base->last_tick_count = evutil_GetTickCount_(base);
  461. if (precise && !fallback) {
  462. LARGE_INTEGER freq;
  463. if (QueryPerformanceFrequency(&freq)) {
  464. LARGE_INTEGER counter;
  465. QueryPerformanceCounter(&counter);
  466. base->first_counter = counter.QuadPart;
  467. base->usec_per_count = 1.0e6 / freq.QuadPart;
  468. base->use_performance_counter = 1;
  469. }
  470. }
  471. return 0;
  472. }
  473. static inline ev_int64_t
  474. abs64(ev_int64_t i)
  475. {
  476. return i < 0 ? -i : i;
  477. }
  478. int
  479. evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
  480. struct timeval *tp)
  481. {
  482. ev_uint64_t ticks = evutil_GetTickCount_(base);
  483. if (base->use_performance_counter) {
  484. /* Here's a trick we took from BitTorrent's libutp, at Greg
  485. * Hazel's recommendation. We use QueryPerformanceCounter for
  486. * our high-resolution timer, but use GetTickCount*() to keep
  487. * it sane, and adjust_monotonic_time() to keep it monotonic.
  488. */
  489. LARGE_INTEGER counter;
  490. ev_int64_t counter_elapsed, counter_usec_elapsed, ticks_elapsed;
  491. QueryPerformanceCounter(&counter);
  492. counter_elapsed = (ev_int64_t)
  493. (counter.QuadPart - base->first_counter);
  494. ticks_elapsed = ticks - base->first_tick;
  495. /* TODO: This may upset VC6. If you need this to work with
  496. * VC6, please supply an appropriate patch. */
  497. counter_usec_elapsed = (ev_int64_t)
  498. (counter_elapsed * base->usec_per_count);
  499. if (abs64(ticks_elapsed*1000 - counter_usec_elapsed) > 1000000) {
  500. /* It appears that the QueryPerformanceCounter()
  501. * result is more than 1 second away from
  502. * GetTickCount() result. Let's adjust it to be as
  503. * accurate as we can; adjust_monotnonic_time() below
  504. * will keep it monotonic. */
  505. counter_usec_elapsed = ticks_elapsed * 1000;
  506. base->first_counter = (ev_uint64_t) (counter.QuadPart - counter_usec_elapsed / base->usec_per_count);
  507. }
  508. tp->tv_sec = (time_t) (counter_usec_elapsed / 1000000);
  509. tp->tv_usec = counter_usec_elapsed % 1000000;
  510. } else {
  511. /* We're just using GetTickCount(). */
  512. tp->tv_sec = (time_t) (ticks / 1000);
  513. tp->tv_usec = (ticks % 1000) * 1000;
  514. }
  515. adjust_monotonic_time(base, tp);
  516. return 0;
  517. }
  518. #endif
  519. #if defined(HAVE_FALLBACK_MONOTONIC)
  520. /* =====
  521. And if none of the other options work, let's just use gettimeofday(), and
  522. ratchet it forward so that it acts like a monotonic timer, whether it
  523. wants to or not.
  524. */
  525. int
  526. evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
  527. int precise)
  528. {
  529. memset(base, 0, sizeof(*base));
  530. return 0;
  531. }
  532. int
  533. evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
  534. struct timeval *tp)
  535. {
  536. if (evutil_gettimeofday(tp, NULL) < 0)
  537. return -1;
  538. adjust_monotonic_time(base, tp);
  539. return 0;
  540. }
  541. #endif