On 09/21/2011 08:51 AM, Jan Friesse wrote: > This patch solves problems with aisexec and big time changes, by using > clock_gettime where it make sense. > > On systems without clock_gettime, availability and value of > _POSIX_MONOTONIC_CLOCK is tested, and non supported systems > uses old behaviour of gettimeofday. > > Signed-off-by: Jan Friesse <jfriesse@xxxxxxxxxx> Reviewed-by: Steven Dake <sdake@xxxxxxxxxx> great work Honza -steve > --- > branches/whitetank/Makefile.inc | 9 ++++ > branches/whitetank/exec/timer.h | 2 +- > branches/whitetank/exec/tlist.h | 80 +++++++++++++++++++++++++++++++++------ > 3 files changed, 78 insertions(+), 13 deletions(-) > > diff --git a/branches/whitetank/Makefile.inc b/branches/whitetank/Makefile.inc > index c94e820..8d4f976 100644 > --- a/branches/whitetank/Makefile.inc > +++ b/branches/whitetank/Makefile.inc > @@ -62,6 +62,11 @@ ifndef OPENAIS_BUILD > OPENAIS_BUILD=RELEASE > endif > > +# OPENAIS_RT can be defined to 1 to build with librt > +ifndef LINK_WITH_RT > + LINK_WITH_RT=1 > +endif > + > # OPENAIS_PROFILE > > # default CFLAGS, LDFLAGS > @@ -95,6 +100,10 @@ ifdef OPENAIS_PROFILE > LDFLAGS += -pg > endif > > +ifeq (${LINK_WITH_RT}, 1) > + LDFLAGS += -lrt > +endif > + > # platform specific CFLAGS, LDFLAGS > # > ifeq (${OPENAIS_COMPAT}, LINUX) > diff --git a/branches/whitetank/exec/timer.h b/branches/whitetank/exec/timer.h > index 45dd74f..6ddf159 100644 > --- a/branches/whitetank/exec/timer.h > +++ b/branches/whitetank/exec/timer.h > @@ -42,7 +42,7 @@ extern void openais_timer_init ( > void (*serialize_unlock) (void)); > > extern int openais_timer_add_duration ( > - unsigned long long nanoseconds_in_future, > + unsigned long long nanosec_duration, > void *data, > void (*timer_fn) (void *data), > openais_timer_handle *handle); > diff --git a/branches/whitetank/exec/tlist.h b/branches/whitetank/exec/tlist.h > index 6143e22..b549247 100644 > --- a/branches/whitetank/exec/tlist.h > +++ b/branches/whitetank/exec/tlist.h > @@ -42,6 +42,7 @@ > #include <errno.h> > #include <string.h> > #include <sys/param.h> > +#include <unistd.h> > > #include "../include/list.h" > > @@ -51,6 +52,13 @@ > > typedef void * timer_handle; > > +#define TIMERLIST_MS_IN_SEC 1000ULL > +#define TIMERLIST_US_IN_SEC 1000000ULL > +#define TIMERLIST_NS_IN_SEC 1000000000ULL > +#define TIMERLIST_US_IN_MSEC 1000ULL > +#define TIMERLIST_NS_IN_MSEC 1000000ULL > +#define TIMERLIST_NS_IN_USEC 1000ULL > + > struct timerlist { > struct list_head timer_head; > struct list_head *timer_iter; > @@ -58,7 +66,8 @@ struct timerlist { > > struct timerlist_timer { > struct list_head list; > - unsigned long long nano_from_epoch; > + unsigned long long expire_time; > + int is_absolute_timer; > void (*timer_fn)(void *data); > void *data; > timer_handle handle_addr; > @@ -75,10 +84,46 @@ static inline unsigned long long timerlist_nano_from_epoch (void) > struct timeval time_from_epoch; > gettimeofday (&time_from_epoch, 0); > > - nano_from_epoch = ((time_from_epoch.tv_sec * 1000000000ULL) + (time_from_epoch.tv_usec * 1000ULL)); > + nano_from_epoch = ((time_from_epoch.tv_sec * TIMERLIST_NS_IN_SEC) + > + (time_from_epoch.tv_usec * TIMERLIST_NS_IN_USEC)); > + > return (nano_from_epoch); > } > > +#if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0 > +static inline unsigned long long timerlist_nano_current_get (void) > +{ > + unsigned long long nano_monotonic; > + struct timespec ts; > + > + clock_gettime (CLOCK_MONOTONIC, &ts); > + > + nano_monotonic = (ts.tv_sec * TIMERLIST_NS_IN_SEC) + (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 = TIMERLIST_NS_IN_SEC / ((ts.tv_sec * TIMERLIST_NS_IN_SEC) + ts.tv_nsec); > + > + return (nano_monotonic_hz); > +} > +#else > +#warning "Your system doesn't support monotonic timer. gettimeofday will be used" > +static inline unsigned long long timerlist_nano_current_get (void) > +{ > + return (timerlist_nano_from_epoch ()); > +} > + > +static inline unsigned long long timerlist_nano_monotonic_hz (void) { > + return HZ; > +} > +#endif > + > static inline void timerlist_add (struct timerlist *timerlist, struct timerlist_timer *timer) > { > struct list_head *timer_list = 0; > @@ -92,7 +137,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 */ > @@ -117,7 +162,8 @@ static inline int timerlist_add_absolute (struct timerlist *timerlist, > return (-1); > } > > - timer->nano_from_epoch = nano_from_epoch; > + timer->expire_time = nano_from_epoch; > + timer->is_absolute_timer = 1; > timer->data = data; > timer->timer_fn = timer_fn; > timer->handle_addr = handle; > @@ -141,7 +187,8 @@ static inline int timerlist_add_duration (struct timerlist *timerlist, > return (-1); > } > > - timer->nano_from_epoch = timerlist_nano_from_epoch() + nano_duration; > + timer->expire_time = timerlist_nano_current_get () + nano_duration; > + timer->is_absolute_timer = 0; > timer->data = data; > timer->timer_fn = timer_fn; > timer->handle_addr = handle; > @@ -191,7 +238,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; > > /* > @@ -204,17 +251,21 @@ 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(); > + if (timer_from_list->is_absolute_timer) { > + current_time = timerlist_nano_from_epoch (); > + } else { > + current_time = timerlist_nano_current_get (); > + } > > /* > * 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) / TIMERLIST_NS_IN_MSEC) + > (1000 / HZ); > return (msec_duration_to_expire); > } > @@ -225,9 +276,12 @@ 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_from_epoch; > + unsigned long long current_monotonic_time; > + unsigned long long current_time; > > - nano_from_epoch = timerlist_nano_from_epoch(); > + current_monotonic_time = timerlist_nano_current_get (); > + current_time_from_epoch = current_time = timerlist_nano_from_epoch (); > > for (timerlist->timer_iter = timerlist->timer_head.next; > timerlist->timer_iter != &timerlist->timer_head;) { > @@ -235,7 +289,9 @@ 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) { > + current_time = (timer_from_list->is_absolute_timer ? current_time_from_epoch : current_monotonic_time); > + > + if (timer_from_list->expire_time < current_time) { > timerlist->timer_iter = timerlist->timer_iter->next; > > timerlist_pre_dispatch (timerlist, timer_from_list); _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss