12b15cb3dSCy Schubert /*
22b15cb3dSCy Schubert * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
32b15cb3dSCy Schubert *
42b15cb3dSCy Schubert * Redistribution and use in source and binary forms, with or without
52b15cb3dSCy Schubert * modification, are permitted provided that the following conditions
62b15cb3dSCy Schubert * are met:
72b15cb3dSCy Schubert * 1. Redistributions of source code must retain the above copyright
82b15cb3dSCy Schubert * notice, this list of conditions and the following disclaimer.
92b15cb3dSCy Schubert * 2. Redistributions in binary form must reproduce the above copyright
102b15cb3dSCy Schubert * notice, this list of conditions and the following disclaimer in the
112b15cb3dSCy Schubert * documentation and/or other materials provided with the distribution.
122b15cb3dSCy Schubert * 3. The name of the author may not be used to endorse or promote products
132b15cb3dSCy Schubert * derived from this software without specific prior written permission.
142b15cb3dSCy Schubert *
152b15cb3dSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
162b15cb3dSCy Schubert * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
172b15cb3dSCy Schubert * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
182b15cb3dSCy Schubert * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
192b15cb3dSCy Schubert * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
202b15cb3dSCy Schubert * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
212b15cb3dSCy Schubert * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
222b15cb3dSCy Schubert * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
232b15cb3dSCy Schubert * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
242b15cb3dSCy Schubert * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
252b15cb3dSCy Schubert */
262b15cb3dSCy Schubert
272b15cb3dSCy Schubert #include "event2/event-config.h"
282b15cb3dSCy Schubert #include "evconfig-private.h"
292b15cb3dSCy Schubert
302b15cb3dSCy Schubert #ifdef _WIN32
312b15cb3dSCy Schubert #include <winsock2.h>
322b15cb3dSCy Schubert #define WIN32_LEAN_AND_MEAN
332b15cb3dSCy Schubert #include <windows.h>
342b15cb3dSCy Schubert #undef WIN32_LEAN_AND_MEAN
352b15cb3dSCy Schubert #endif
362b15cb3dSCy Schubert
372b15cb3dSCy Schubert #include <sys/types.h>
382b15cb3dSCy Schubert #ifdef EVENT__HAVE_STDLIB_H
392b15cb3dSCy Schubert #include <stdlib.h>
402b15cb3dSCy Schubert #endif
412b15cb3dSCy Schubert #include <errno.h>
422b15cb3dSCy Schubert #include <limits.h>
432b15cb3dSCy Schubert #ifndef EVENT__HAVE_GETTIMEOFDAY
442b15cb3dSCy Schubert #include <sys/timeb.h>
452b15cb3dSCy Schubert #endif
46*a466cc55SCy Schubert #if !defined(EVENT__HAVE_NANOSLEEP) && !defined(EVENT__HAVE_USLEEP) && \
472b15cb3dSCy Schubert !defined(_WIN32)
482b15cb3dSCy Schubert #include <sys/select.h>
492b15cb3dSCy Schubert #endif
502b15cb3dSCy Schubert #include <time.h>
512b15cb3dSCy Schubert #include <sys/stat.h>
522b15cb3dSCy Schubert #include <string.h>
532b15cb3dSCy Schubert
54*a466cc55SCy Schubert /** evutil_usleep_() */
55*a466cc55SCy Schubert #if defined(_WIN32)
56*a466cc55SCy Schubert #elif defined(EVENT__HAVE_NANOSLEEP)
57*a466cc55SCy Schubert #elif defined(EVENT__HAVE_USLEEP)
58*a466cc55SCy Schubert #include <unistd.h>
59*a466cc55SCy Schubert #endif
60*a466cc55SCy Schubert
612b15cb3dSCy Schubert #include "event2/util.h"
622b15cb3dSCy Schubert #include "util-internal.h"
632b15cb3dSCy Schubert #include "log-internal.h"
64a25439b6SCy Schubert #include "mm-internal.h"
652b15cb3dSCy Schubert
662b15cb3dSCy Schubert #ifndef EVENT__HAVE_GETTIMEOFDAY
672b15cb3dSCy Schubert /* No gettimeofday; this must be windows. */
68*a466cc55SCy Schubert
69*a466cc55SCy Schubert typedef void (WINAPI *GetSystemTimePreciseAsFileTime_fn_t) (LPFILETIME);
70*a466cc55SCy Schubert
712b15cb3dSCy Schubert int
evutil_gettimeofday(struct timeval * tv,struct timezone * tz)722b15cb3dSCy Schubert evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
732b15cb3dSCy Schubert {
742b15cb3dSCy Schubert #ifdef _MSC_VER
752b15cb3dSCy Schubert #define U64_LITERAL(n) n##ui64
762b15cb3dSCy Schubert #else
772b15cb3dSCy Schubert #define U64_LITERAL(n) n##llu
782b15cb3dSCy Schubert #endif
792b15cb3dSCy Schubert
802b15cb3dSCy Schubert /* Conversion logic taken from Tor, which in turn took it
812b15cb3dSCy Schubert * from Perl. GetSystemTimeAsFileTime returns its value as
822b15cb3dSCy Schubert * an unaligned (!) 64-bit value containing the number of
832b15cb3dSCy Schubert * 100-nanosecond intervals since 1 January 1601 UTC. */
842b15cb3dSCy Schubert #define EPOCH_BIAS U64_LITERAL(116444736000000000)
852b15cb3dSCy Schubert #define UNITS_PER_SEC U64_LITERAL(10000000)
862b15cb3dSCy Schubert #define USEC_PER_SEC U64_LITERAL(1000000)
872b15cb3dSCy Schubert #define UNITS_PER_USEC U64_LITERAL(10)
882b15cb3dSCy Schubert union {
892b15cb3dSCy Schubert FILETIME ft_ft;
902b15cb3dSCy Schubert ev_uint64_t ft_64;
912b15cb3dSCy Schubert } ft;
922b15cb3dSCy Schubert
932b15cb3dSCy Schubert if (tv == NULL)
942b15cb3dSCy Schubert return -1;
952b15cb3dSCy Schubert
96*a466cc55SCy Schubert static GetSystemTimePreciseAsFileTime_fn_t GetSystemTimePreciseAsFileTime_fn = NULL;
97*a466cc55SCy Schubert static int check_precise = 1;
98*a466cc55SCy Schubert
99*a466cc55SCy Schubert if (EVUTIL_UNLIKELY(check_precise)) {
100*a466cc55SCy Schubert HMODULE h = evutil_load_windows_system_library_(TEXT("kernel32.dll"));
101*a466cc55SCy Schubert if (h != NULL)
102*a466cc55SCy Schubert GetSystemTimePreciseAsFileTime_fn =
103*a466cc55SCy Schubert (GetSystemTimePreciseAsFileTime_fn_t)
104*a466cc55SCy Schubert GetProcAddress(h, "GetSystemTimePreciseAsFileTime");
105*a466cc55SCy Schubert check_precise = 0;
106*a466cc55SCy Schubert }
107*a466cc55SCy Schubert
108*a466cc55SCy Schubert if (GetSystemTimePreciseAsFileTime_fn != NULL)
109*a466cc55SCy Schubert GetSystemTimePreciseAsFileTime_fn(&ft.ft_ft);
110*a466cc55SCy Schubert else
1112b15cb3dSCy Schubert GetSystemTimeAsFileTime(&ft.ft_ft);
1122b15cb3dSCy Schubert
1132b15cb3dSCy Schubert if (EVUTIL_UNLIKELY(ft.ft_64 < EPOCH_BIAS)) {
1142b15cb3dSCy Schubert /* Time before the unix epoch. */
1152b15cb3dSCy Schubert return -1;
1162b15cb3dSCy Schubert }
1172b15cb3dSCy Schubert ft.ft_64 -= EPOCH_BIAS;
1182b15cb3dSCy Schubert tv->tv_sec = (long) (ft.ft_64 / UNITS_PER_SEC);
1192b15cb3dSCy Schubert tv->tv_usec = (long) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
1202b15cb3dSCy Schubert return 0;
1212b15cb3dSCy Schubert }
1222b15cb3dSCy Schubert #endif
1232b15cb3dSCy Schubert
1242b15cb3dSCy Schubert #define MAX_SECONDS_IN_MSEC_LONG \
1252b15cb3dSCy Schubert (((LONG_MAX) - 999) / 1000)
1262b15cb3dSCy Schubert
1272b15cb3dSCy Schubert long
evutil_tv_to_msec_(const struct timeval * tv)1282b15cb3dSCy Schubert evutil_tv_to_msec_(const struct timeval *tv)
1292b15cb3dSCy Schubert {
1302b15cb3dSCy Schubert if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG)
1312b15cb3dSCy Schubert return -1;
1322b15cb3dSCy Schubert
1332b15cb3dSCy Schubert return (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000);
1342b15cb3dSCy Schubert }
1352b15cb3dSCy Schubert
1362b15cb3dSCy Schubert /*
1372b15cb3dSCy Schubert Replacement for usleep on platforms that don't have one. Not guaranteed to
1382b15cb3dSCy Schubert be any more finegrained than 1 msec.
1392b15cb3dSCy Schubert */
1402b15cb3dSCy Schubert void
evutil_usleep_(const struct timeval * tv)1412b15cb3dSCy Schubert evutil_usleep_(const struct timeval *tv)
1422b15cb3dSCy Schubert {
1432b15cb3dSCy Schubert if (!tv)
1442b15cb3dSCy Schubert return;
1452b15cb3dSCy Schubert #if defined(_WIN32)
1462b15cb3dSCy Schubert {
147*a466cc55SCy Schubert __int64 usec;
148*a466cc55SCy Schubert LARGE_INTEGER li;
149*a466cc55SCy Schubert HANDLE timer;
150*a466cc55SCy Schubert
151*a466cc55SCy Schubert usec = tv->tv_sec * 1000000LL + tv->tv_usec;
152*a466cc55SCy Schubert if (!usec)
153*a466cc55SCy Schubert return;
154*a466cc55SCy Schubert
155*a466cc55SCy Schubert li.QuadPart = -10LL * usec;
156*a466cc55SCy Schubert timer = CreateWaitableTimer(NULL, TRUE, NULL);
157*a466cc55SCy Schubert if (!timer)
158*a466cc55SCy Schubert return;
159*a466cc55SCy Schubert
160*a466cc55SCy Schubert SetWaitableTimer(timer, &li, 0, NULL, NULL, 0);
161*a466cc55SCy Schubert WaitForSingleObject(timer, INFINITE);
162*a466cc55SCy Schubert CloseHandle(timer);
1632b15cb3dSCy Schubert }
1642b15cb3dSCy Schubert #elif defined(EVENT__HAVE_NANOSLEEP)
1652b15cb3dSCy Schubert {
1662b15cb3dSCy Schubert struct timespec ts;
1672b15cb3dSCy Schubert ts.tv_sec = tv->tv_sec;
1682b15cb3dSCy Schubert ts.tv_nsec = tv->tv_usec*1000;
1692b15cb3dSCy Schubert nanosleep(&ts, NULL);
1702b15cb3dSCy Schubert }
1712b15cb3dSCy Schubert #elif defined(EVENT__HAVE_USLEEP)
1722b15cb3dSCy Schubert /* Some systems don't like to usleep more than 999999 usec */
1732b15cb3dSCy Schubert sleep(tv->tv_sec);
1742b15cb3dSCy Schubert usleep(tv->tv_usec);
1752b15cb3dSCy Schubert #else
176*a466cc55SCy Schubert {
177*a466cc55SCy Schubert struct timeval tv2 = *tv;
178*a466cc55SCy Schubert select(0, NULL, NULL, NULL, &tv2);
179*a466cc55SCy Schubert }
1802b15cb3dSCy Schubert #endif
1812b15cb3dSCy Schubert }
1822b15cb3dSCy Schubert
183*a466cc55SCy Schubert int
evutil_date_rfc1123(char * date,const size_t datelen,const struct tm * tm)184*a466cc55SCy Schubert evutil_date_rfc1123(char *date, const size_t datelen, const struct tm *tm)
185*a466cc55SCy Schubert {
186*a466cc55SCy Schubert static const char *DAYS[] =
187*a466cc55SCy Schubert { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
188*a466cc55SCy Schubert static const char *MONTHS[] =
189*a466cc55SCy Schubert { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
190*a466cc55SCy Schubert
191*a466cc55SCy Schubert time_t t = time(NULL);
192*a466cc55SCy Schubert
193*a466cc55SCy Schubert #if defined(EVENT__HAVE__GMTIME64_S) || !defined(_WIN32)
194*a466cc55SCy Schubert struct tm sys;
195*a466cc55SCy Schubert #endif
196*a466cc55SCy Schubert
197*a466cc55SCy Schubert /* If `tm` is null, set system's current time. */
198*a466cc55SCy Schubert if (tm == NULL) {
199*a466cc55SCy Schubert #if !defined(_WIN32)
200*a466cc55SCy Schubert gmtime_r(&t, &sys);
201*a466cc55SCy Schubert tm = &sys;
202*a466cc55SCy Schubert /** detect _gmtime64()/_gmtime64_s() */
203*a466cc55SCy Schubert #elif defined(EVENT__HAVE__GMTIME64_S)
204*a466cc55SCy Schubert errno_t err;
205*a466cc55SCy Schubert err = _gmtime64_s(&sys, &t);
206*a466cc55SCy Schubert if (err) {
207*a466cc55SCy Schubert event_errx(1, "Invalid argument to _gmtime64_s");
208*a466cc55SCy Schubert } else {
209*a466cc55SCy Schubert tm = &sys;
210*a466cc55SCy Schubert }
211*a466cc55SCy Schubert #elif defined(EVENT__HAVE__GMTIME64)
212*a466cc55SCy Schubert tm = _gmtime64(&t);
213*a466cc55SCy Schubert #else
214*a466cc55SCy Schubert tm = gmtime(&t);
215*a466cc55SCy Schubert #endif
216*a466cc55SCy Schubert }
217*a466cc55SCy Schubert
218*a466cc55SCy Schubert return evutil_snprintf(
219*a466cc55SCy Schubert date, datelen, "%s, %02d %s %4d %02d:%02d:%02d GMT",
220*a466cc55SCy Schubert DAYS[tm->tm_wday], tm->tm_mday, MONTHS[tm->tm_mon],
221*a466cc55SCy Schubert 1900 + tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec);
222*a466cc55SCy Schubert }
223*a466cc55SCy Schubert
2242b15cb3dSCy Schubert /*
2252b15cb3dSCy Schubert This function assumes it's called repeatedly with a
2262b15cb3dSCy Schubert not-actually-so-monotonic time source whose outputs are in 'tv'. It
2272b15cb3dSCy Schubert implements a trivial ratcheting mechanism so that the values never go
2282b15cb3dSCy Schubert backwards.
2292b15cb3dSCy Schubert */
2302b15cb3dSCy Schubert static void
adjust_monotonic_time(struct evutil_monotonic_timer * base,struct timeval * tv)2312b15cb3dSCy Schubert adjust_monotonic_time(struct evutil_monotonic_timer *base,
2322b15cb3dSCy Schubert struct timeval *tv)
2332b15cb3dSCy Schubert {
2342b15cb3dSCy Schubert evutil_timeradd(tv, &base->adjust_monotonic_clock, tv);
2352b15cb3dSCy Schubert
2362b15cb3dSCy Schubert if (evutil_timercmp(tv, &base->last_time, <)) {
2372b15cb3dSCy Schubert /* Guess it wasn't monotonic after all. */
2382b15cb3dSCy Schubert struct timeval adjust;
2392b15cb3dSCy Schubert evutil_timersub(&base->last_time, tv, &adjust);
2402b15cb3dSCy Schubert evutil_timeradd(&adjust, &base->adjust_monotonic_clock,
2412b15cb3dSCy Schubert &base->adjust_monotonic_clock);
2422b15cb3dSCy Schubert *tv = base->last_time;
2432b15cb3dSCy Schubert }
2442b15cb3dSCy Schubert base->last_time = *tv;
2452b15cb3dSCy Schubert }
2462b15cb3dSCy Schubert
247a25439b6SCy Schubert /*
248a25439b6SCy Schubert Allocate a new struct evutil_monotonic_timer
249a25439b6SCy Schubert */
250a25439b6SCy Schubert struct evutil_monotonic_timer *
evutil_monotonic_timer_new(void)251a25439b6SCy Schubert evutil_monotonic_timer_new(void)
252a25439b6SCy Schubert {
253a25439b6SCy Schubert struct evutil_monotonic_timer *p = NULL;
254a25439b6SCy Schubert
255a25439b6SCy Schubert p = mm_malloc(sizeof(*p));
256a25439b6SCy Schubert if (!p) goto done;
257a25439b6SCy Schubert
258a25439b6SCy Schubert memset(p, 0, sizeof(*p));
259a25439b6SCy Schubert
260a25439b6SCy Schubert done:
261a25439b6SCy Schubert return p;
262a25439b6SCy Schubert }
263a25439b6SCy Schubert
264a25439b6SCy Schubert /*
265a25439b6SCy Schubert Free a struct evutil_monotonic_timer
266a25439b6SCy Schubert */
267a25439b6SCy Schubert void
evutil_monotonic_timer_free(struct evutil_monotonic_timer * timer)268a25439b6SCy Schubert evutil_monotonic_timer_free(struct evutil_monotonic_timer *timer)
269a25439b6SCy Schubert {
270a25439b6SCy Schubert if (timer) {
271a25439b6SCy Schubert mm_free(timer);
272a25439b6SCy Schubert }
273a25439b6SCy Schubert }
274a25439b6SCy Schubert
275a25439b6SCy Schubert /*
276a25439b6SCy Schubert Set up a struct evutil_monotonic_timer for initial use
277a25439b6SCy Schubert */
278a25439b6SCy Schubert int
evutil_configure_monotonic_time(struct evutil_monotonic_timer * timer,int flags)279a25439b6SCy Schubert evutil_configure_monotonic_time(struct evutil_monotonic_timer *timer,
280a25439b6SCy Schubert int flags)
281a25439b6SCy Schubert {
282a25439b6SCy Schubert return evutil_configure_monotonic_time_(timer, flags);
283a25439b6SCy Schubert }
284a25439b6SCy Schubert
285a25439b6SCy Schubert /*
286a25439b6SCy Schubert Query the current monotonic time
287a25439b6SCy Schubert */
288a25439b6SCy Schubert int
evutil_gettime_monotonic(struct evutil_monotonic_timer * timer,struct timeval * tp)289a25439b6SCy Schubert evutil_gettime_monotonic(struct evutil_monotonic_timer *timer,
290a25439b6SCy Schubert struct timeval *tp)
291a25439b6SCy Schubert {
292a25439b6SCy Schubert return evutil_gettime_monotonic_(timer, tp);
293a25439b6SCy Schubert }
294a25439b6SCy Schubert
295a25439b6SCy Schubert
2962b15cb3dSCy Schubert #if defined(HAVE_POSIX_MONOTONIC)
2972b15cb3dSCy Schubert /* =====
2982b15cb3dSCy Schubert The POSIX clock_gettime() interface provides a few ways to get at a
2992b15cb3dSCy Schubert monotonic clock. CLOCK_MONOTONIC is most widely supported. Linux also
3002b15cb3dSCy Schubert provides a CLOCK_MONOTONIC_COARSE with accuracy of about 1-4 msec.
3012b15cb3dSCy Schubert
3022b15cb3dSCy Schubert On all platforms I'm aware of, CLOCK_MONOTONIC really is monotonic.
3032b15cb3dSCy Schubert Platforms don't agree about whether it should jump on a sleep/resume.
3042b15cb3dSCy Schubert */
3052b15cb3dSCy Schubert
3062b15cb3dSCy Schubert int
evutil_configure_monotonic_time_(struct evutil_monotonic_timer * base,int flags)3072b15cb3dSCy Schubert evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
3082b15cb3dSCy Schubert int flags)
3092b15cb3dSCy Schubert {
3102b15cb3dSCy Schubert /* CLOCK_MONOTONIC exists on FreeBSD, Linux, and Solaris. You need to
3112b15cb3dSCy Schubert * check for it at runtime, because some older kernel versions won't
3122b15cb3dSCy Schubert * have it working. */
3132b15cb3dSCy Schubert #ifdef CLOCK_MONOTONIC_COARSE
3142b15cb3dSCy Schubert const int precise = flags & EV_MONOT_PRECISE;
3152b15cb3dSCy Schubert #endif
3162b15cb3dSCy Schubert const int fallback = flags & EV_MONOT_FALLBACK;
3172b15cb3dSCy Schubert struct timespec ts;
3182b15cb3dSCy Schubert
3192b15cb3dSCy Schubert #ifdef CLOCK_MONOTONIC_COARSE
3202b15cb3dSCy Schubert if (CLOCK_MONOTONIC_COARSE < 0) {
3212b15cb3dSCy Schubert /* Technically speaking, nothing keeps CLOCK_* from being
3222b15cb3dSCy Schubert * negative (as far as I know). This check and the one below
3232b15cb3dSCy Schubert * make sure that it's safe for us to use -1 as an "unset"
3242b15cb3dSCy Schubert * value. */
3252b15cb3dSCy Schubert event_errx(1,"I didn't expect CLOCK_MONOTONIC_COARSE to be < 0");
3262b15cb3dSCy Schubert }
3272b15cb3dSCy Schubert if (! precise && ! fallback) {
3282b15cb3dSCy Schubert if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) == 0) {
3292b15cb3dSCy Schubert base->monotonic_clock = CLOCK_MONOTONIC_COARSE;
3302b15cb3dSCy Schubert return 0;
3312b15cb3dSCy Schubert }
3322b15cb3dSCy Schubert }
3332b15cb3dSCy Schubert #endif
3342b15cb3dSCy Schubert if (!fallback && clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
3352b15cb3dSCy Schubert base->monotonic_clock = CLOCK_MONOTONIC;
3362b15cb3dSCy Schubert return 0;
3372b15cb3dSCy Schubert }
3382b15cb3dSCy Schubert
3392b15cb3dSCy Schubert if (CLOCK_MONOTONIC < 0) {
3402b15cb3dSCy Schubert event_errx(1,"I didn't expect CLOCK_MONOTONIC to be < 0");
3412b15cb3dSCy Schubert }
3422b15cb3dSCy Schubert
3432b15cb3dSCy Schubert base->monotonic_clock = -1;
3442b15cb3dSCy Schubert return 0;
3452b15cb3dSCy Schubert }
3462b15cb3dSCy Schubert
3472b15cb3dSCy Schubert int
evutil_gettime_monotonic_(struct evutil_monotonic_timer * base,struct timeval * tp)3482b15cb3dSCy Schubert evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
3492b15cb3dSCy Schubert struct timeval *tp)
3502b15cb3dSCy Schubert {
3512b15cb3dSCy Schubert struct timespec ts;
3522b15cb3dSCy Schubert
3532b15cb3dSCy Schubert if (base->monotonic_clock < 0) {
3542b15cb3dSCy Schubert if (evutil_gettimeofday(tp, NULL) < 0)
3552b15cb3dSCy Schubert return -1;
3562b15cb3dSCy Schubert adjust_monotonic_time(base, tp);
3572b15cb3dSCy Schubert return 0;
3582b15cb3dSCy Schubert }
3592b15cb3dSCy Schubert
3602b15cb3dSCy Schubert if (clock_gettime(base->monotonic_clock, &ts) == -1)
3612b15cb3dSCy Schubert return -1;
3622b15cb3dSCy Schubert tp->tv_sec = ts.tv_sec;
3632b15cb3dSCy Schubert tp->tv_usec = ts.tv_nsec / 1000;
3642b15cb3dSCy Schubert
3652b15cb3dSCy Schubert return 0;
3662b15cb3dSCy Schubert }
3672b15cb3dSCy Schubert #endif
3682b15cb3dSCy Schubert
3692b15cb3dSCy Schubert #if defined(HAVE_MACH_MONOTONIC)
3702b15cb3dSCy Schubert /* ======
3712b15cb3dSCy Schubert Apple is a little late to the POSIX party. And why not? Instead of
3722b15cb3dSCy Schubert clock_gettime(), they provide mach_absolute_time(). Its units are not
3732b15cb3dSCy Schubert fixed; we need to use mach_timebase_info() to get the right functions to
3742b15cb3dSCy Schubert convert its units into nanoseconds.
3752b15cb3dSCy Schubert
3762b15cb3dSCy Schubert To all appearances, mach_absolute_time() seems to be honest-to-goodness
3772b15cb3dSCy Schubert monotonic. Whether it stops during sleep or not is unspecified in
3782b15cb3dSCy Schubert principle, and dependent on CPU architecture in practice.
3792b15cb3dSCy Schubert */
3802b15cb3dSCy Schubert
3812b15cb3dSCy Schubert int
evutil_configure_monotonic_time_(struct evutil_monotonic_timer * base,int flags)3822b15cb3dSCy Schubert evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
3832b15cb3dSCy Schubert int flags)
3842b15cb3dSCy Schubert {
3852b15cb3dSCy Schubert const int fallback = flags & EV_MONOT_FALLBACK;
3862b15cb3dSCy Schubert struct mach_timebase_info mi;
3872b15cb3dSCy Schubert memset(base, 0, sizeof(*base));
3882b15cb3dSCy Schubert /* OSX has mach_absolute_time() */
3892b15cb3dSCy Schubert if (!fallback &&
3902b15cb3dSCy Schubert mach_timebase_info(&mi) == 0 &&
3912b15cb3dSCy Schubert mach_absolute_time() != 0) {
3922b15cb3dSCy Schubert /* mach_timebase_info tells us how to convert
3932b15cb3dSCy Schubert * mach_absolute_time() into nanoseconds, but we
3942b15cb3dSCy Schubert * want to use microseconds instead. */
3952b15cb3dSCy Schubert mi.denom *= 1000;
3962b15cb3dSCy Schubert memcpy(&base->mach_timebase_units, &mi, sizeof(mi));
3972b15cb3dSCy Schubert } else {
3982b15cb3dSCy Schubert base->mach_timebase_units.numer = 0;
3992b15cb3dSCy Schubert }
4002b15cb3dSCy Schubert return 0;
4012b15cb3dSCy Schubert }
4022b15cb3dSCy Schubert
4032b15cb3dSCy Schubert int
evutil_gettime_monotonic_(struct evutil_monotonic_timer * base,struct timeval * tp)4042b15cb3dSCy Schubert evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
4052b15cb3dSCy Schubert struct timeval *tp)
4062b15cb3dSCy Schubert {
4072b15cb3dSCy Schubert ev_uint64_t abstime, usec;
4082b15cb3dSCy Schubert if (base->mach_timebase_units.numer == 0) {
4092b15cb3dSCy Schubert if (evutil_gettimeofday(tp, NULL) < 0)
4102b15cb3dSCy Schubert return -1;
4112b15cb3dSCy Schubert adjust_monotonic_time(base, tp);
4122b15cb3dSCy Schubert return 0;
4132b15cb3dSCy Schubert }
4142b15cb3dSCy Schubert
4152b15cb3dSCy Schubert abstime = mach_absolute_time();
4162b15cb3dSCy Schubert usec = (abstime * base->mach_timebase_units.numer)
4172b15cb3dSCy Schubert / (base->mach_timebase_units.denom);
4182b15cb3dSCy Schubert tp->tv_sec = usec / 1000000;
4192b15cb3dSCy Schubert tp->tv_usec = usec % 1000000;
4202b15cb3dSCy Schubert
4212b15cb3dSCy Schubert return 0;
4222b15cb3dSCy Schubert }
4232b15cb3dSCy Schubert #endif
4242b15cb3dSCy Schubert
4252b15cb3dSCy Schubert #if defined(HAVE_WIN32_MONOTONIC)
4262b15cb3dSCy Schubert /* =====
4272b15cb3dSCy Schubert Turn we now to Windows. Want monontonic time on Windows?
4282b15cb3dSCy Schubert
4292b15cb3dSCy Schubert Windows has QueryPerformanceCounter(), which gives time most high-
4302b15cb3dSCy Schubert resolution time. It's a pity it's not so monotonic in practice; it's
4312b15cb3dSCy Schubert also got some fun bugs, especially: with older Windowses, under
4322b15cb3dSCy Schubert virtualizations, with funny hardware, on multiprocessor systems, and so
4332b15cb3dSCy Schubert on. PEP418 [1] has a nice roundup of the issues here.
4342b15cb3dSCy Schubert
4352b15cb3dSCy Schubert There's GetTickCount64() on Vista and later, which gives a number of 1-msec
4362b15cb3dSCy Schubert ticks since startup. The accuracy here might be as bad as 10-20 msec, I
4372b15cb3dSCy Schubert hear. There's an undocumented function (NtSetTimerResolution) that
4382b15cb3dSCy Schubert allegedly increases the accuracy. Good luck!
4392b15cb3dSCy Schubert
4402b15cb3dSCy Schubert There's also GetTickCount(), which is only 32 bits, but seems to be
4412b15cb3dSCy Schubert supported on pre-Vista versions of Windows. Apparently, you can coax
4422b15cb3dSCy Schubert another 14 bits out of it, giving you 2231 years before rollover.
4432b15cb3dSCy Schubert
4442b15cb3dSCy Schubert The less said about timeGetTime() the better.
4452b15cb3dSCy Schubert
4462b15cb3dSCy Schubert "We don't care. We don't have to. We're the Phone Company."
4472b15cb3dSCy Schubert -- Lily Tomlin, SNL
4482b15cb3dSCy Schubert
4492b15cb3dSCy Schubert Our strategy, if precise timers are turned off, is to just use the best
4502b15cb3dSCy Schubert GetTickCount equivalent available. If we've been asked for precise timing,
4512b15cb3dSCy Schubert then we mostly[2] assume that GetTickCount is monotonic, and correct
4522b15cb3dSCy Schubert GetPerformanceCounter to approximate it.
4532b15cb3dSCy Schubert
4542b15cb3dSCy Schubert [1] http://www.python.org/dev/peps/pep-0418
4552b15cb3dSCy Schubert [2] Of course, we feed the Windows stuff into adjust_monotonic_time()
4562b15cb3dSCy Schubert anyway, just in case it isn't.
4572b15cb3dSCy Schubert
4582b15cb3dSCy Schubert */
4592b15cb3dSCy Schubert /*
4602b15cb3dSCy Schubert Parts of our logic in the win32 timer code here are closely based on
4612b15cb3dSCy Schubert BitTorrent's libUTP library. That code is subject to the following
4622b15cb3dSCy Schubert license:
4632b15cb3dSCy Schubert
4642b15cb3dSCy Schubert Copyright (c) 2010 BitTorrent, Inc.
4652b15cb3dSCy Schubert
4662b15cb3dSCy Schubert Permission is hereby granted, free of charge, to any person obtaining a
4672b15cb3dSCy Schubert copy of this software and associated documentation files (the
4682b15cb3dSCy Schubert "Software"), to deal in the Software without restriction, including
4692b15cb3dSCy Schubert without limitation the rights to use, copy, modify, merge, publish,
4702b15cb3dSCy Schubert distribute, sublicense, and/or sell copies of the Software, and to
4712b15cb3dSCy Schubert permit persons to whom the Software is furnished to do so, subject to
4722b15cb3dSCy Schubert the following conditions:
4732b15cb3dSCy Schubert
4742b15cb3dSCy Schubert The above copyright notice and this permission notice shall be included
4752b15cb3dSCy Schubert in all copies or substantial portions of the Software.
4762b15cb3dSCy Schubert
4772b15cb3dSCy Schubert THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
4782b15cb3dSCy Schubert OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
4792b15cb3dSCy Schubert MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
4802b15cb3dSCy Schubert NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
4812b15cb3dSCy Schubert LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
4822b15cb3dSCy Schubert OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
4832b15cb3dSCy Schubert WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4842b15cb3dSCy Schubert */
4852b15cb3dSCy Schubert
4862b15cb3dSCy Schubert static ev_uint64_t
evutil_GetTickCount_(struct evutil_monotonic_timer * base)4872b15cb3dSCy Schubert evutil_GetTickCount_(struct evutil_monotonic_timer *base)
4882b15cb3dSCy Schubert {
4892b15cb3dSCy Schubert if (base->GetTickCount64_fn) {
4902b15cb3dSCy Schubert /* Let's just use GetTickCount64 if we can. */
4912b15cb3dSCy Schubert return base->GetTickCount64_fn();
4922b15cb3dSCy Schubert } else if (base->GetTickCount_fn) {
4932b15cb3dSCy Schubert /* Greg Hazel assures me that this works, that BitTorrent has
4942b15cb3dSCy Schubert * done it for years, and this it won't turn around and
4952b15cb3dSCy Schubert * bite us. He says they found it on some game programmers'
4962b15cb3dSCy Schubert * forum some time around 2007.
4972b15cb3dSCy Schubert */
4982b15cb3dSCy Schubert ev_uint64_t v = base->GetTickCount_fn();
4992b15cb3dSCy Schubert return (DWORD)v | ((v >> 18) & 0xFFFFFFFF00000000);
5002b15cb3dSCy Schubert } else {
5012b15cb3dSCy Schubert /* Here's the fallback implementation. We have to use
5022b15cb3dSCy Schubert * GetTickCount() with its given signature, so we only get
5032b15cb3dSCy Schubert * 32 bits worth of milliseconds, which will roll ove every
5042b15cb3dSCy Schubert * 49 days or so. */
5052b15cb3dSCy Schubert DWORD ticks = GetTickCount();
5062b15cb3dSCy Schubert if (ticks < base->last_tick_count) {
5072b15cb3dSCy Schubert base->adjust_tick_count += ((ev_uint64_t)1) << 32;
5082b15cb3dSCy Schubert }
5092b15cb3dSCy Schubert base->last_tick_count = ticks;
5102b15cb3dSCy Schubert return ticks + base->adjust_tick_count;
5112b15cb3dSCy Schubert }
5122b15cb3dSCy Schubert }
5132b15cb3dSCy Schubert
5142b15cb3dSCy Schubert int
evutil_configure_monotonic_time_(struct evutil_monotonic_timer * base,int flags)5152b15cb3dSCy Schubert evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
5162b15cb3dSCy Schubert int flags)
5172b15cb3dSCy Schubert {
5182b15cb3dSCy Schubert const int precise = flags & EV_MONOT_PRECISE;
5192b15cb3dSCy Schubert const int fallback = flags & EV_MONOT_FALLBACK;
5202b15cb3dSCy Schubert HANDLE h;
5212b15cb3dSCy Schubert memset(base, 0, sizeof(*base));
5222b15cb3dSCy Schubert
5232b15cb3dSCy Schubert h = evutil_load_windows_system_library_(TEXT("kernel32.dll"));
5242b15cb3dSCy Schubert if (h != NULL && !fallback) {
5252b15cb3dSCy Schubert base->GetTickCount64_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount64");
5262b15cb3dSCy Schubert base->GetTickCount_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount");
5272b15cb3dSCy Schubert }
5282b15cb3dSCy Schubert
5292b15cb3dSCy Schubert base->first_tick = base->last_tick_count = evutil_GetTickCount_(base);
5302b15cb3dSCy Schubert if (precise && !fallback) {
5312b15cb3dSCy Schubert LARGE_INTEGER freq;
5322b15cb3dSCy Schubert if (QueryPerformanceFrequency(&freq)) {
5332b15cb3dSCy Schubert LARGE_INTEGER counter;
5342b15cb3dSCy Schubert QueryPerformanceCounter(&counter);
5352b15cb3dSCy Schubert base->first_counter = counter.QuadPart;
5362b15cb3dSCy Schubert base->usec_per_count = 1.0e6 / freq.QuadPart;
5372b15cb3dSCy Schubert base->use_performance_counter = 1;
5382b15cb3dSCy Schubert }
5392b15cb3dSCy Schubert }
5402b15cb3dSCy Schubert
5412b15cb3dSCy Schubert return 0;
5422b15cb3dSCy Schubert }
5432b15cb3dSCy Schubert
5442b15cb3dSCy Schubert static inline ev_int64_t
abs64(ev_int64_t i)5452b15cb3dSCy Schubert abs64(ev_int64_t i)
5462b15cb3dSCy Schubert {
5472b15cb3dSCy Schubert return i < 0 ? -i : i;
5482b15cb3dSCy Schubert }
5492b15cb3dSCy Schubert
5502b15cb3dSCy Schubert
5512b15cb3dSCy Schubert int
evutil_gettime_monotonic_(struct evutil_monotonic_timer * base,struct timeval * tp)5522b15cb3dSCy Schubert evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
5532b15cb3dSCy Schubert struct timeval *tp)
5542b15cb3dSCy Schubert {
5552b15cb3dSCy Schubert ev_uint64_t ticks = evutil_GetTickCount_(base);
5562b15cb3dSCy Schubert if (base->use_performance_counter) {
5572b15cb3dSCy Schubert /* Here's a trick we took from BitTorrent's libutp, at Greg
5582b15cb3dSCy Schubert * Hazel's recommendation. We use QueryPerformanceCounter for
5592b15cb3dSCy Schubert * our high-resolution timer, but use GetTickCount*() to keep
5602b15cb3dSCy Schubert * it sane, and adjust_monotonic_time() to keep it monotonic.
5612b15cb3dSCy Schubert */
5622b15cb3dSCy Schubert LARGE_INTEGER counter;
5632b15cb3dSCy Schubert ev_int64_t counter_elapsed, counter_usec_elapsed, ticks_elapsed;
5642b15cb3dSCy Schubert QueryPerformanceCounter(&counter);
5652b15cb3dSCy Schubert counter_elapsed = (ev_int64_t)
5662b15cb3dSCy Schubert (counter.QuadPart - base->first_counter);
5672b15cb3dSCy Schubert ticks_elapsed = ticks - base->first_tick;
5682b15cb3dSCy Schubert /* TODO: This may upset VC6. If you need this to work with
5692b15cb3dSCy Schubert * VC6, please supply an appropriate patch. */
5702b15cb3dSCy Schubert counter_usec_elapsed = (ev_int64_t)
5712b15cb3dSCy Schubert (counter_elapsed * base->usec_per_count);
5722b15cb3dSCy Schubert
5732b15cb3dSCy Schubert if (abs64(ticks_elapsed*1000 - counter_usec_elapsed) > 1000000) {
5742b15cb3dSCy Schubert /* It appears that the QueryPerformanceCounter()
5752b15cb3dSCy Schubert * result is more than 1 second away from
5762b15cb3dSCy Schubert * GetTickCount() result. Let's adjust it to be as
5772b15cb3dSCy Schubert * accurate as we can; adjust_monotnonic_time() below
5782b15cb3dSCy Schubert * will keep it monotonic. */
5792b15cb3dSCy Schubert counter_usec_elapsed = ticks_elapsed * 1000;
5802b15cb3dSCy Schubert base->first_counter = (ev_uint64_t) (counter.QuadPart - counter_usec_elapsed / base->usec_per_count);
5812b15cb3dSCy Schubert }
5822b15cb3dSCy Schubert tp->tv_sec = (time_t) (counter_usec_elapsed / 1000000);
5832b15cb3dSCy Schubert tp->tv_usec = counter_usec_elapsed % 1000000;
5842b15cb3dSCy Schubert
5852b15cb3dSCy Schubert } else {
5862b15cb3dSCy Schubert /* We're just using GetTickCount(). */
5872b15cb3dSCy Schubert tp->tv_sec = (time_t) (ticks / 1000);
5882b15cb3dSCy Schubert tp->tv_usec = (ticks % 1000) * 1000;
5892b15cb3dSCy Schubert }
5902b15cb3dSCy Schubert adjust_monotonic_time(base, tp);
5912b15cb3dSCy Schubert
5922b15cb3dSCy Schubert return 0;
5932b15cb3dSCy Schubert }
5942b15cb3dSCy Schubert #endif
5952b15cb3dSCy Schubert
5962b15cb3dSCy Schubert #if defined(HAVE_FALLBACK_MONOTONIC)
5972b15cb3dSCy Schubert /* =====
5982b15cb3dSCy Schubert And if none of the other options work, let's just use gettimeofday(), and
5992b15cb3dSCy Schubert ratchet it forward so that it acts like a monotonic timer, whether it
6002b15cb3dSCy Schubert wants to or not.
6012b15cb3dSCy Schubert */
6022b15cb3dSCy Schubert
6032b15cb3dSCy Schubert int
evutil_configure_monotonic_time_(struct evutil_monotonic_timer * base,int precise)6042b15cb3dSCy Schubert evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
6052b15cb3dSCy Schubert int precise)
6062b15cb3dSCy Schubert {
6072b15cb3dSCy Schubert memset(base, 0, sizeof(*base));
6082b15cb3dSCy Schubert return 0;
6092b15cb3dSCy Schubert }
6102b15cb3dSCy Schubert
6112b15cb3dSCy Schubert int
evutil_gettime_monotonic_(struct evutil_monotonic_timer * base,struct timeval * tp)6122b15cb3dSCy Schubert evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
6132b15cb3dSCy Schubert struct timeval *tp)
6142b15cb3dSCy Schubert {
6152b15cb3dSCy Schubert if (evutil_gettimeofday(tp, NULL) < 0)
6162b15cb3dSCy Schubert return -1;
6172b15cb3dSCy Schubert adjust_monotonic_time(base, tp);
6182b15cb3dSCy Schubert return 0;
6192b15cb3dSCy Schubert
6202b15cb3dSCy Schubert }
6212b15cb3dSCy Schubert #endif
622