Patch should solve problem with ntp and corosync (what it really does) by using clock_gettime.
I tried to find EVERY appearance of gettimeofday and where it makes sense (so basically, where this value is used as timer) convert to call clock_gettime. Patch modifies configure.ac to detect if clock_gettime and CLOCK_MONOTONIC exists on system. If not, gettimeofday will be used (so you will get old behavior). Comments are welcomed. Regards, Honza
commit 5d2bd8a98f378452a0a7737b7bc990a0c22a2b2f Author: Jan Friesse <jfrie...@redhat.com> Date: Tue Jul 21 15:33:52 2009 +0200 Support for monotime timer This patch should solve problems with corosync and ntp, by using clock_gettime where is available (this is why configure.ac is modified), and when using this functions make sense. diff --git a/trunk/configure.ac b/trunk/configure.ac index bff779a..2d5b5bc 100644 --- a/trunk/configure.ac +++ b/trunk/configure.ac @@ -107,6 +107,26 @@ AC_CHECK_FUNCS([alarm alphasort atexit bzero dup2 endgrent endpwent fcntl \ pthread_spin_unlock pthread_setschedparam \ sched_get_priority_max sched_setscheduler]) +# Check for time souce to use (monotonic in function clock_gettime, or gettimeofday) +if test "x$USE_GETTIMEOFDAY" = "x" +then + AC_CHECK_FUNCS([clock_gettime], + dnl clock_gettime() found + [AC_CHECK_DECLS([CLOCK_MONOTONIC],AC_DEFINE([USE_CLOCK_MONOTONIC],,[Clock type to use]), + dnl no CLOCK_MONOTONIC + [AC_CHECK_FUNCS([gettimeofday],AC_DEFINE([USE_GETTIMEOFDAY],,[Clock type to use]),AC_MSG_ERROR([No suitable clock found]))], + dnl for CLOCK_MONOTONIC + [#include <time.h>])], + dnl clock_gettime() not found + [AC_CHECK_FUNCS([gettimeofday],AC_DEFINE([USE_GETTIMEOFDAY],,[Clock type to use]),AC_MSG_ERROR([No suitable clock found]))] + ) +else + AC_MSG_NOTICE([Forced to use gettimeofday()]) + AC_CHECK_FUNCS([gettimeofday],AC_DEFINE([USE_GETTIMEOFDAY],,[Clock type to use]),AC_MSG_ERROR([No suitable clock found])) + AC_CHECK_FUNCS([clock_gettime]) + AC_CHECK_TYPES([clockid_t]) +fi + AC_CONFIG_FILES([Makefile exec/Makefile include/Makefile diff --git a/trunk/exec/timer.c b/trunk/exec/timer.c index 69f9a95..e5a419a 100644 --- a/trunk/exec/timer.c +++ b/trunk/exec/timer.c @@ -174,7 +174,7 @@ int corosync_timer_init ( } int corosync_timer_add_absolute ( - unsigned long long nanosec_from_epoch, + unsigned long long expire_time, void *data, void (*timer_fn) (void *data), timer_handle *handle) @@ -193,7 +193,7 @@ int corosync_timer_add_absolute ( &timers_timerlist, timer_fn, data, - nanosec_from_epoch, + expire_time, handle); if (unlock) { diff --git a/trunk/exec/timer.h b/trunk/exec/timer.h index 3df9d36..9f13170 100644 --- a/trunk/exec/timer.h +++ b/trunk/exec/timer.h @@ -49,7 +49,7 @@ extern int corosync_timer_add_duration ( corosync_timer_handle *handle); extern int corosync_timer_add_absolute ( - unsigned long long nanoseconds_from_epoch, + unsigned long long expire_time, void *data, void (*timer_fn) (void *data), corosync_timer_handle *handle); diff --git a/trunk/exec/tlist.h b/trunk/exec/tlist.h index 263c8d7..1a08398 100644 --- a/trunk/exec/tlist.h +++ b/trunk/exec/tlist.h @@ -61,7 +61,7 @@ struct timerlist { struct timerlist_timer { struct list_head list; - unsigned long long nano_from_epoch; + unsigned long long expire_time; void (*timer_fn)(void *data); void *data; timer_handle handle_addr; @@ -82,6 +82,30 @@ static inline unsigned long long timerlist_nano_from_epoch (void) return (nano_from_epoch); } +#ifdef USE_CLOCK_MONOTONIC +static inline unsigned long long timerlist_nano_monotonic_time (void) +{ + unsigned long long nano_monotonic; + struct timespec ts; + + clock_gettime (CLOCK_MONOTONIC, &ts); + + nano_monotonic = (ts.tv_sec * 1000000000ULL) + (unsigned long long )ts.tv_nsec; + return (nano_monotonic); +} + +static inline unsigned long long timerlist_nano_monotonic_hz (void) { + unsigned long long nano_monotonic_hz; + struct timespec ts; + + clock_getres (CLOCK_MONOTONIC, &ts); + + nano_monotonic_hz = ts.tv_sec + 1000000000ULL / (unsigned long long )ts.tv_nsec; + + return (nano_monotonic_hz); +} +#endif + static inline void timerlist_add (struct timerlist *timerlist, struct timerlist_timer *timer) { struct list_head *timer_list = 0; @@ -95,7 +119,7 @@ static inline void timerlist_add (struct timerlist *timerlist, struct timerlist_ timer_from_list = list_entry (timer_list, struct timerlist_timer, list); - if (timer_from_list->nano_from_epoch > timer->nano_from_epoch) { + if (timer_from_list->expire_time > timer->expire_time) { list_add (&timer->list, timer_list->prev); found = 1; break; /* for timer iteration */ @@ -109,7 +133,7 @@ static inline void timerlist_add (struct timerlist *timerlist, struct timerlist_ static inline int timerlist_add_absolute (struct timerlist *timerlist, void (*timer_fn) (void *data), void *data, - unsigned long long nano_from_epoch, + unsigned long long expire_time, timer_handle *handle) { struct timerlist_timer *timer; @@ -120,7 +144,7 @@ static inline int timerlist_add_absolute (struct timerlist *timerlist, return (-1); } - timer->nano_from_epoch = nano_from_epoch; + timer->expire_time = expire_time; timer->data = data; timer->timer_fn = timer_fn; timer->handle_addr = handle; @@ -144,7 +168,11 @@ static inline int timerlist_add_duration (struct timerlist *timerlist, return (-1); } - timer->nano_from_epoch = timerlist_nano_from_epoch() + nano_duration; +#ifdef USE_CLOCK_MONOTONIC + timer->expire_time= timerlist_nano_monotonic_time() + nano_duration; +#else + timer->expire_time = timerlist_nano_from_epoch() + nano_duration; +#endif timer->data = data; timer->timer_fn = timer_fn; timer->handle_addr = handle; @@ -177,7 +205,7 @@ static inline unsigned long long timerlist_expire_time (struct timerlist *timerl { struct timerlist_timer *timer = (struct timerlist_timer *)_timer_handle; - return (timer->nano_from_epoch); + return (timer->expire_time); } static inline void timerlist_pre_dispatch (struct timerlist *timerlist, timer_handle _timer_handle) @@ -202,7 +230,7 @@ static inline void timerlist_post_dispatch (struct timerlist *timerlist, timer_h static inline unsigned long long timerlist_msec_duration_to_expire (struct timerlist *timerlist) { struct timerlist_timer *timer_from_list; - volatile unsigned long long nano_from_epoch; + volatile unsigned long long current_time; volatile unsigned long long msec_duration_to_expire; /* @@ -215,16 +243,19 @@ static inline unsigned long long timerlist_msec_duration_to_expire (struct timer timer_from_list = list_entry (timerlist->timer_head.next, struct timerlist_timer, list); - nano_from_epoch = timerlist_nano_from_epoch(); - +#ifdef USE_CLOCK_MONOTONIC + current_time = timerlist_nano_monotonic_time(); +#else + current_time = timerlist_nano_from_epoch(); +#endif /* * timer at head of list is expired, zero msecs required */ - if (timer_from_list->nano_from_epoch < nano_from_epoch) { + if (timer_from_list->expire_time < current_time) { return (0); } - msec_duration_to_expire = ((timer_from_list->nano_from_epoch - nano_from_epoch) / 1000000ULL) + + msec_duration_to_expire = ((timer_from_list->expire_time - current_time) / 1000000ULL) + (1000 / HZ); return (msec_duration_to_expire); } @@ -235,9 +266,13 @@ static inline unsigned long long timerlist_msec_duration_to_expire (struct timer static inline void timerlist_expire (struct timerlist *timerlist) { struct timerlist_timer *timer_from_list; - unsigned long long nano_from_epoch; + unsigned long long current_time; - nano_from_epoch = timerlist_nano_from_epoch(); +#ifdef USE_CLOCK_MONOTONIC + current_time = timerlist_nano_monotonic_time(); +#else + current_time = timerlist_nano_from_epoch(); +#endif for (timerlist->timer_iter = timerlist->timer_head.next; timerlist->timer_iter != &timerlist->timer_head;) { @@ -245,7 +280,7 @@ static inline void timerlist_expire (struct timerlist *timerlist) timer_from_list = list_entry (timerlist->timer_iter, struct timerlist_timer, list); - if (timer_from_list->nano_from_epoch < nano_from_epoch) { + if (timer_from_list->expire_time < current_time) { timerlist->timer_iter = timerlist->timer_iter->next; timerlist_pre_dispatch (timerlist, timer_from_list); diff --git a/trunk/exec/totemsrp.c b/trunk/exec/totemsrp.c index c5b5235..a03bd55 100644 --- a/trunk/exec/totemsrp.c +++ b/trunk/exec/totemsrp.c @@ -689,6 +689,19 @@ static unsigned int main_msgs_missing (void) return (0); } +static inline void get_monotonic_timeofday (struct timeval *tv) +{ +#ifdef USE_CLOCK_MONOTONIC + struct timespec ts; + clock_gettime (CLOCK_MONOTONIC, &ts); + + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000ULL; +#else + gettimeofday (&tv, NULL); +#endif +} + static int pause_flush (struct totemsrp_instance *instance) { struct timeval now; @@ -696,7 +709,8 @@ static int pause_flush (struct totemsrp_instance *instance) uint64_t timestamp_msec; int res = 0; - gettimeofday (&now, NULL); + get_monotonic_timeofday (&now); + now_msec = ((now.tv_sec * 1000ULL) + (now.tv_usec / 1000ULL)); timestamp_msec = ((instance->pause_timestamp.tv_sec * 1000ULL) + (instance->pause_timestamp.tv_usec/1000ULL)); @@ -845,7 +859,7 @@ int totemsrp_initialize ( instance->totemsrp_confchg_fn = confchg_fn; instance->use_heartbeat = 1; - gettimeofday (&instance->pause_timestamp, NULL); + get_monotonic_timeofday (&instance->pause_timestamp); if ( totem_config->heartbeat_failures_allowed == 0 ) { log_printf (instance->totemsrp_log_level_debug, @@ -1524,7 +1538,7 @@ static void timer_function_pause_timeout (void *data) { struct totemsrp_instance *instance = data; - gettimeofday (&instance->pause_timestamp, NULL); + get_monotonic_timeofday (&instance->pause_timestamp); reset_pause_timeout (instance); } @@ -3311,7 +3325,7 @@ static int message_handler_orf_token ( struct timeval tv_current; struct timeval tv_diff; - gettimeofday (&tv_current, NULL); + get_monotonic_timeofday (&tv_current); timersub (&tv_current, &tv_old, &tv_diff); memcpy (&tv_old, &tv_current, sizeof (struct timeval)); @@ -3555,7 +3569,7 @@ static int message_handler_orf_token ( token_send (instance, token, forward_token); #ifdef GIVEINFO - gettimeofday (&tv_current, NULL); + get_monotonic_timeofday (&tv_current); timersub (&tv_current, &tv_old, &tv_diff); memcpy (&tv_old, &tv_current, sizeof (struct timeval)); log_printf (instance->totemsrp_log_level_debug, diff --git a/trunk/services/pload.c b/trunk/services/pload.c index cf82bbc..0e6e4b5 100644 --- a/trunk/services/pload.c +++ b/trunk/services/pload.c @@ -349,6 +349,19 @@ struct timeval tv2; struct timeval tv_elapsed; int last_msg_no = 0; +static inline void get_monotonic_timeofday (struct timeval *tv) +{ +#ifdef USE_CLOCK_MONOTONIC + struct timespec ts; + clock_gettime (CLOCK_MONOTONIC, &ts); + + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000ULL; +#else + gettimeofday (&tv, NULL); +#endif +} + static void message_handler_req_exec_pload_mcast ( const void *msg, unsigned int nodeid) @@ -357,11 +370,11 @@ static void message_handler_req_exec_pload_mcast ( last_msg_no = pload_mcast->msg_code; if (msgs_delivered == 0) { - gettimeofday (&tv1, NULL); + get_monotonic_timeofday (&tv1); } msgs_delivered += 1; if (msgs_delivered == msgs_wanted) { - gettimeofday (&tv2, NULL); + get_monotonic_timeofday (&tv2); timersub (&tv2, &tv1, &tv_elapsed); printf ("%5d Writes ", msgs_delivered); printf ("%5d bytes per write ", msg_size); diff --git a/trunk/services/votequorum.c b/trunk/services/votequorum.c index 79855bf..b5d82b6 100644 --- a/trunk/services/votequorum.c +++ b/trunk/services/votequorum.c @@ -1305,6 +1305,19 @@ static void message_handler_req_lib_votequorum_leaving (void *conn, const void * LEAVE(); } +static inline void get_monotonic_timeofday (struct timeval *tv) +{ +#ifdef USE_CLOCK_MONOTONIC + struct timespec ts; + clock_gettime (CLOCK_MONOTONIC, &ts); + + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000ULL; +#else + gettimeofday (&tv, NULL); +#endif +} + static void quorum_device_timer_fn(void *arg) { struct timeval now; @@ -1312,7 +1325,7 @@ static void quorum_device_timer_fn(void *arg) ENTER(); if (!quorum_device || quorum_device->state == NODESTATE_DEAD) return; - gettimeofday(&now, NULL); + get_monotonic_timeofday (&now); if (quorum_device->last_hello.tv_sec + quorumdev_poll/1000 < now.tv_sec) { quorum_device->state = NODESTATE_DEAD; log_printf(LOGSYS_LEVEL_INFO, "lost contact with quorum device\n"); @@ -1395,7 +1408,7 @@ static void message_handler_req_lib_votequorum_qdisk_poll (void *conn, if (quorum_device) { if (req_lib_votequorum_qdisk_poll->state) { - gettimeofday(&quorum_device->last_hello, NULL); + get_monotonic_timeofday (&quorum_device->last_hello); if (quorum_device->state == NODESTATE_DEAD) { quorum_device->state = NODESTATE_MEMBER; recalculate_quorum(0, 0);
_______________________________________________ Openais mailing list Openais@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/openais