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