summaryrefslogtreecommitdiff
path: root/libs/libevent/src/evutil_time.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libevent/src/evutil_time.c')
-rw-r--r--libs/libevent/src/evutil_time.c538
1 files changed, 0 insertions, 538 deletions
diff --git a/libs/libevent/src/evutil_time.c b/libs/libevent/src/evutil_time.c
deleted file mode 100644
index 8f53c66b68..0000000000
--- a/libs/libevent/src/evutil_time.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "event2/event-config.h"
-#include "evconfig-private.h"
-
-#ifdef _WIN32
-#include <winsock2.h>
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-#endif
-
-#include <sys/types.h>
-#ifdef EVENT__HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <errno.h>
-#include <limits.h>
-#ifndef EVENT__HAVE_GETTIMEOFDAY
-#include <sys/timeb.h>
-#endif
-#if !defined(EVENT__HAVE_NANOSLEEP) && !defined(EVENT_HAVE_USLEEP) && \
- !defined(_WIN32)
-#include <sys/select.h>
-#endif
-#include <time.h>
-#include <sys/stat.h>
-#include <string.h>
-
-#include "event2/util.h"
-#include "util-internal.h"
-#include "log-internal.h"
-#include "mm-internal.h"
-
-#ifndef EVENT__HAVE_GETTIMEOFDAY
-/* No gettimeofday; this must be windows. */
-int
-evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
-{
-#ifdef _MSC_VER
-#define U64_LITERAL(n) n##ui64
-#else
-#define U64_LITERAL(n) n##llu
-#endif
-
- /* Conversion logic taken from Tor, which in turn took it
- * from Perl. GetSystemTimeAsFileTime returns its value as
- * an unaligned (!) 64-bit value containing the number of
- * 100-nanosecond intervals since 1 January 1601 UTC. */
-#define EPOCH_BIAS U64_LITERAL(116444736000000000)
-#define UNITS_PER_SEC U64_LITERAL(10000000)
-#define USEC_PER_SEC U64_LITERAL(1000000)
-#define UNITS_PER_USEC U64_LITERAL(10)
- union {
- FILETIME ft_ft;
- ev_uint64_t ft_64;
- } ft;
-
- if (tv == NULL)
- return -1;
-
- GetSystemTimeAsFileTime(&ft.ft_ft);
-
- if (EVUTIL_UNLIKELY(ft.ft_64 < EPOCH_BIAS)) {
- /* Time before the unix epoch. */
- return -1;
- }
- ft.ft_64 -= EPOCH_BIAS;
- tv->tv_sec = (long) (ft.ft_64 / UNITS_PER_SEC);
- tv->tv_usec = (long) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
- return 0;
-}
-#endif
-
-#define MAX_SECONDS_IN_MSEC_LONG \
- (((LONG_MAX) - 999) / 1000)
-
-long
-evutil_tv_to_msec_(const struct timeval *tv)
-{
- if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG)
- return -1;
-
- return (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000);
-}
-
-/*
- Replacement for usleep on platforms that don't have one. Not guaranteed to
- be any more finegrained than 1 msec.
- */
-void
-evutil_usleep_(const struct timeval *tv)
-{
- if (!tv)
- return;
-#if defined(_WIN32)
- {
- long msec = evutil_tv_to_msec_(tv);
- Sleep((DWORD)msec);
- }
-#elif defined(EVENT__HAVE_NANOSLEEP)
- {
- struct timespec ts;
- ts.tv_sec = tv->tv_sec;
- ts.tv_nsec = tv->tv_usec*1000;
- nanosleep(&ts, NULL);
- }
-#elif defined(EVENT__HAVE_USLEEP)
- /* Some systems don't like to usleep more than 999999 usec */
- sleep(tv->tv_sec);
- usleep(tv->tv_usec);
-#else
- select(0, NULL, NULL, NULL, tv);
-#endif
-}
-
-/*
- This function assumes it's called repeatedly with a
- not-actually-so-monotonic time source whose outputs are in 'tv'. It
- implements a trivial ratcheting mechanism so that the values never go
- backwards.
- */
-static void
-adjust_monotonic_time(struct evutil_monotonic_timer *base,
- struct timeval *tv)
-{
- evutil_timeradd(tv, &base->adjust_monotonic_clock, tv);
-
- if (evutil_timercmp(tv, &base->last_time, <)) {
- /* Guess it wasn't monotonic after all. */
- struct timeval adjust;
- evutil_timersub(&base->last_time, tv, &adjust);
- evutil_timeradd(&adjust, &base->adjust_monotonic_clock,
- &base->adjust_monotonic_clock);
- *tv = base->last_time;
- }
- base->last_time = *tv;
-}
-
-/*
- Allocate a new struct evutil_monotonic_timer
- */
-struct evutil_monotonic_timer *
-evutil_monotonic_timer_new(void)
-{
- struct evutil_monotonic_timer *p = NULL;
-
- p = mm_malloc(sizeof(*p));
- if (!p) goto done;
-
- memset(p, 0, sizeof(*p));
-
- done:
- return p;
-}
-
-/*
- Free a struct evutil_monotonic_timer
- */
-void
-evutil_monotonic_timer_free(struct evutil_monotonic_timer *timer)
-{
- if (timer) {
- mm_free(timer);
- }
-}
-
-/*
- Set up a struct evutil_monotonic_timer for initial use
- */
-int
-evutil_configure_monotonic_time(struct evutil_monotonic_timer *timer,
- int flags)
-{
- return evutil_configure_monotonic_time_(timer, flags);
-}
-
-/*
- Query the current monotonic time
- */
-int
-evutil_gettime_monotonic(struct evutil_monotonic_timer *timer,
- struct timeval *tp)
-{
- return evutil_gettime_monotonic_(timer, tp);
-}
-
-
-#if defined(HAVE_POSIX_MONOTONIC)
-/* =====
- The POSIX clock_gettime() interface provides a few ways to get at a
- monotonic clock. CLOCK_MONOTONIC is most widely supported. Linux also
- provides a CLOCK_MONOTONIC_COARSE with accuracy of about 1-4 msec.
-
- On all platforms I'm aware of, CLOCK_MONOTONIC really is monotonic.
- Platforms don't agree about whether it should jump on a sleep/resume.
- */
-
-int
-evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
- int flags)
-{
- /* CLOCK_MONOTONIC exists on FreeBSD, Linux, and Solaris. You need to
- * check for it at runtime, because some older kernel versions won't
- * have it working. */
-#ifdef CLOCK_MONOTONIC_COARSE
- const int precise = flags & EV_MONOT_PRECISE;
-#endif
- const int fallback = flags & EV_MONOT_FALLBACK;
- struct timespec ts;
-
-#ifdef CLOCK_MONOTONIC_COARSE
- if (CLOCK_MONOTONIC_COARSE < 0) {
- /* Technically speaking, nothing keeps CLOCK_* from being
- * negative (as far as I know). This check and the one below
- * make sure that it's safe for us to use -1 as an "unset"
- * value. */
- event_errx(1,"I didn't expect CLOCK_MONOTONIC_COARSE to be < 0");
- }
- if (! precise && ! fallback) {
- if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) == 0) {
- base->monotonic_clock = CLOCK_MONOTONIC_COARSE;
- return 0;
- }
- }
-#endif
- if (!fallback && clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
- base->monotonic_clock = CLOCK_MONOTONIC;
- return 0;
- }
-
- if (CLOCK_MONOTONIC < 0) {
- event_errx(1,"I didn't expect CLOCK_MONOTONIC to be < 0");
- }
-
- base->monotonic_clock = -1;
- return 0;
-}
-
-int
-evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
- struct timeval *tp)
-{
- struct timespec ts;
-
- if (base->monotonic_clock < 0) {
- if (evutil_gettimeofday(tp, NULL) < 0)
- return -1;
- adjust_monotonic_time(base, tp);
- return 0;
- }
-
- if (clock_gettime(base->monotonic_clock, &ts) == -1)
- return -1;
- tp->tv_sec = ts.tv_sec;
- tp->tv_usec = ts.tv_nsec / 1000;
-
- return 0;
-}
-#endif
-
-#if defined(HAVE_MACH_MONOTONIC)
-/* ======
- Apple is a little late to the POSIX party. And why not? Instead of
- clock_gettime(), they provide mach_absolute_time(). Its units are not
- fixed; we need to use mach_timebase_info() to get the right functions to
- convert its units into nanoseconds.
-
- To all appearances, mach_absolute_time() seems to be honest-to-goodness
- monotonic. Whether it stops during sleep or not is unspecified in
- principle, and dependent on CPU architecture in practice.
- */
-
-int
-evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
- int flags)
-{
- const int fallback = flags & EV_MONOT_FALLBACK;
- struct mach_timebase_info mi;
- memset(base, 0, sizeof(*base));
- /* OSX has mach_absolute_time() */
- if (!fallback &&
- mach_timebase_info(&mi) == 0 &&
- mach_absolute_time() != 0) {
- /* mach_timebase_info tells us how to convert
- * mach_absolute_time() into nanoseconds, but we
- * want to use microseconds instead. */
- mi.denom *= 1000;
- memcpy(&base->mach_timebase_units, &mi, sizeof(mi));
- } else {
- base->mach_timebase_units.numer = 0;
- }
- return 0;
-}
-
-int
-evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
- struct timeval *tp)
-{
- ev_uint64_t abstime, usec;
- if (base->mach_timebase_units.numer == 0) {
- if (evutil_gettimeofday(tp, NULL) < 0)
- return -1;
- adjust_monotonic_time(base, tp);
- return 0;
- }
-
- abstime = mach_absolute_time();
- usec = (abstime * base->mach_timebase_units.numer)
- / (base->mach_timebase_units.denom);
- tp->tv_sec = usec / 1000000;
- tp->tv_usec = usec % 1000000;
-
- return 0;
-}
-#endif
-
-#if defined(HAVE_WIN32_MONOTONIC)
-/* =====
- Turn we now to Windows. Want monontonic time on Windows?
-
- Windows has QueryPerformanceCounter(), which gives time most high-
- resolution time. It's a pity it's not so monotonic in practice; it's
- also got some fun bugs, especially: with older Windowses, under
- virtualizations, with funny hardware, on multiprocessor systems, and so
- on. PEP418 [1] has a nice roundup of the issues here.
-
- There's GetTickCount64() on Vista and later, which gives a number of 1-msec
- ticks since startup. The accuracy here might be as bad as 10-20 msec, I
- hear. There's an undocumented function (NtSetTimerResolution) that
- allegedly increases the accuracy. Good luck!
-
- There's also GetTickCount(), which is only 32 bits, but seems to be
- supported on pre-Vista versions of Windows. Apparently, you can coax
- another 14 bits out of it, giving you 2231 years before rollover.
-
- The less said about timeGetTime() the better.
-
- "We don't care. We don't have to. We're the Phone Company."
- -- Lily Tomlin, SNL
-
- Our strategy, if precise timers are turned off, is to just use the best
- GetTickCount equivalent available. If we've been asked for precise timing,
- then we mostly[2] assume that GetTickCount is monotonic, and correct
- GetPerformanceCounter to approximate it.
-
- [1] http://www.python.org/dev/peps/pep-0418
- [2] Of course, we feed the Windows stuff into adjust_monotonic_time()
- anyway, just in case it isn't.
-
- */
-/*
- Parts of our logic in the win32 timer code here are closely based on
- BitTorrent's libUTP library. That code is subject to the following
- license:
-
- Copyright (c) 2010 BitTorrent, Inc.
-
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-static ev_uint64_t
-evutil_GetTickCount_(struct evutil_monotonic_timer *base)
-{
- if (base->GetTickCount64_fn) {
- /* Let's just use GetTickCount64 if we can. */
- return base->GetTickCount64_fn();
- } else if (base->GetTickCount_fn) {
- /* Greg Hazel assures me that this works, that BitTorrent has
- * done it for years, and this it won't turn around and
- * bite us. He says they found it on some game programmers'
- * forum some time around 2007.
- */
- ev_uint64_t v = base->GetTickCount_fn();
- return (DWORD)v | ((v >> 18) & 0xFFFFFFFF00000000);
- } else {
- /* Here's the fallback implementation. We have to use
- * GetTickCount() with its given signature, so we only get
- * 32 bits worth of milliseconds, which will roll ove every
- * 49 days or so. */
- DWORD ticks = GetTickCount();
- if (ticks < base->last_tick_count) {
- base->adjust_tick_count += ((ev_uint64_t)1) << 32;
- }
- base->last_tick_count = ticks;
- return ticks + base->adjust_tick_count;
- }
-}
-
-int
-evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
- int flags)
-{
- const int precise = flags & EV_MONOT_PRECISE;
- const int fallback = flags & EV_MONOT_FALLBACK;
- HANDLE h;
- memset(base, 0, sizeof(*base));
-
- h = evutil_load_windows_system_library_(TEXT("kernel32.dll"));
- if (h != NULL && !fallback) {
- base->GetTickCount64_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount64");
- base->GetTickCount_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount");
- }
-
- base->first_tick = base->last_tick_count = evutil_GetTickCount_(base);
- if (precise && !fallback) {
- LARGE_INTEGER freq;
- if (QueryPerformanceFrequency(&freq)) {
- LARGE_INTEGER counter;
- QueryPerformanceCounter(&counter);
- base->first_counter = counter.QuadPart;
- base->usec_per_count = 1.0e6 / freq.QuadPart;
- base->use_performance_counter = 1;
- }
- }
-
- return 0;
-}
-
-static inline ev_int64_t
-abs64(ev_int64_t i)
-{
- return i < 0 ? -i : i;
-}
-
-
-int
-evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
- struct timeval *tp)
-{
- ev_uint64_t ticks = evutil_GetTickCount_(base);
- if (base->use_performance_counter) {
- /* Here's a trick we took from BitTorrent's libutp, at Greg
- * Hazel's recommendation. We use QueryPerformanceCounter for
- * our high-resolution timer, but use GetTickCount*() to keep
- * it sane, and adjust_monotonic_time() to keep it monotonic.
- */
- LARGE_INTEGER counter;
- ev_int64_t counter_elapsed, counter_usec_elapsed, ticks_elapsed;
- QueryPerformanceCounter(&counter);
- counter_elapsed = (ev_int64_t)
- (counter.QuadPart - base->first_counter);
- ticks_elapsed = ticks - base->first_tick;
- /* TODO: This may upset VC6. If you need this to work with
- * VC6, please supply an appropriate patch. */
- counter_usec_elapsed = (ev_int64_t)
- (counter_elapsed * base->usec_per_count);
-
- if (abs64(ticks_elapsed*1000 - counter_usec_elapsed) > 1000000) {
- /* It appears that the QueryPerformanceCounter()
- * result is more than 1 second away from
- * GetTickCount() result. Let's adjust it to be as
- * accurate as we can; adjust_monotnonic_time() below
- * will keep it monotonic. */
- counter_usec_elapsed = ticks_elapsed * 1000;
- base->first_counter = (ev_uint64_t) (counter.QuadPart - counter_usec_elapsed / base->usec_per_count);
- }
- tp->tv_sec = (time_t) (counter_usec_elapsed / 1000000);
- tp->tv_usec = counter_usec_elapsed % 1000000;
-
- } else {
- /* We're just using GetTickCount(). */
- tp->tv_sec = (time_t) (ticks / 1000);
- tp->tv_usec = (ticks % 1000) * 1000;
- }
- adjust_monotonic_time(base, tp);
-
- return 0;
-}
-#endif
-
-#if defined(HAVE_FALLBACK_MONOTONIC)
-/* =====
- And if none of the other options work, let's just use gettimeofday(), and
- ratchet it forward so that it acts like a monotonic timer, whether it
- wants to or not.
- */
-
-int
-evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
- int precise)
-{
- memset(base, 0, sizeof(*base));
- return 0;
-}
-
-int
-evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
- struct timeval *tp)
-{
- if (evutil_gettimeofday(tp, NULL) < 0)
- return -1;
- adjust_monotonic_time(base, tp);
- return 0;
-
-}
-#endif