From ef401997d311c8ba84f5c36bf94a9239ecaf9a5f Mon Sep 17 00:00:00 2001 From: Richard Nyberg Date: Thu, 29 Jan 2009 17:00:40 +0100 Subject: [PATCH] Make the timer code work on MacOS as well. --- btpd/main.c | 5 ++--- configure.ac | 23 ++++++++++++++++++++--- evloop/evloop.h | 1 + evloop/timer.c | 39 +++++++++++++++++++++++++++++++++------ 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/btpd/main.c b/btpd/main.c index c31fa53..f735ec2 100644 --- a/btpd/main.c +++ b/btpd/main.c @@ -35,9 +35,8 @@ setup_daemon(int daemonize, const char *dir) if (snprintf(NULL, 0, "btpd") != 4) btpd_err("snprintf doesn't work.\n"); - if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) - btpd_err("clock_gettime(CLOCK_MONOTONIC, ...) failed (%s).\n", - strerror(errno)); + if (evtimer_gettime(&ts) != 0) + btpd_err("evtimer_gettime failed (%s).\n", strerror(errno)); if (dir == NULL) { if ((dir = find_btpd_dir()) == NULL) diff --git a/configure.ac b/configure.ac index 8fd64e4..e56a971 100644 --- a/configure.ac +++ b/configure.ac @@ -41,15 +41,32 @@ AC_ARG_WITH(evloop-method, old_LIBS=$LIBS LIBS="" -AC_SEARCH_LIBS(clock_gettime, rt,,AC_MSG_FAILURE(btpd needs clock_gettime)) -AC_SUBST(CLOCKLIB,$LIBS) -LIBS="" AC_SEARCH_LIBS(inet_ntop, nsl,,AC_MSG_FAILURE(btpd needs inet_ntop)) AC_SEARCH_LIBS(bind, socket,,AC_MSG_FAILURE(btpd needs bind)) AC_SUBST(INETLIBS,$LIBS) LIBS=$old_LIBS AC_CHECK_FUNCS(asprintf) +AC_MSG_CHECKING(for CLOCK_MONOTONIC) +AC_COMPILE_IFELSE([ + #include + #include + int main(void) { return clock_gettime(CLOCK_MONOTONIC, (void *)0); } +], clock_gettime=yes, clock_gettime=no) +AC_MSG_RESULT($clock_gettime) +if test $clock_gettime == yes; then + old_LIBS=$LIBS + LIBS="" + AC_SEARCH_LIBS(clock_gettime,rt,clock_gettime=yes,clock_gettime=no) + AC_SUBST(CLOCKLIB,$LIBS) + LIBS=$old_LIBS + AC_DEFINE(HAVE_CLOCK_MONOTONIC) +fi +if test $clock_gettime == no; then + AC_CHECK_FUNCS(mach_absolute_time,, + AC_MSG_FAILURE(no supported time mechanism found)) +fi + AC_MSG_CHECKING(whether compiler accepts -Wno-pointer-sign) CC_ARGS_OK_IFELSE(-Wno-pointer-sign, AC_SUBST(WARNNPS,"-Wno-pointer-sign") diff --git a/evloop/evloop.h b/evloop/evloop.h index 55589aa..44f8803 100644 --- a/evloop/evloop.h +++ b/evloop/evloop.h @@ -53,5 +53,6 @@ void evtimer_del(struct timeout *); void evtimers_run(void); struct timespec evtimer_delay(void); +int evtimer_gettime(struct timespec *); #endif diff --git a/evloop/timer.c b/evloop/timer.c index 3174c08..d115959 100644 --- a/evloop/timer.c +++ b/evloop/timer.c @@ -3,12 +3,39 @@ #include "evloop.h" #include "timeheap.h" -#if defined(CLOCK_MONOTONIC_FAST) +#if defined(HAVE_CLOCK_MONOTONIC) + +#ifdef CLOCK_MONOTONIC_FAST #define TIMER_CLOCK CLOCK_MONOTONIC_FAST -#elif defined(CLOCK_MONOTONIC) +#else #define TIMER_CLOCK CLOCK_MONOTONIC +#endif + +int +evtimer_gettime(struct timespec *ts) +{ + return clock_gettime(TIMER_CLOCK, ts); +} + +#elif defined(HAVE_MACH_ABSOLUTE_TIME) + +#include + +int +evtimer_gettime(struct timespec *ts) +{ + uint64_t nsecs; + static mach_timebase_info_data_t nsratio = { 0, 0 }; + if (nsratio.denom == 0) + mach_timebase_info(&nsratio); + nsecs = mach_absolute_time() * nsratio.numer / nsratio.denom; + ts->tv_sec = nsecs / 1000000000; + ts->tv_nsec = nsecs - ts->tv_sec * 1000000000; + return 0; +} + #else -#error CLOCK_MONOTONIC needed! +#error No supported time mechanism #endif static struct timespec @@ -50,7 +77,7 @@ int evtimer_add(struct timeout *h, struct timespec *t) { struct timespec now, sum; - clock_gettime(TIMER_CLOCK, &now); + evtimer_gettime(&now); sum = addtime(now, *t); if (h->th.i == -1) return timeheap_insert(&h->th, &sum); @@ -73,7 +100,7 @@ void evtimers_run(void) { struct timespec now; - clock_gettime(TIMER_CLOCK, &now); + evtimer_gettime(&now); while (timeheap_size() > 0) { struct timespec diff = subtime(timeheap_top(), now); if (diff.tv_sec < 0) { @@ -93,7 +120,7 @@ evtimer_delay(void) diff.tv_sec = -1; diff.tv_nsec = 0; } else { - clock_gettime(TIMER_CLOCK, &now); + evtimer_gettime(&now); diff = subtime(timeheap_top(), now); if (diff.tv_sec < 0) { diff.tv_sec = 0;