evutil_time.c revision 285612
1130812Smarcel/* 2130812Smarcel * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 3130812Smarcel * 4130812Smarcel * Redistribution and use in source and binary forms, with or without 5130812Smarcel * modification, are permitted provided that the following conditions 6130812Smarcel * are met: 7130812Smarcel * 1. Redistributions of source code must retain the above copyright 8130812Smarcel * notice, this list of conditions and the following disclaimer. 9130812Smarcel * 2. Redistributions in binary form must reproduce the above copyright 10130812Smarcel * notice, this list of conditions and the following disclaimer in the 11130812Smarcel * documentation and/or other materials provided with the distribution. 12130812Smarcel * 3. The name of the author may not be used to endorse or promote products 13130812Smarcel * derived from this software without specific prior written permission. 14130812Smarcel * 15130812Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16130812Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17130812Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18130812Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19130812Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20130812Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21130812Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22130812Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23130812Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24130812Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25130812Smarcel */ 26130812Smarcel 27130812Smarcel#include "event2/event-config.h" 28130812Smarcel#include "evconfig-private.h" 29130812Smarcel 30130812Smarcel#ifdef _WIN32 31130812Smarcel#include <winsock2.h> 32130812Smarcel#define WIN32_LEAN_AND_MEAN 33130812Smarcel#include <windows.h> 34130812Smarcel#undef WIN32_LEAN_AND_MEAN 35130812Smarcel#endif 36130812Smarcel 37130812Smarcel#include <sys/types.h> 38130812Smarcel#ifdef EVENT__HAVE_STDLIB_H 39130812Smarcel#include <stdlib.h> 40130812Smarcel#endif 41130812Smarcel#include <errno.h> 42130812Smarcel#include <limits.h> 43130812Smarcel#ifndef EVENT__HAVE_GETTIMEOFDAY 44130812Smarcel#include <sys/timeb.h> 45130812Smarcel#endif 46130812Smarcel#if !defined(EVENT__HAVE_NANOSLEEP) && !defined(EVENT_HAVE_USLEEP) && \ 47130812Smarcel !defined(_WIN32) 48130812Smarcel#include <sys/select.h> 49130812Smarcel#endif 50130812Smarcel#include <time.h> 51130812Smarcel#include <sys/stat.h> 52130812Smarcel#include <string.h> 53130812Smarcel 54130812Smarcel#include "event2/util.h" 55130812Smarcel#include "util-internal.h" 56130812Smarcel#include "log-internal.h" 57130812Smarcel#include "mm-internal.h" 58130812Smarcel 59130812Smarcel#ifndef EVENT__HAVE_GETTIMEOFDAY 60130812Smarcel/* No gettimeofday; this must be windows. */ 61130812Smarcelint 62130812Smarcelevutil_gettimeofday(struct timeval *tv, struct timezone *tz) 63130812Smarcel{ 64130812Smarcel#ifdef _MSC_VER 65130812Smarcel#define U64_LITERAL(n) n##ui64 66130812Smarcel#else 67130812Smarcel#define U64_LITERAL(n) n##llu 68130812Smarcel#endif 69130812Smarcel 70130812Smarcel /* Conversion logic taken from Tor, which in turn took it 71130812Smarcel * from Perl. GetSystemTimeAsFileTime returns its value as 72130812Smarcel * an unaligned (!) 64-bit value containing the number of 73130812Smarcel * 100-nanosecond intervals since 1 January 1601 UTC. */ 74130812Smarcel#define EPOCH_BIAS U64_LITERAL(116444736000000000) 75130812Smarcel#define UNITS_PER_SEC U64_LITERAL(10000000) 76130812Smarcel#define USEC_PER_SEC U64_LITERAL(1000000) 77130812Smarcel#define UNITS_PER_USEC U64_LITERAL(10) 78130812Smarcel union { 79130812Smarcel FILETIME ft_ft; 80130812Smarcel ev_uint64_t ft_64; 81130812Smarcel } ft; 82130812Smarcel 83130812Smarcel if (tv == NULL) 84130812Smarcel return -1; 85130812Smarcel 86130812Smarcel GetSystemTimeAsFileTime(&ft.ft_ft); 87130812Smarcel 88130812Smarcel if (EVUTIL_UNLIKELY(ft.ft_64 < EPOCH_BIAS)) { 89130812Smarcel /* Time before the unix epoch. */ 90130812Smarcel return -1; 91130812Smarcel } 92130812Smarcel ft.ft_64 -= EPOCH_BIAS; 93130812Smarcel tv->tv_sec = (long) (ft.ft_64 / UNITS_PER_SEC); 94130812Smarcel tv->tv_usec = (long) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC); 95130812Smarcel return 0; 96130812Smarcel} 97130812Smarcel#endif 98130812Smarcel 99130812Smarcel#define MAX_SECONDS_IN_MSEC_LONG \ 100130812Smarcel (((LONG_MAX) - 999) / 1000) 101130812Smarcel 102130812Smarcellong 103130812Smarcelevutil_tv_to_msec_(const struct timeval *tv) 104130812Smarcel{ 105130812Smarcel if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG) 106130812Smarcel return -1; 107130812Smarcel 108130812Smarcel return (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000); 109130812Smarcel} 110130812Smarcel 111130812Smarcel/* 112130812Smarcel Replacement for usleep on platforms that don't have one. Not guaranteed to 113130812Smarcel be any more finegrained than 1 msec. 114130812Smarcel */ 115130812Smarcelvoid 116130812Smarcelevutil_usleep_(const struct timeval *tv) 117130812Smarcel{ 118130812Smarcel if (!tv) 119130812Smarcel return; 120130812Smarcel#if defined(_WIN32) 121130812Smarcel { 122130812Smarcel long msec = evutil_tv_to_msec_(tv); 123130812Smarcel Sleep((DWORD)msec); 124130812Smarcel } 125130812Smarcel#elif defined(EVENT__HAVE_NANOSLEEP) 126130812Smarcel { 127130812Smarcel struct timespec ts; 128130812Smarcel ts.tv_sec = tv->tv_sec; 129130812Smarcel ts.tv_nsec = tv->tv_usec*1000; 130130812Smarcel nanosleep(&ts, NULL); 131130812Smarcel } 132130812Smarcel#elif defined(EVENT__HAVE_USLEEP) 133130812Smarcel /* Some systems don't like to usleep more than 999999 usec */ 134130812Smarcel sleep(tv->tv_sec); 135130812Smarcel usleep(tv->tv_usec); 136130812Smarcel#else 137130812Smarcel select(0, NULL, NULL, NULL, tv); 138130812Smarcel#endif 139130812Smarcel} 140130812Smarcel 141130812Smarcel/* 142130812Smarcel This function assumes it's called repeatedly with a 143130812Smarcel not-actually-so-monotonic time source whose outputs are in 'tv'. It 144130812Smarcel implements a trivial ratcheting mechanism so that the values never go 145130812Smarcel backwards. 146130812Smarcel */ 147130812Smarcelstatic void 148130812Smarceladjust_monotonic_time(struct evutil_monotonic_timer *base, 149130812Smarcel struct timeval *tv) 150130812Smarcel{ 151130812Smarcel evutil_timeradd(tv, &base->adjust_monotonic_clock, tv); 152130812Smarcel 153130812Smarcel if (evutil_timercmp(tv, &base->last_time, <)) { 154130812Smarcel /* Guess it wasn't monotonic after all. */ 155130812Smarcel struct timeval adjust; 156130812Smarcel evutil_timersub(&base->last_time, tv, &adjust); 157130812Smarcel evutil_timeradd(&adjust, &base->adjust_monotonic_clock, 158130812Smarcel &base->adjust_monotonic_clock); 159130812Smarcel *tv = base->last_time; 160130812Smarcel } 161130812Smarcel base->last_time = *tv; 162130812Smarcel} 163130812Smarcel 164130812Smarcel/* 165130812Smarcel Allocate a new struct evutil_monotonic_timer 166130812Smarcel */ 167130812Smarcelstruct evutil_monotonic_timer * 168130812Smarcelevutil_monotonic_timer_new(void) 169130812Smarcel{ 170130812Smarcel struct evutil_monotonic_timer *p = NULL; 171130812Smarcel 172130812Smarcel p = mm_malloc(sizeof(*p)); 173130812Smarcel if (!p) goto done; 174130812Smarcel 175130812Smarcel memset(p, 0, sizeof(*p)); 176130812Smarcel 177130812Smarcel done: 178130812Smarcel return p; 179130812Smarcel} 180130812Smarcel 181130812Smarcel/* 182130812Smarcel Free a struct evutil_monotonic_timer 183130812Smarcel */ 184130812Smarcelvoid 185130812Smarcelevutil_monotonic_timer_free(struct evutil_monotonic_timer *timer) 186130812Smarcel{ 187130812Smarcel if (timer) { 188130812Smarcel mm_free(timer); 189130812Smarcel } 190130812Smarcel} 191130812Smarcel 192130812Smarcel/* 193130812Smarcel Set up a struct evutil_monotonic_timer for initial use 194130812Smarcel */ 195130812Smarcelint 196130812Smarcelevutil_configure_monotonic_time(struct evutil_monotonic_timer *timer, 197130812Smarcel int flags) 198130812Smarcel{ 199130812Smarcel return evutil_configure_monotonic_time_(timer, flags); 200130812Smarcel} 201130812Smarcel 202130812Smarcel/* 203130812Smarcel Query the current monotonic time 204130812Smarcel */ 205130812Smarcelint 206130812Smarcelevutil_gettime_monotonic(struct evutil_monotonic_timer *timer, 207130812Smarcel struct timeval *tp) 208130812Smarcel{ 209130812Smarcel return evutil_gettime_monotonic_(timer, tp); 210130812Smarcel} 211130812Smarcel 212130812Smarcel 213130812Smarcel#if defined(HAVE_POSIX_MONOTONIC) 214130812Smarcel/* ===== 215130812Smarcel The POSIX clock_gettime() interface provides a few ways to get at a 216130812Smarcel monotonic clock. CLOCK_MONOTONIC is most widely supported. Linux also 217130812Smarcel provides a CLOCK_MONOTONIC_COARSE with accuracy of about 1-4 msec. 218130812Smarcel 219130812Smarcel On all platforms I'm aware of, CLOCK_MONOTONIC really is monotonic. 220130812Smarcel Platforms don't agree about whether it should jump on a sleep/resume. 221130812Smarcel */ 222130812Smarcel 223130812Smarcelint 224130812Smarcelevutil_configure_monotonic_time_(struct evutil_monotonic_timer *base, 225130812Smarcel int flags) 226130812Smarcel{ 227130812Smarcel /* CLOCK_MONOTONIC exists on FreeBSD, Linux, and Solaris. You need to 228130812Smarcel * check for it at runtime, because some older kernel versions won't 229130812Smarcel * have it working. */ 230130812Smarcel#ifdef CLOCK_MONOTONIC_COARSE 231130812Smarcel const int precise = flags & EV_MONOT_PRECISE; 232130812Smarcel#endif 233130812Smarcel const int fallback = flags & EV_MONOT_FALLBACK; 234130812Smarcel struct timespec ts; 235130812Smarcel 236130812Smarcel#ifdef CLOCK_MONOTONIC_COARSE 237130812Smarcel if (CLOCK_MONOTONIC_COARSE < 0) { 238130812Smarcel /* Technically speaking, nothing keeps CLOCK_* from being 239130812Smarcel * negative (as far as I know). This check and the one below 240130812Smarcel * make sure that it's safe for us to use -1 as an "unset" 241130812Smarcel * value. */ 242130812Smarcel event_errx(1,"I didn't expect CLOCK_MONOTONIC_COARSE to be < 0"); 243130812Smarcel } 244130812Smarcel if (! precise && ! fallback) { 245130812Smarcel if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) == 0) { 246130812Smarcel base->monotonic_clock = CLOCK_MONOTONIC_COARSE; 247130812Smarcel return 0; 248130812Smarcel } 249130812Smarcel } 250130812Smarcel#endif 251130812Smarcel if (!fallback && clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { 252130812Smarcel base->monotonic_clock = CLOCK_MONOTONIC; 253130812Smarcel return 0; 254130812Smarcel } 255130812Smarcel 256130812Smarcel if (CLOCK_MONOTONIC < 0) { 257130812Smarcel event_errx(1,"I didn't expect CLOCK_MONOTONIC to be < 0"); 258130812Smarcel } 259130812Smarcel 260130812Smarcel base->monotonic_clock = -1; 261130812Smarcel return 0; 262130812Smarcel} 263130812Smarcel 264130812Smarcelint 265130812Smarcelevutil_gettime_monotonic_(struct evutil_monotonic_timer *base, 266130812Smarcel struct timeval *tp) 267130812Smarcel{ 268130812Smarcel struct timespec ts; 269130812Smarcel 270130812Smarcel if (base->monotonic_clock < 0) { 271130812Smarcel if (evutil_gettimeofday(tp, NULL) < 0) 272130812Smarcel return -1; 273130812Smarcel adjust_monotonic_time(base, tp); 274130812Smarcel return 0; 275130812Smarcel } 276130812Smarcel 277130812Smarcel if (clock_gettime(base->monotonic_clock, &ts) == -1) 278130812Smarcel return -1; 279130812Smarcel tp->tv_sec = ts.tv_sec; 280130812Smarcel tp->tv_usec = ts.tv_nsec / 1000; 281130812Smarcel 282130812Smarcel return 0; 283130812Smarcel} 284130812Smarcel#endif 285130812Smarcel 286130812Smarcel#if defined(HAVE_MACH_MONOTONIC) 287130812Smarcel/* ====== 288130812Smarcel Apple is a little late to the POSIX party. And why not? Instead of 289130812Smarcel clock_gettime(), they provide mach_absolute_time(). Its units are not 290130812Smarcel fixed; we need to use mach_timebase_info() to get the right functions to 291130812Smarcel convert its units into nanoseconds. 292130812Smarcel 293130812Smarcel To all appearances, mach_absolute_time() seems to be honest-to-goodness 294130812Smarcel monotonic. Whether it stops during sleep or not is unspecified in 295130812Smarcel principle, and dependent on CPU architecture in practice. 296130812Smarcel */ 297130812Smarcel 298130812Smarcelint 299130812Smarcelevutil_configure_monotonic_time_(struct evutil_monotonic_timer *base, 300130812Smarcel int flags) 301130812Smarcel{ 302130812Smarcel const int fallback = flags & EV_MONOT_FALLBACK; 303130812Smarcel struct mach_timebase_info mi; 304130812Smarcel memset(base, 0, sizeof(*base)); 305130812Smarcel /* OSX has mach_absolute_time() */ 306130812Smarcel if (!fallback && 307130812Smarcel mach_timebase_info(&mi) == 0 && 308130812Smarcel mach_absolute_time() != 0) { 309130812Smarcel /* mach_timebase_info tells us how to convert 310130812Smarcel * mach_absolute_time() into nanoseconds, but we 311130812Smarcel * want to use microseconds instead. */ 312130812Smarcel mi.denom *= 1000; 313130812Smarcel memcpy(&base->mach_timebase_units, &mi, sizeof(mi)); 314130812Smarcel } else { 315130812Smarcel base->mach_timebase_units.numer = 0; 316130812Smarcel } 317130812Smarcel return 0; 318130812Smarcel} 319130812Smarcel 320130812Smarcelint 321130812Smarcelevutil_gettime_monotonic_(struct evutil_monotonic_timer *base, 322130812Smarcel struct timeval *tp) 323130812Smarcel{ 324130812Smarcel ev_uint64_t abstime, usec; 325130812Smarcel if (base->mach_timebase_units.numer == 0) { 326130812Smarcel if (evutil_gettimeofday(tp, NULL) < 0) 327130812Smarcel return -1; 328130812Smarcel adjust_monotonic_time(base, tp); 329130812Smarcel return 0; 330130812Smarcel } 331130812Smarcel 332130812Smarcel abstime = mach_absolute_time(); 333130812Smarcel usec = (abstime * base->mach_timebase_units.numer) 334130812Smarcel / (base->mach_timebase_units.denom); 335130812Smarcel tp->tv_sec = usec / 1000000; 336130812Smarcel tp->tv_usec = usec % 1000000; 337130812Smarcel 338130812Smarcel return 0; 339130812Smarcel} 340130812Smarcel#endif 341130812Smarcel 342130812Smarcel#if defined(HAVE_WIN32_MONOTONIC) 343130812Smarcel/* ===== 344130812Smarcel Turn we now to Windows. Want monontonic time on Windows? 345130812Smarcel 346130812Smarcel Windows has QueryPerformanceCounter(), which gives time most high- 347130812Smarcel resolution time. It's a pity it's not so monotonic in practice; it's 348130812Smarcel also got some fun bugs, especially: with older Windowses, under 349130812Smarcel virtualizations, with funny hardware, on multiprocessor systems, and so 350130812Smarcel on. PEP418 [1] has a nice roundup of the issues here. 351130812Smarcel 352130812Smarcel There's GetTickCount64() on Vista and later, which gives a number of 1-msec 353130812Smarcel ticks since startup. The accuracy here might be as bad as 10-20 msec, I 354130812Smarcel hear. There's an undocumented function (NtSetTimerResolution) that 355130812Smarcel allegedly increases the accuracy. Good luck! 356130812Smarcel 357130812Smarcel There's also GetTickCount(), which is only 32 bits, but seems to be 358130812Smarcel supported on pre-Vista versions of Windows. Apparently, you can coax 359130812Smarcel another 14 bits out of it, giving you 2231 years before rollover. 360130812Smarcel 361130812Smarcel The less said about timeGetTime() the better. 362130812Smarcel 363130812Smarcel "We don't care. We don't have to. We're the Phone Company." 364130812Smarcel -- Lily Tomlin, SNL 365130812Smarcel 366130812Smarcel Our strategy, if precise timers are turned off, is to just use the best 367130812Smarcel GetTickCount equivalent available. If we've been asked for precise timing, 368130812Smarcel then we mostly[2] assume that GetTickCount is monotonic, and correct 369130812Smarcel GetPerformanceCounter to approximate it. 370130812Smarcel 371130812Smarcel [1] http://www.python.org/dev/peps/pep-0418 372130812Smarcel [2] Of course, we feed the Windows stuff into adjust_monotonic_time() 373130812Smarcel anyway, just in case it isn't. 374130812Smarcel 375130812Smarcel */ 376130812Smarcel/* 377130812Smarcel Parts of our logic in the win32 timer code here are closely based on 378130812Smarcel BitTorrent's libUTP library. That code is subject to the following 379130812Smarcel license: 380130812Smarcel 381130812Smarcel Copyright (c) 2010 BitTorrent, Inc. 382130812Smarcel 383130812Smarcel Permission is hereby granted, free of charge, to any person obtaining a 384130812Smarcel copy of this software and associated documentation files (the 385130812Smarcel "Software"), to deal in the Software without restriction, including 386130812Smarcel without limitation the rights to use, copy, modify, merge, publish, 387130812Smarcel distribute, sublicense, and/or sell copies of the Software, and to 388130812Smarcel permit persons to whom the Software is furnished to do so, subject to 389130812Smarcel the following conditions: 390130812Smarcel 391130812Smarcel The above copyright notice and this permission notice shall be included 392130812Smarcel in all copies or substantial portions of the Software. 393130812Smarcel 394130812Smarcel THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 395130812Smarcel OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 396130812Smarcel MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 397130812Smarcel NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 398130812Smarcel LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 399130812Smarcel OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 400130812Smarcel WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 401130812Smarcel*/ 402130812Smarcel 403130812Smarcelstatic ev_uint64_t 404130812Smarcelevutil_GetTickCount_(struct evutil_monotonic_timer *base) 405130812Smarcel{ 406130812Smarcel if (base->GetTickCount64_fn) { 407130812Smarcel /* Let's just use GetTickCount64 if we can. */ 408130812Smarcel return base->GetTickCount64_fn(); 409130812Smarcel } else if (base->GetTickCount_fn) { 410130812Smarcel /* Greg Hazel assures me that this works, that BitTorrent has 411130812Smarcel * done it for years, and this it won't turn around and 412130812Smarcel * bite us. He says they found it on some game programmers' 413130812Smarcel * forum some time around 2007. 414130812Smarcel */ 415130812Smarcel ev_uint64_t v = base->GetTickCount_fn(); 416130812Smarcel return (DWORD)v | ((v >> 18) & 0xFFFFFFFF00000000); 417130812Smarcel } else { 418130812Smarcel /* Here's the fallback implementation. We have to use 419130812Smarcel * GetTickCount() with its given signature, so we only get 420130812Smarcel * 32 bits worth of milliseconds, which will roll ove every 421130812Smarcel * 49 days or so. */ 422130812Smarcel DWORD ticks = GetTickCount(); 423130812Smarcel if (ticks < base->last_tick_count) { 424130812Smarcel base->adjust_tick_count += ((ev_uint64_t)1) << 32; 425130812Smarcel } 426130812Smarcel base->last_tick_count = ticks; 427130812Smarcel return ticks + base->adjust_tick_count; 428130812Smarcel } 429130812Smarcel} 430130812Smarcel 431130812Smarcelint 432130812Smarcelevutil_configure_monotonic_time_(struct evutil_monotonic_timer *base, 433130812Smarcel int flags) 434130812Smarcel{ 435130812Smarcel const int precise = flags & EV_MONOT_PRECISE; 436130812Smarcel const int fallback = flags & EV_MONOT_FALLBACK; 437130812Smarcel HANDLE h; 438130812Smarcel memset(base, 0, sizeof(*base)); 439130812Smarcel 440130812Smarcel h = evutil_load_windows_system_library_(TEXT("kernel32.dll")); 441130812Smarcel if (h != NULL && !fallback) { 442130812Smarcel base->GetTickCount64_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount64"); 443130812Smarcel base->GetTickCount_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount"); 444130812Smarcel } 445130812Smarcel 446130812Smarcel base->first_tick = base->last_tick_count = evutil_GetTickCount_(base); 447130812Smarcel if (precise && !fallback) { 448130812Smarcel LARGE_INTEGER freq; 449130812Smarcel if (QueryPerformanceFrequency(&freq)) { 450130812Smarcel LARGE_INTEGER counter; 451130812Smarcel QueryPerformanceCounter(&counter); 452130812Smarcel base->first_counter = counter.QuadPart; 453130812Smarcel base->usec_per_count = 1.0e6 / freq.QuadPart; 454130812Smarcel base->use_performance_counter = 1; 455130812Smarcel } 456130812Smarcel } 457130812Smarcel 458130812Smarcel return 0; 459130812Smarcel} 460130812Smarcel 461130812Smarcelstatic inline ev_int64_t 462130812Smarcelabs64(ev_int64_t i) 463130812Smarcel{ 464130812Smarcel return i < 0 ? -i : i; 465130812Smarcel} 466130812Smarcel 467130812Smarcel 468130812Smarcelint 469130812Smarcelevutil_gettime_monotonic_(struct evutil_monotonic_timer *base, 470130812Smarcel struct timeval *tp) 471130812Smarcel{ 472130812Smarcel ev_uint64_t ticks = evutil_GetTickCount_(base); 473130812Smarcel if (base->use_performance_counter) { 474130812Smarcel /* Here's a trick we took from BitTorrent's libutp, at Greg 475130812Smarcel * Hazel's recommendation. We use QueryPerformanceCounter for 476130812Smarcel * our high-resolution timer, but use GetTickCount*() to keep 477130812Smarcel * it sane, and adjust_monotonic_time() to keep it monotonic. 478130812Smarcel */ 479130812Smarcel LARGE_INTEGER counter; 480130812Smarcel ev_int64_t counter_elapsed, counter_usec_elapsed, ticks_elapsed; 481130812Smarcel QueryPerformanceCounter(&counter); 482130812Smarcel counter_elapsed = (ev_int64_t) 483130812Smarcel (counter.QuadPart - base->first_counter); 484130812Smarcel ticks_elapsed = ticks - base->first_tick; 485130812Smarcel /* TODO: This may upset VC6. If you need this to work with 486130812Smarcel * VC6, please supply an appropriate patch. */ 487130812Smarcel counter_usec_elapsed = (ev_int64_t) 488130812Smarcel (counter_elapsed * base->usec_per_count); 489130812Smarcel 490130812Smarcel if (abs64(ticks_elapsed*1000 - counter_usec_elapsed) > 1000000) { 491130812Smarcel /* It appears that the QueryPerformanceCounter() 492130812Smarcel * result is more than 1 second away from 493130812Smarcel * GetTickCount() result. Let's adjust it to be as 494130812Smarcel * accurate as we can; adjust_monotnonic_time() below 495130812Smarcel * will keep it monotonic. */ 496130812Smarcel counter_usec_elapsed = ticks_elapsed * 1000; 497130812Smarcel base->first_counter = (ev_uint64_t) (counter.QuadPart - counter_usec_elapsed / base->usec_per_count); 498130812Smarcel } 499130812Smarcel tp->tv_sec = (time_t) (counter_usec_elapsed / 1000000); 500130812Smarcel tp->tv_usec = counter_usec_elapsed % 1000000; 501130812Smarcel 502130812Smarcel } else { 503130812Smarcel /* We're just using GetTickCount(). */ 504130812Smarcel tp->tv_sec = (time_t) (ticks / 1000); 505130812Smarcel tp->tv_usec = (ticks % 1000) * 1000; 506130812Smarcel } 507130812Smarcel adjust_monotonic_time(base, tp); 508130812Smarcel 509130812Smarcel return 0; 510130812Smarcel} 511130812Smarcel#endif 512130812Smarcel 513130812Smarcel#if defined(HAVE_FALLBACK_MONOTONIC) 514130812Smarcel/* ===== 515130812Smarcel And if none of the other options work, let's just use gettimeofday(), and 516130812Smarcel ratchet it forward so that it acts like a monotonic timer, whether it 517130812Smarcel wants to or not. 518130812Smarcel */ 519130812Smarcel 520130812Smarcelint 521130812Smarcelevutil_configure_monotonic_time_(struct evutil_monotonic_timer *base, 522130812Smarcel int precise) 523130812Smarcel{ 524130812Smarcel memset(base, 0, sizeof(*base)); 525130812Smarcel return 0; 526130812Smarcel} 527130812Smarcel 528130812Smarcelint 529130812Smarcelevutil_gettime_monotonic_(struct evutil_monotonic_timer *base, 530130812Smarcel struct timeval *tp) 531130812Smarcel{ 532130812Smarcel if (evutil_gettimeofday(tp, NULL) < 0) 533130812Smarcel return -1; 534130812Smarcel adjust_monotonic_time(base, tp); 535130812Smarcel return 0; 536130812Smarcel 537130812Smarcel} 538130812Smarcel#endif 539130812Smarcel