64-bit glibc appears to avoid syscalls for clock_gettime(), so we can get higher resolution timing and avoid having a timer firing off SIGALRM without introducing extra overhead.
Signed-off-by: Leo Alterman <lalter...@nicira.com> --- lib/timeval.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/timeval.c b/lib/timeval.c index d29b661..a5068de 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -33,6 +33,19 @@ #include "util.h" #include "vlog.h" +/* On Linux IA64 systems, glibc avoids using syscalls for clock_gettime(). + * + * For systems which do invoke a system call we wait at least + * TIME_UPDATE_INTERVAL ms between clock_gettime() calls and cache the time for + * the interim. + * + * For systems which do not invoke a system call, we just call clock_gettime() + * whenever the time is requested. As a result we don't start the background + * SIGALRM timer unless explicitly needed by time_alarm() */ +#ifndef __LP64__ +#define CACHE_TIME 1 +#endif + VLOG_DEFINE_THIS_MODULE(timeval); /* The clock to use for measuring time intervals. This is CLOCK_MONOTONIC by @@ -40,7 +53,7 @@ VLOG_DEFINE_THIS_MODULE(timeval); * to CLOCK_REALTIME. */ static clockid_t monotonic_clock; -/* Has a timer tick occurred? +/* Has a timer tick occurred? Only relevant if CACHE_TIME is defined. * * We initialize these to true to force time_init() to get called on the first * call to time_msec() or another function that queries the current time. */ @@ -94,8 +107,11 @@ time_init(void) VLOG_DBG("monotonic timer not available"); } + #ifdef CACHE_TIME set_up_signal(SA_RESTART); set_up_timer(); + #endif + boot_time = time_msec(); } @@ -168,7 +184,16 @@ void time_postfork(void) { time_init(); + + #ifdef CACHE_TIME set_up_timer(); + #else + /* If we are not caching kernel time, the only reason the timer should + * exist is if time_alarm() was called and deadline is set */ + if (deadline != TIME_MIN) { + set_up_timer(); + } + #endif } static void @@ -199,7 +224,9 @@ refresh_monotonic(void) /* Forces a refresh of the current time from the kernel. It is not usually * necessary to call this function, since the time will be refreshed - * automatically at least every TIME_UPDATE_INTERVAL milliseconds. */ + * automatically at least every TIME_UPDATE_INTERVAL milliseconds. If + * CACHE_TIME is undefined, we will always refresh the current time so this + * function has no effect. */ void time_refresh(void) { @@ -275,9 +302,16 @@ time_alarm(unsigned int secs) sigset_t oldsigs; time_init(); + block_sigalrm(&oldsigs); deadline = secs ? time_add(time_now(), secs) : TIME_MIN; unblock_sigalrm(&oldsigs); + + /* If we aren't timing the gaps between kernel time refreshes we need to + * to start the timer up now */ + #ifndef CACHE_TIME + set_up_timer(); + #endif } /* Like poll(), except: @@ -366,17 +400,25 @@ sigalrm_handler(int sig_nr) static void refresh_wall_if_ticked(void) { + #ifdef CACHE_TIME if (wall_tick) { refresh_wall(); } + #else + refresh_wall(); + #endif } static void refresh_monotonic_if_ticked(void) { + #ifdef CACHE_TIME if (monotonic_tick) { refresh_monotonic(); } + #else + refresh_monotonic(); + #endif } static void -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev