From d5e1d5ad99d4a1dd05f3c72cbbd9a985ef43fcf3 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 17 Apr 2012 15:16:08 -0400 Subject: [PATCH] Implement a GetTickCount-based monotonic timer for Windows --- event-internal.h | 7 +++++++ event.c | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/event-internal.h b/event-internal.h index 6910469c..a2fc8e80 100644 --- a/event-internal.h +++ b/event-internal.h @@ -68,6 +68,8 @@ extern "C" { #define HAVE_ANY_MONOTONIC 1 #elif defined(EVENT__HAVE_MACH_ABSOLUTE_TIME) #define HAVE_ANY_MONOTONIC 1 +#elif defined(_WIN32) +#define HAVE_ANY_MONOTONIC 1 #endif /** Structure to define the backend of a given event_base. */ @@ -262,8 +264,13 @@ struct event_base { #define CLOCK_IS_SELECTED int monotonic_clock; #endif +#ifdef _WIN32 + DWORD last_tick_count; + struct timeval adjust_tick_count; +#endif #if defined(HAVE_ANY_MONOTONIC) /** True iff we should use our system's monotonic time implementation */ + /* TODO: Support systems where we don't need to detct monotonic time */ int use_monotonic; /** Difference between internal time (maybe from clock_gettime) and * gettimeofday. */ diff --git a/event.c b/event.c index fe55e216..c1d00eb3 100644 --- a/event.c +++ b/event.c @@ -375,6 +375,8 @@ detect_monotonic(struct event_base *base, const struct event_config *cfg) memcpy(&base->mach_timebase_units, &mi, sizeof(mi)); } } +#elif defined(_WIN32) + base->use_monotonic = 1; #endif } @@ -418,6 +420,23 @@ gettime(struct event_base *base, struct timeval *tp) / (base->mach_timebase_units.denom); tp->tv_sec = usec / 1000000; tp->tv_usec = usec % 1000000; +#elif defined(_WIN32) + /* TODO: Support GetTickCount64. */ + /* TODO: Support alternate timer backends if the user asked + * for a high-precision timer. QueryPerformanceCounter is + * possibly a good idea, but it is also supposed to have + * reliability issues under various circumstances. */ + DWORD ticks = GetTickCount(); + if (ticks < base->last_tick_count) { + /* The 32-bit timer rolled over. Let's assume it only + * happened once. Add 2**32 msec to adjust_tick_count. */ + const struct timeval tv_rollover = { 4294967, 296000 }; + evutil_timeradd(&tv_rollover, &base->adjust_tick_count, &base->adjust_tick_count); + } + base->last_tick_count = ticks; + tp->tv_sec = ticks / 1000; + tp->tv_usec = (ticks % 1000) * 1000; + evutil_timeradd(tp, &base->adjust_tick_count, tp); #else #error "Missing monotonic time implementation." #endif