mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 13:04:23 -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 \
|
fcntl.h \
|
||||||
ifaddrs.h \
|
ifaddrs.h \
|
||||||
inttypes.h \
|
inttypes.h \
|
||||||
|
mach/mach_time.h \
|
||||||
netdb.h \
|
netdb.h \
|
||||||
netinet/in.h \
|
netinet/in.h \
|
||||||
netinet/in6.h \
|
netinet/in6.h \
|
||||||
@ -339,6 +340,7 @@ AC_CHECK_FUNCS([ \
|
|||||||
inet_ntop \
|
inet_ntop \
|
||||||
inet_pton \
|
inet_pton \
|
||||||
issetugid \
|
issetugid \
|
||||||
|
mach_absolute_time \
|
||||||
mmap \
|
mmap \
|
||||||
nanosleep \
|
nanosleep \
|
||||||
pipe \
|
pipe \
|
||||||
|
@ -58,6 +58,14 @@ extern "C" {
|
|||||||
#define EV_CLOSURE_SIGNAL 1
|
#define EV_CLOSURE_SIGNAL 1
|
||||||
#define EV_CLOSURE_PERSIST 2
|
#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. */
|
/** Structure to define the backend of a given event_base. */
|
||||||
struct eventop {
|
struct eventop {
|
||||||
/** The name of this backend. */
|
/** The name of this backend. */
|
||||||
@ -243,7 +251,7 @@ struct event_base {
|
|||||||
* too often. */
|
* too often. */
|
||||||
struct timeval tv_cache;
|
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
|
/** Difference between internal time (maybe from clock_gettime) and
|
||||||
* gettimeofday. */
|
* gettimeofday. */
|
||||||
struct timeval tv_clock_diff;
|
struct timeval tv_clock_diff;
|
||||||
|
61
event.c
61
event.c
@ -46,6 +46,9 @@
|
|||||||
#ifdef EVENT__HAVE_UNISTD_H
|
#ifdef EVENT__HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef EVENT__HAVE_MACH_MACH_TIME_H
|
||||||
|
#include <mach/mach_time.h>
|
||||||
|
#endif
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.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) \
|
#define EVENT_BASE_ASSERT_LOCKED(base) \
|
||||||
EVLOCK_ASSERT_LOCKED((base)->th_base_lock)
|
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
|
/* The first time this function is called, it sets use_monotonic to 1
|
||||||
* if we have a clock function that supports monotonic time */
|
* if we have a clock function that supports monotonic time */
|
||||||
static void
|
static void
|
||||||
detect_monotonic(void)
|
detect_monotonic(void)
|
||||||
{
|
{
|
||||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
|
||||||
struct timespec ts;
|
|
||||||
static int use_monotonic_initialized = 0;
|
static int use_monotonic_initialized = 0;
|
||||||
|
|
||||||
if (use_monotonic_initialized)
|
if (use_monotonic_initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||||
use_monotonic = 1;
|
{
|
||||||
|
/* 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;
|
||||||
|
|
||||||
use_monotonic_initialized = 1;
|
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||||
|
use_monotonic = 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
|
#endif
|
||||||
|
use_monotonic_initialized = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* How often (in seconds) do we check for changes in wall clock time relative
|
/* 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);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
|
||||||
if (use_monotonic) {
|
if (use_monotonic) {
|
||||||
|
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
|
||||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
|
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
tp->tv_sec = ts.tv_sec;
|
tp->tv_sec = ts.tv_sec;
|
||||||
tp->tv_usec = ts.tv_nsec / 1000;
|
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
|
if (base->last_updated_clock_diff + CLOCK_SYNC_INTERVAL
|
||||||
< ts.tv_sec) {
|
< tp->tv_sec) {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
evutil_gettimeofday(&tv,NULL);
|
evutil_gettimeofday(&tv,NULL);
|
||||||
evutil_timersub(&tv, tp, &base->tv_clock_diff);
|
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);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return (evutil_gettimeofday(tp, NULL));
|
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) {
|
if (base->tv_cache.tv_sec == 0) {
|
||||||
r = evutil_gettimeofday(tv, NULL);
|
r = evutil_gettimeofday(tv, NULL);
|
||||||
} else {
|
} else {
|
||||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
#ifdef HAVE_ANY_MONOTONIC
|
||||||
evutil_timeradd(&base->tv_cache, &base->tv_clock_diff, tv);
|
evutil_timeradd(&base->tv_cache, &base->tv_clock_diff, tv);
|
||||||
#else
|
#else
|
||||||
*tv = base->tv_cache;
|
*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)) {
|
if (tv != NULL && (flags & event & EV_TIMEOUT)) {
|
||||||
struct timeval tmp = ev->ev_timeout;
|
struct timeval tmp = ev->ev_timeout;
|
||||||
tmp.tv_usec &= MICROSECONDS_MASK;
|
tmp.tv_usec &= MICROSECONDS_MASK;
|
||||||
#if defined(EVENT__HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
#ifdef HAVE_ANY_MONOTONIC
|
||||||
/* correctly remamp to real time */
|
/* correctly remamp to real time */
|
||||||
evutil_timeradd(&ev->ev_base->tv_clock_diff, &tmp, tv);
|
evutil_timeradd(&ev->ev_base->tv_clock_diff, &tmp, tv);
|
||||||
#else
|
#else
|
||||||
@ -3125,7 +3158,7 @@ dump_inserted_event_fn(struct event_base *base, struct event *e, void *arg)
|
|||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
tv.tv_sec = e->ev_timeout.tv_sec;
|
tv.tv_sec = e->ev_timeout.tv_sec;
|
||||||
tv.tv_usec = e->ev_timeout.tv_usec & MICROSECONDS_MASK;
|
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);
|
evutil_timeradd(&tv, &base->tv_clock_diff, &tv);
|
||||||
#endif
|
#endif
|
||||||
fprintf(output, " Timeout=%ld.%06d",
|
fprintf(output, " Timeout=%ld.%06d",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user