mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-09 12:28:19 -04:00
Use mach_absolute_time() for monotonic clock support on OSX.
This commit is contained in:
parent
a969f7e706
commit
b8fd6f918b
@ -198,6 +198,7 @@ AC_CHECK_HEADERS([ \
|
||||
fcntl.h \
|
||||
ifaddrs.h \
|
||||
inttypes.h \
|
||||
mach/mach_time.h \
|
||||
netdb.h \
|
||||
netinet/in.h \
|
||||
netinet/in6.h \
|
||||
@ -339,6 +340,7 @@ AC_CHECK_FUNCS([ \
|
||||
inet_ntop \
|
||||
inet_pton \
|
||||
issetugid \
|
||||
mach_absolute_time \
|
||||
mmap \
|
||||
nanosleep \
|
||||
pipe \
|
||||
|
@ -58,6 +58,14 @@ extern "C" {
|
||||
#define EV_CLOSURE_SIGNAL 1
|
||||
#define EV_CLOSURE_PERSIST 2
|
||||
|
||||
/* Define HAVE_ANY_MONOTONIC iff we *might* have a working monotonic
|
||||
* clock implementation */
|
||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
#define HAVE_ANY_MONOTONIC 1
|
||||
#elif defined(EVENT__HAVE_MACH_ABSOLUTE_TIME)
|
||||
#define HAVE_ANY_MONOTONIC 1
|
||||
#endif
|
||||
|
||||
/** Structure to define the backend of a given event_base. */
|
||||
struct eventop {
|
||||
/** The name of this backend. */
|
||||
@ -243,7 +251,7 @@ struct event_base {
|
||||
* too often. */
|
||||
struct timeval tv_cache;
|
||||
|
||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
#if defined(HAVE_ANY_MONOTONIC)
|
||||
/** Difference between internal time (maybe from clock_gettime) and
|
||||
* gettimeofday. */
|
||||
struct timeval tv_clock_diff;
|
||||
|
59
event.c
59
event.c
@ -46,6 +46,9 @@
|
||||
#ifdef EVENT__HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef EVENT__HAVE_MACH_MACH_TIME_H
|
||||
#include <mach/mach_time.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
@ -335,23 +338,45 @@ HT_GENERATE(event_debug_map, event_debug_entry, node, hash_debug_entry,
|
||||
#define EVENT_BASE_ASSERT_LOCKED(base) \
|
||||
EVLOCK_ASSERT_LOCKED((base)->th_base_lock)
|
||||
|
||||
#if defined(EVENT__HAVE_MACH_ABSOLUTE_TIME)
|
||||
struct mach_timebase_info mach_timebase_units;
|
||||
#endif
|
||||
|
||||
/* The first time this function is called, it sets use_monotonic to 1
|
||||
* if we have a clock function that supports monotonic time */
|
||||
static void
|
||||
detect_monotonic(void)
|
||||
{
|
||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
struct timespec ts;
|
||||
static int use_monotonic_initialized = 0;
|
||||
|
||||
if (use_monotonic_initialized)
|
||||
return;
|
||||
|
||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
{
|
||||
/* CLOCK_MONOTONIC exists on FreeBSD, Linux, and Solaris.
|
||||
* You need to check for it at runtime, because some older
|
||||
* versions won't have it working. */
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||
use_monotonic = 1;
|
||||
|
||||
use_monotonic_initialized = 1;
|
||||
}
|
||||
#elif defined(EVENT__HAVE_MACH_ABSOLUTE_TIME)
|
||||
{
|
||||
struct mach_timebase_info mi;
|
||||
/* OSX has mach_absolute_time() */
|
||||
if (mach_timebase_info(&mi) == 0 && mach_absolute_time() != 0) {
|
||||
use_monotonic = 1;
|
||||
/* mach_timebase_info tells us how to convert
|
||||
* mach_absolute_time() into nanoseconds, but we
|
||||
* want to use microseconds instead. */
|
||||
mi.denom *= 1000;
|
||||
memcpy(&mach_timebase_units, &mi, sizeof(mi));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
use_monotonic_initialized = 1;
|
||||
|
||||
}
|
||||
|
||||
/* How often (in seconds) do we check for changes in wall clock time relative
|
||||
@ -373,26 +398,34 @@ gettime(struct event_base *base, struct timeval *tp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
if (use_monotonic) {
|
||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
|
||||
return (-1);
|
||||
|
||||
tp->tv_sec = ts.tv_sec;
|
||||
tp->tv_usec = ts.tv_nsec / 1000;
|
||||
#elif defined(EVENT__HAVE_MACH_ABSOLUTE_TIME)
|
||||
uint64_t abstime = mach_absolute_time();
|
||||
uint64_t usec;
|
||||
usec = (abstime * mach_timebase_units.numer)
|
||||
/ (mach_timebase_units.denom);
|
||||
tp->tv_sec = usec / 1000000;
|
||||
tp->tv_usec = usec % 1000000;
|
||||
#else
|
||||
#error "Missing monotonic time implementation."
|
||||
#endif
|
||||
if (base->last_updated_clock_diff + CLOCK_SYNC_INTERVAL
|
||||
< ts.tv_sec) {
|
||||
< tp->tv_sec) {
|
||||
struct timeval tv;
|
||||
evutil_gettimeofday(&tv,NULL);
|
||||
evutil_timersub(&tv, tp, &base->tv_clock_diff);
|
||||
base->last_updated_clock_diff = ts.tv_sec;
|
||||
base->last_updated_clock_diff = tp->tv_sec;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (evutil_gettimeofday(tp, NULL));
|
||||
}
|
||||
@ -411,7 +444,7 @@ event_base_gettimeofday_cached(struct event_base *base, struct timeval *tv)
|
||||
if (base->tv_cache.tv_sec == 0) {
|
||||
r = evutil_gettimeofday(tv, NULL);
|
||||
} else {
|
||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
#ifdef HAVE_ANY_MONOTONIC
|
||||
evutil_timeradd(&base->tv_cache, &base->tv_clock_diff, tv);
|
||||
#else
|
||||
*tv = base->tv_cache;
|
||||
@ -2014,7 +2047,7 @@ event_pending(const struct event *ev, short event, struct timeval *tv)
|
||||
if (tv != NULL && (flags & event & EV_TIMEOUT)) {
|
||||
struct timeval tmp = ev->ev_timeout;
|
||||
tmp.tv_usec &= MICROSECONDS_MASK;
|
||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
#ifdef HAVE_ANY_MONOTONIC
|
||||
/* correctly remamp to real time */
|
||||
evutil_timeradd(&ev->ev_base->tv_clock_diff, &tmp, tv);
|
||||
#else
|
||||
@ -3125,7 +3158,7 @@ dump_inserted_event_fn(struct event_base *base, struct event *e, void *arg)
|
||||
struct timeval tv;
|
||||
tv.tv_sec = e->ev_timeout.tv_sec;
|
||||
tv.tv_usec = e->ev_timeout.tv_usec & MICROSECONDS_MASK;
|
||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
#if defined(HAVE_ANY_MONOTONIC)
|
||||
evutil_timeradd(&tv, &base->tv_clock_diff, &tv);
|
||||
#endif
|
||||
fprintf(output, " Timeout=%ld.%06d",
|
||||
|
Loading…
x
Reference in New Issue
Block a user