[ovs-dev] [PATCH] timeval: On 64-bit systems refresh time whenever it is requested.
Leo Alterman
lalterman at nicira.com
Wed Aug 8 00:00:59 UTC 2012
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 <lalterman at 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
More information about the dev
mailing list