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