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