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