[quagga-dev 5859] Re: Monotonic time, RFC

Joakim Tjernlund joakim.tjernlund at transmode.se
Tue Sep 2 13:38:12 BST 2008


On Mon, 2008-09-01 at 19:06 +0100, paul at clubi.ie wrote:
> On Mon, 1 Sep 2008, Joakim Tjernlund wrote:
> 
> > There were a problem with a patch which you commented
> > "Clearly something is wrong with refresh of external LSAs
> > this added hack around defaults not refreshing after a timer jump"
> > makes me think there is something lurking around in there.
> 
> Ah, I meant something wrong with refreshing, not with the underlying 
> time.
> 
> > Such hacks are not ideal and isn't needed when you got
> > an monotonic clock. times(2) has a one but in ticks so
> > it is only good for calculation of the relative difference.
> 
> Well, the internal monotonic timer works fine.
> 
> If we're going to change this, it's probably best to:
> 
> a) Enable the POSIX monotic timer HAVE_CLOCK_TIMER code
> 
> b) Whenever the march of time results in our supported platform list
>     all having this timer, we just excise our internal delta-timer. (I
>     guess the holdout is FreeBSD 4, but I havn't checked)
> 
> There's no point swapping our internal delta-timer hack for another 
> one.

Well, I could not resist :) What do you think of this?
No more jumps for relative time.

>From 3b949b4b2267f1d28b34427ad9f6749578482c7d Mon Sep 17 00:00:00 2001
From: Joakim Tjernlund <Joakim.Tjernlund at transmode.se>
Date: Tue, 2 Sep 2008 11:10:51 +0200
Subject: [PATCH] Use times(2) to calculate relative time.

times(2) is monotonic, use it to calculte relative_time
and scale the value using sysconf(_SC_CLK_TCK);

Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund at transmode.se>
---
 lib/thread.c |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/lib/thread.c b/lib/thread.c
index 260e8c8..4d63364 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -94,9 +94,27 @@ timeval_elapsed (struct timeval a, struct timeval b)
 }
 
 #ifndef HAVE_CLOCK_MONOTONIC
+static clock_t prev_clock_mark; /* Holds value of last call to times(2) */
+
 static void
 quagga_gettimeofday_relative_adjust (void)
 {
+#ifdef GNU_LINUX
+  static long clocks_per_sec;
+  clock_t clock_mark, diff;
+
+  if (!clocks_per_sec)
+      clocks_per_sec = sysconf(_SC_CLK_TCK);
+  clock_mark = times(NULL); /* Linux can handle NULL, but other OS:es needs a dummy value */
+  diff = clock_mark - prev_clock_mark;
+
+  /* save mark for next calculation */
+  prev_clock_mark = clock_mark;
+
+  relative_time.tv_sec += diff / clocks_per_sec; /* convert to seconds */
+  relative_time.tv_usec += ((diff % clocks_per_sec) * TIMER_SECOND_MICRO) / clocks_per_sec;
+  timeval_adjust (relative_time);
+#else
   struct timeval diff;
   if (timeval_cmp (recent_time, last_recent_time) < 0)
     {
@@ -110,6 +128,7 @@ quagga_gettimeofday_relative_adjust (void)
       relative_time.tv_usec += diff.tv_usec;
       relative_time = timeval_adjust (relative_time);
     }
+#endif
   last_recent_time = recent_time;
 }
 #endif /* !HAVE_CLOCK_MONOTONIC */
@@ -128,6 +147,9 @@ quagga_gettimeofday (struct timeval *tv)
       if (!timers_inited)
         {
           relative_time_base = last_recent_time = recent_time;
+#if defined(GNU_LINUX) && !defined(HAVE_CLOCK_MONOTONIC)
+	  prev_clock_mark = times(NULL); /* Linux can handle NULL, but others don't */
+#endif
           timers_inited = 1;
         }
       /* avoid copy if user passed recent_time pointer.. */
-- 
1.5.6.5





More information about the Quagga-dev mailing list