@@ -35,9 +35,8 @@ setup_daemon(int daemonize, const char *dir) | |||||
if (snprintf(NULL, 0, "btpd") != 4) | if (snprintf(NULL, 0, "btpd") != 4) | ||||
btpd_err("snprintf doesn't work.\n"); | 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 == NULL) { | ||||
if ((dir = find_btpd_dir()) == NULL) | if ((dir = find_btpd_dir()) == NULL) | ||||
@@ -41,15 +41,32 @@ AC_ARG_WITH(evloop-method, | |||||
old_LIBS=$LIBS | old_LIBS=$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(inet_ntop, nsl,,AC_MSG_FAILURE(btpd needs inet_ntop)) | ||||
AC_SEARCH_LIBS(bind, socket,,AC_MSG_FAILURE(btpd needs bind)) | AC_SEARCH_LIBS(bind, socket,,AC_MSG_FAILURE(btpd needs bind)) | ||||
AC_SUBST(INETLIBS,$LIBS) | AC_SUBST(INETLIBS,$LIBS) | ||||
LIBS=$old_LIBS | LIBS=$old_LIBS | ||||
AC_CHECK_FUNCS(asprintf) | AC_CHECK_FUNCS(asprintf) | ||||
AC_MSG_CHECKING(for CLOCK_MONOTONIC) | |||||
AC_COMPILE_IFELSE([ | |||||
#include <sys/time.h> | |||||
#include <time.h> | |||||
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) | AC_MSG_CHECKING(whether compiler accepts -Wno-pointer-sign) | ||||
CC_ARGS_OK_IFELSE(-Wno-pointer-sign, | CC_ARGS_OK_IFELSE(-Wno-pointer-sign, | ||||
AC_SUBST(WARNNPS,"-Wno-pointer-sign") | AC_SUBST(WARNNPS,"-Wno-pointer-sign") | ||||
@@ -53,5 +53,6 @@ void evtimer_del(struct timeout *); | |||||
void evtimers_run(void); | void evtimers_run(void); | ||||
struct timespec evtimer_delay(void); | struct timespec evtimer_delay(void); | ||||
int evtimer_gettime(struct timespec *); | |||||
#endif | #endif |
@@ -3,12 +3,39 @@ | |||||
#include "evloop.h" | #include "evloop.h" | ||||
#include "timeheap.h" | #include "timeheap.h" | ||||
#if defined(CLOCK_MONOTONIC_FAST) | |||||
#if defined(HAVE_CLOCK_MONOTONIC) | |||||
#ifdef CLOCK_MONOTONIC_FAST | |||||
#define TIMER_CLOCK CLOCK_MONOTONIC_FAST | #define TIMER_CLOCK CLOCK_MONOTONIC_FAST | ||||
#elif defined(CLOCK_MONOTONIC) | |||||
#else | |||||
#define TIMER_CLOCK CLOCK_MONOTONIC | #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 <mach/mach_time.h> | |||||
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 | #else | ||||
#error CLOCK_MONOTONIC needed! | |||||
#error No supported time mechanism | |||||
#endif | #endif | ||||
static struct timespec | static struct timespec | ||||
@@ -50,7 +77,7 @@ int | |||||
evtimer_add(struct timeout *h, struct timespec *t) | evtimer_add(struct timeout *h, struct timespec *t) | ||||
{ | { | ||||
struct timespec now, sum; | struct timespec now, sum; | ||||
clock_gettime(TIMER_CLOCK, &now); | |||||
evtimer_gettime(&now); | |||||
sum = addtime(now, *t); | sum = addtime(now, *t); | ||||
if (h->th.i == -1) | if (h->th.i == -1) | ||||
return timeheap_insert(&h->th, &sum); | return timeheap_insert(&h->th, &sum); | ||||
@@ -73,7 +100,7 @@ void | |||||
evtimers_run(void) | evtimers_run(void) | ||||
{ | { | ||||
struct timespec now; | struct timespec now; | ||||
clock_gettime(TIMER_CLOCK, &now); | |||||
evtimer_gettime(&now); | |||||
while (timeheap_size() > 0) { | while (timeheap_size() > 0) { | ||||
struct timespec diff = subtime(timeheap_top(), now); | struct timespec diff = subtime(timeheap_top(), now); | ||||
if (diff.tv_sec < 0) { | if (diff.tv_sec < 0) { | ||||
@@ -93,7 +120,7 @@ evtimer_delay(void) | |||||
diff.tv_sec = -1; | diff.tv_sec = -1; | ||||
diff.tv_nsec = 0; | diff.tv_nsec = 0; | ||||
} else { | } else { | ||||
clock_gettime(TIMER_CLOCK, &now); | |||||
evtimer_gettime(&now); | |||||
diff = subtime(timeheap_top(), now); | diff = subtime(timeheap_top(), now); | ||||
if (diff.tv_sec < 0) { | if (diff.tv_sec < 0) { | ||||
diff.tv_sec = 0; | diff.tv_sec = 0; | ||||