1275970Scy/* 2275970Scy * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 3275970Scy * 4275970Scy * Redistribution and use in source and binary forms, with or without 5275970Scy * modification, are permitted provided that the following conditions 6275970Scy * are met: 7275970Scy * 1. Redistributions of source code must retain the above copyright 8275970Scy * notice, this list of conditions and the following disclaimer. 9275970Scy * 2. Redistributions in binary form must reproduce the above copyright 10275970Scy * notice, this list of conditions and the following disclaimer in the 11275970Scy * documentation and/or other materials provided with the distribution. 12275970Scy * 3. The name of the author may not be used to endorse or promote products 13275970Scy * derived from this software without specific prior written permission. 14275970Scy * 15275970Scy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16275970Scy * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17275970Scy * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18275970Scy * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19275970Scy * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20275970Scy * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21275970Scy * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22275970Scy * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23275970Scy * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24275970Scy * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25275970Scy */ 26275970Scy 27275970Scy#include "event2/event-config.h" 28275970Scy#include "evconfig-private.h" 29275970Scy 30275970Scy#ifdef _WIN32 31275970Scy#include <winsock2.h> 32275970Scy#define WIN32_LEAN_AND_MEAN 33275970Scy#include <windows.h> 34275970Scy#undef WIN32_LEAN_AND_MEAN 35275970Scy#endif 36275970Scy 37275970Scy#include <sys/types.h> 38275970Scy#ifdef EVENT__HAVE_STDLIB_H 39275970Scy#include <stdlib.h> 40275970Scy#endif 41275970Scy#include <errno.h> 42275970Scy#include <limits.h> 43275970Scy#ifndef EVENT__HAVE_GETTIMEOFDAY 44275970Scy#include <sys/timeb.h> 45275970Scy#endif 46275970Scy#if !defined(EVENT__HAVE_NANOSLEEP) && !defined(EVENT_HAVE_USLEEP) && \ 47275970Scy !defined(_WIN32) 48275970Scy#include <sys/select.h> 49275970Scy#endif 50275970Scy#include <time.h> 51275970Scy#include <sys/stat.h> 52275970Scy#include <string.h> 53275970Scy 54275970Scy#include "event2/util.h" 55275970Scy#include "util-internal.h" 56275970Scy#include "log-internal.h" 57285612Sdelphij#include "mm-internal.h" 58275970Scy 59275970Scy#ifndef EVENT__HAVE_GETTIMEOFDAY 60275970Scy/* No gettimeofday; this must be windows. */ 61275970Scyint 62275970Scyevutil_gettimeofday(struct timeval *tv, struct timezone *tz) 63275970Scy{ 64275970Scy#ifdef _MSC_VER 65275970Scy#define U64_LITERAL(n) n##ui64 66275970Scy#else 67275970Scy#define U64_LITERAL(n) n##llu 68275970Scy#endif 69275970Scy 70275970Scy /* Conversion logic taken from Tor, which in turn took it 71275970Scy * from Perl. GetSystemTimeAsFileTime returns its value as 72275970Scy * an unaligned (!) 64-bit value containing the number of 73275970Scy * 100-nanosecond intervals since 1 January 1601 UTC. */ 74275970Scy#define EPOCH_BIAS U64_LITERAL(116444736000000000) 75275970Scy#define UNITS_PER_SEC U64_LITERAL(10000000) 76275970Scy#define USEC_PER_SEC U64_LITERAL(1000000) 77275970Scy#define UNITS_PER_USEC U64_LITERAL(10) 78275970Scy union { 79275970Scy FILETIME ft_ft; 80275970Scy ev_uint64_t ft_64; 81275970Scy } ft; 82275970Scy 83275970Scy if (tv == NULL) 84275970Scy return -1; 85275970Scy 86275970Scy GetSystemTimeAsFileTime(&ft.ft_ft); 87275970Scy 88275970Scy if (EVUTIL_UNLIKELY(ft.ft_64 < EPOCH_BIAS)) { 89275970Scy /* Time before the unix epoch. */ 90275970Scy return -1; 91275970Scy } 92275970Scy ft.ft_64 -= EPOCH_BIAS; 93275970Scy tv->tv_sec = (long) (ft.ft_64 / UNITS_PER_SEC); 94275970Scy tv->tv_usec = (long) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC); 95275970Scy return 0; 96275970Scy} 97275970Scy#endif 98275970Scy 99275970Scy#define MAX_SECONDS_IN_MSEC_LONG \ 100275970Scy (((LONG_MAX) - 999) / 1000) 101275970Scy 102275970Scylong 103275970Scyevutil_tv_to_msec_(const struct timeval *tv) 104275970Scy{ 105275970Scy if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG) 106275970Scy return -1; 107275970Scy 108275970Scy return (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000); 109275970Scy} 110275970Scy 111275970Scy/* 112275970Scy Replacement for usleep on platforms that don't have one. Not guaranteed to 113275970Scy be any more finegrained than 1 msec. 114275970Scy */ 115275970Scyvoid 116275970Scyevutil_usleep_(const struct timeval *tv) 117275970Scy{ 118275970Scy if (!tv) 119275970Scy return; 120275970Scy#if defined(_WIN32) 121275970Scy { 122275970Scy long msec = evutil_tv_to_msec_(tv); 123275970Scy Sleep((DWORD)msec); 124275970Scy } 125275970Scy#elif defined(EVENT__HAVE_NANOSLEEP) 126275970Scy { 127275970Scy struct timespec ts; 128275970Scy ts.tv_sec = tv->tv_sec; 129275970Scy ts.tv_nsec = tv->tv_usec*1000; 130275970Scy nanosleep(&ts, NULL); 131275970Scy } 132275970Scy#elif defined(EVENT__HAVE_USLEEP) 133275970Scy /* Some systems don't like to usleep more than 999999 usec */ 134275970Scy sleep(tv->tv_sec); 135275970Scy usleep(tv->tv_usec); 136275970Scy#else 137275970Scy select(0, NULL, NULL, NULL, tv); 138275970Scy#endif 139275970Scy} 140275970Scy 141275970Scy/* 142275970Scy This function assumes it's called repeatedly with a 143275970Scy not-actually-so-monotonic time source whose outputs are in 'tv'. It 144275970Scy implements a trivial ratcheting mechanism so that the values never go 145275970Scy backwards. 146275970Scy */ 147275970Scystatic void 148275970Scyadjust_monotonic_time(struct evutil_monotonic_timer *base, 149275970Scy struct timeval *tv) 150275970Scy{ 151275970Scy evutil_timeradd(tv, &base->adjust_monotonic_clock, tv); 152275970Scy 153275970Scy if (evutil_timercmp(tv, &base->last_time, <)) { 154275970Scy /* Guess it wasn't monotonic after all. */ 155275970Scy struct timeval adjust; 156275970Scy evutil_timersub(&base->last_time, tv, &adjust); 157275970Scy evutil_timeradd(&adjust, &base->adjust_monotonic_clock, 158275970Scy &base->adjust_monotonic_clock); 159275970Scy *tv = base->last_time; 160275970Scy } 161275970Scy base->last_time = *tv; 162275970Scy} 163275970Scy 164285612Sdelphij/* 165285612Sdelphij Allocate a new struct evutil_monotonic_timer 166285612Sdelphij */ 167285612Sdelphijstruct evutil_monotonic_timer * 168285612Sdelphijevutil_monotonic_timer_new(void) 169285612Sdelphij{ 170285612Sdelphij struct evutil_monotonic_timer *p = NULL; 171285612Sdelphij 172285612Sdelphij p = mm_malloc(sizeof(*p)); 173285612Sdelphij if (!p) goto done; 174285612Sdelphij 175285612Sdelphij memset(p, 0, sizeof(*p)); 176285612Sdelphij 177285612Sdelphij done: 178285612Sdelphij return p; 179285612Sdelphij} 180285612Sdelphij 181285612Sdelphij/* 182285612Sdelphij Free a struct evutil_monotonic_timer 183285612Sdelphij */ 184285612Sdelphijvoid 185285612Sdelphijevutil_monotonic_timer_free(struct evutil_monotonic_timer *timer) 186285612Sdelphij{ 187285612Sdelphij if (timer) { 188285612Sdelphij mm_free(timer); 189285612Sdelphij } 190285612Sdelphij} 191285612Sdelphij 192285612Sdelphij/* 193285612Sdelphij Set up a struct evutil_monotonic_timer for initial use 194285612Sdelphij */ 195285612Sdelphijint 196285612Sdelphijevutil_configure_monotonic_time(struct evutil_monotonic_timer *timer, 197285612Sdelphij int flags) 198285612Sdelphij{ 199285612Sdelphij return evutil_configure_monotonic_time_(timer, flags); 200285612Sdelphij} 201285612Sdelphij 202285612Sdelphij/* 203285612Sdelphij Query the current monotonic time 204285612Sdelphij */ 205285612Sdelphijint 206285612Sdelphijevutil_gettime_monotonic(struct evutil_monotonic_timer *timer, 207285612Sdelphij struct timeval *tp) 208285612Sdelphij{ 209285612Sdelphij return evutil_gettime_monotonic_(timer, tp); 210285612Sdelphij} 211285612Sdelphij 212285612Sdelphij 213275970Scy#if defined(HAVE_POSIX_MONOTONIC) 214275970Scy/* ===== 215275970Scy The POSIX clock_gettime() interface provides a few ways to get at a 216275970Scy monotonic clock. CLOCK_MONOTONIC is most widely supported. Linux also 217275970Scy provides a CLOCK_MONOTONIC_COARSE with accuracy of about 1-4 msec. 218275970Scy 219275970Scy On all platforms I'm aware of, CLOCK_MONOTONIC really is monotonic. 220275970Scy Platforms don't agree about whether it should jump on a sleep/resume. 221275970Scy */ 222275970Scy 223275970Scyint 224275970Scyevutil_configure_monotonic_time_(struct evutil_monotonic_timer *base, 225275970Scy int flags) 226275970Scy{ 227275970Scy /* CLOCK_MONOTONIC exists on FreeBSD, Linux, and Solaris. You need to 228275970Scy * check for it at runtime, because some older kernel versions won't 229275970Scy * have it working. */ 230275970Scy#ifdef CLOCK_MONOTONIC_COARSE 231275970Scy const int precise = flags & EV_MONOT_PRECISE; 232275970Scy#endif 233275970Scy const int fallback = flags & EV_MONOT_FALLBACK; 234275970Scy struct timespec ts; 235275970Scy 236275970Scy#ifdef CLOCK_MONOTONIC_COARSE 237275970Scy if (CLOCK_MONOTONIC_COARSE < 0) { 238275970Scy /* Technically speaking, nothing keeps CLOCK_* from being 239275970Scy * negative (as far as I know). This check and the one below 240275970Scy * make sure that it's safe for us to use -1 as an "unset" 241275970Scy * value. */ 242275970Scy event_errx(1,"I didn't expect CLOCK_MONOTONIC_COARSE to be < 0"); 243275970Scy } 244275970Scy if (! precise && ! fallback) { 245275970Scy if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) == 0) { 246275970Scy base->monotonic_clock = CLOCK_MONOTONIC_COARSE; 247275970Scy return 0; 248275970Scy } 249275970Scy } 250275970Scy#endif 251275970Scy if (!fallback && clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { 252275970Scy base->monotonic_clock = CLOCK_MONOTONIC; 253275970Scy return 0; 254275970Scy } 255275970Scy 256275970Scy if (CLOCK_MONOTONIC < 0) { 257275970Scy event_errx(1,"I didn't expect CLOCK_MONOTONIC to be < 0"); 258275970Scy } 259275970Scy 260275970Scy base->monotonic_clock = -1; 261275970Scy return 0; 262275970Scy} 263275970Scy 264275970Scyint 265275970Scyevutil_gettime_monotonic_(struct evutil_monotonic_timer *base, 266275970Scy struct timeval *tp) 267275970Scy{ 268275970Scy struct timespec ts; 269275970Scy 270275970Scy if (base->monotonic_clock < 0) { 271275970Scy if (evutil_gettimeofday(tp, NULL) < 0) 272275970Scy return -1; 273275970Scy adjust_monotonic_time(base, tp); 274275970Scy return 0; 275275970Scy } 276275970Scy 277275970Scy if (clock_gettime(base->monotonic_clock, &ts) == -1) 278275970Scy return -1; 279275970Scy tp->tv_sec = ts.tv_sec; 280275970Scy tp->tv_usec = ts.tv_nsec / 1000; 281275970Scy 282275970Scy return 0; 283275970Scy} 284275970Scy#endif 285275970Scy 286275970Scy#if defined(HAVE_MACH_MONOTONIC) 287275970Scy/* ====== 288275970Scy Apple is a little late to the POSIX party. And why not? Instead of 289275970Scy clock_gettime(), they provide mach_absolute_time(). Its units are not 290275970Scy fixed; we need to use mach_timebase_info() to get the right functions to 291275970Scy convert its units into nanoseconds. 292275970Scy 293275970Scy To all appearances, mach_absolute_time() seems to be honest-to-goodness 294275970Scy monotonic. Whether it stops during sleep or not is unspecified in 295275970Scy principle, and dependent on CPU architecture in practice. 296275970Scy */ 297275970Scy 298275970Scyint 299275970Scyevutil_configure_monotonic_time_(struct evutil_monotonic_timer *base, 300275970Scy int flags) 301275970Scy{ 302275970Scy const int fallback = flags & EV_MONOT_FALLBACK; 303275970Scy struct mach_timebase_info mi; 304275970Scy memset(base, 0, sizeof(*base)); 305275970Scy /* OSX has mach_absolute_time() */ 306275970Scy if (!fallback && 307275970Scy mach_timebase_info(&mi) == 0 && 308275970Scy mach_absolute_time() != 0) { 309275970Scy /* mach_timebase_info tells us how to convert 310275970Scy * mach_absolute_time() into nanoseconds, but we 311275970Scy * want to use microseconds instead. */ 312275970Scy mi.denom *= 1000; 313275970Scy memcpy(&base->mach_timebase_units, &mi, sizeof(mi)); 314275970Scy } else { 315275970Scy base->mach_timebase_units.numer = 0; 316275970Scy } 317275970Scy return 0; 318275970Scy} 319275970Scy 320275970Scyint 321275970Scyevutil_gettime_monotonic_(struct evutil_monotonic_timer *base, 322275970Scy struct timeval *tp) 323275970Scy{ 324275970Scy ev_uint64_t abstime, usec; 325275970Scy if (base->mach_timebase_units.numer == 0) { 326275970Scy if (evutil_gettimeofday(tp, NULL) < 0) 327275970Scy return -1; 328275970Scy adjust_monotonic_time(base, tp); 329275970Scy return 0; 330275970Scy } 331275970Scy 332275970Scy abstime = mach_absolute_time(); 333275970Scy usec = (abstime * base->mach_timebase_units.numer) 334275970Scy / (base->mach_timebase_units.denom); 335275970Scy tp->tv_sec = usec / 1000000; 336275970Scy tp->tv_usec = usec % 1000000; 337275970Scy 338275970Scy return 0; 339275970Scy} 340275970Scy#endif 341275970Scy 342275970Scy#if defined(HAVE_WIN32_MONOTONIC) 343275970Scy/* ===== 344275970Scy Turn we now to Windows. Want monontonic time on Windows? 345275970Scy 346275970Scy Windows has QueryPerformanceCounter(), which gives time most high- 347275970Scy resolution time. It's a pity it's not so monotonic in practice; it's 348275970Scy also got some fun bugs, especially: with older Windowses, under 349275970Scy virtualizations, with funny hardware, on multiprocessor systems, and so 350275970Scy on. PEP418 [1] has a nice roundup of the issues here. 351275970Scy 352275970Scy There's GetTickCount64() on Vista and later, which gives a number of 1-msec 353275970Scy ticks since startup. The accuracy here might be as bad as 10-20 msec, I 354275970Scy hear. There's an undocumented function (NtSetTimerResolution) that 355275970Scy allegedly increases the accuracy. Good luck! 356275970Scy 357275970Scy There's also GetTickCount(), which is only 32 bits, but seems to be 358275970Scy supported on pre-Vista versions of Windows. Apparently, you can coax 359275970Scy another 14 bits out of it, giving you 2231 years before rollover. 360275970Scy 361275970Scy The less said about timeGetTime() the better. 362275970Scy 363275970Scy "We don't care. We don't have to. We're the Phone Company." 364275970Scy -- Lily Tomlin, SNL 365275970Scy 366275970Scy Our strategy, if precise timers are turned off, is to just use the best 367275970Scy GetTickCount equivalent available. If we've been asked for precise timing, 368275970Scy then we mostly[2] assume that GetTickCount is monotonic, and correct 369275970Scy GetPerformanceCounter to approximate it. 370275970Scy 371275970Scy [1] http://www.python.org/dev/peps/pep-0418 372275970Scy [2] Of course, we feed the Windows stuff into adjust_monotonic_time() 373275970Scy anyway, just in case it isn't. 374275970Scy 375275970Scy */ 376275970Scy/* 377275970Scy Parts of our logic in the win32 timer code here are closely based on 378275970Scy BitTorrent's libUTP library. That code is subject to the following 379275970Scy license: 380275970Scy 381275970Scy Copyright (c) 2010 BitTorrent, Inc. 382275970Scy 383275970Scy Permission is hereby granted, free of charge, to any person obtaining a 384275970Scy copy of this software and associated documentation files (the 385275970Scy "Software"), to deal in the Software without restriction, including 386275970Scy without limitation the rights to use, copy, modify, merge, publish, 387275970Scy distribute, sublicense, and/or sell copies of the Software, and to 388275970Scy permit persons to whom the Software is furnished to do so, subject to 389275970Scy the following conditions: 390275970Scy 391275970Scy The above copyright notice and this permission notice shall be included 392275970Scy in all copies or substantial portions of the Software. 393275970Scy 394275970Scy THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 395275970Scy OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 396275970Scy MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 397275970Scy NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 398275970Scy LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 399275970Scy OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 400275970Scy WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 401275970Scy*/ 402275970Scy 403275970Scystatic ev_uint64_t 404275970Scyevutil_GetTickCount_(struct evutil_monotonic_timer *base) 405275970Scy{ 406275970Scy if (base->GetTickCount64_fn) { 407275970Scy /* Let's just use GetTickCount64 if we can. */ 408275970Scy return base->GetTickCount64_fn(); 409275970Scy } else if (base->GetTickCount_fn) { 410275970Scy /* Greg Hazel assures me that this works, that BitTorrent has 411275970Scy * done it for years, and this it won't turn around and 412275970Scy * bite us. He says they found it on some game programmers' 413275970Scy * forum some time around 2007. 414275970Scy */ 415275970Scy ev_uint64_t v = base->GetTickCount_fn(); 416275970Scy return (DWORD)v | ((v >> 18) & 0xFFFFFFFF00000000); 417275970Scy } else { 418275970Scy /* Here's the fallback implementation. We have to use 419275970Scy * GetTickCount() with its given signature, so we only get 420275970Scy * 32 bits worth of milliseconds, which will roll ove every 421275970Scy * 49 days or so. */ 422275970Scy DWORD ticks = GetTickCount(); 423275970Scy if (ticks < base->last_tick_count) { 424275970Scy base->adjust_tick_count += ((ev_uint64_t)1) << 32; 425275970Scy } 426275970Scy base->last_tick_count = ticks; 427275970Scy return ticks + base->adjust_tick_count; 428275970Scy } 429275970Scy} 430275970Scy 431275970Scyint 432275970Scyevutil_configure_monotonic_time_(struct evutil_monotonic_timer *base, 433275970Scy int flags) 434275970Scy{ 435275970Scy const int precise = flags & EV_MONOT_PRECISE; 436275970Scy const int fallback = flags & EV_MONOT_FALLBACK; 437275970Scy HANDLE h; 438275970Scy memset(base, 0, sizeof(*base)); 439275970Scy 440275970Scy h = evutil_load_windows_system_library_(TEXT("kernel32.dll")); 441275970Scy if (h != NULL && !fallback) { 442275970Scy base->GetTickCount64_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount64"); 443275970Scy base->GetTickCount_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount"); 444275970Scy } 445275970Scy 446275970Scy base->first_tick = base->last_tick_count = evutil_GetTickCount_(base); 447275970Scy if (precise && !fallback) { 448275970Scy LARGE_INTEGER freq; 449275970Scy if (QueryPerformanceFrequency(&freq)) { 450275970Scy LARGE_INTEGER counter; 451275970Scy QueryPerformanceCounter(&counter); 452275970Scy base->first_counter = counter.QuadPart; 453275970Scy base->usec_per_count = 1.0e6 / freq.QuadPart; 454275970Scy base->use_performance_counter = 1; 455275970Scy } 456275970Scy } 457275970Scy 458275970Scy return 0; 459275970Scy} 460275970Scy 461275970Scystatic inline ev_int64_t 462275970Scyabs64(ev_int64_t i) 463275970Scy{ 464275970Scy return i < 0 ? -i : i; 465275970Scy} 466275970Scy 467275970Scy 468275970Scyint 469275970Scyevutil_gettime_monotonic_(struct evutil_monotonic_timer *base, 470275970Scy struct timeval *tp) 471275970Scy{ 472275970Scy ev_uint64_t ticks = evutil_GetTickCount_(base); 473275970Scy if (base->use_performance_counter) { 474275970Scy /* Here's a trick we took from BitTorrent's libutp, at Greg 475275970Scy * Hazel's recommendation. We use QueryPerformanceCounter for 476275970Scy * our high-resolution timer, but use GetTickCount*() to keep 477275970Scy * it sane, and adjust_monotonic_time() to keep it monotonic. 478275970Scy */ 479275970Scy LARGE_INTEGER counter; 480275970Scy ev_int64_t counter_elapsed, counter_usec_elapsed, ticks_elapsed; 481275970Scy QueryPerformanceCounter(&counter); 482275970Scy counter_elapsed = (ev_int64_t) 483275970Scy (counter.QuadPart - base->first_counter); 484275970Scy ticks_elapsed = ticks - base->first_tick; 485275970Scy /* TODO: This may upset VC6. If you need this to work with 486275970Scy * VC6, please supply an appropriate patch. */ 487275970Scy counter_usec_elapsed = (ev_int64_t) 488275970Scy (counter_elapsed * base->usec_per_count); 489275970Scy 490275970Scy if (abs64(ticks_elapsed*1000 - counter_usec_elapsed) > 1000000) { 491275970Scy /* It appears that the QueryPerformanceCounter() 492275970Scy * result is more than 1 second away from 493275970Scy * GetTickCount() result. Let's adjust it to be as 494275970Scy * accurate as we can; adjust_monotnonic_time() below 495275970Scy * will keep it monotonic. */ 496275970Scy counter_usec_elapsed = ticks_elapsed * 1000; 497275970Scy base->first_counter = (ev_uint64_t) (counter.QuadPart - counter_usec_elapsed / base->usec_per_count); 498275970Scy } 499275970Scy tp->tv_sec = (time_t) (counter_usec_elapsed / 1000000); 500275970Scy tp->tv_usec = counter_usec_elapsed % 1000000; 501275970Scy 502275970Scy } else { 503275970Scy /* We're just using GetTickCount(). */ 504275970Scy tp->tv_sec = (time_t) (ticks / 1000); 505275970Scy tp->tv_usec = (ticks % 1000) * 1000; 506275970Scy } 507275970Scy adjust_monotonic_time(base, tp); 508275970Scy 509275970Scy return 0; 510275970Scy} 511275970Scy#endif 512275970Scy 513275970Scy#if defined(HAVE_FALLBACK_MONOTONIC) 514275970Scy/* ===== 515275970Scy And if none of the other options work, let's just use gettimeofday(), and 516275970Scy ratchet it forward so that it acts like a monotonic timer, whether it 517275970Scy wants to or not. 518275970Scy */ 519275970Scy 520275970Scyint 521275970Scyevutil_configure_monotonic_time_(struct evutil_monotonic_timer *base, 522275970Scy int precise) 523275970Scy{ 524275970Scy memset(base, 0, sizeof(*base)); 525275970Scy return 0; 526275970Scy} 527275970Scy 528275970Scyint 529275970Scyevutil_gettime_monotonic_(struct evutil_monotonic_timer *base, 530275970Scy struct timeval *tp) 531275970Scy{ 532275970Scy if (evutil_gettimeofday(tp, NULL) < 0) 533275970Scy return -1; 534275970Scy adjust_monotonic_time(base, tp); 535275970Scy return 0; 536275970Scy 537275970Scy} 538275970Scy#endif 539