Don't die from assert() in timer_stop() if time goes backwards.
authorEmil Mikulic <emikulic@gmail.com>
Sat, 25 Jan 2014 09:18:46 +0000 (20:18 +1100)
committerEmil Mikulic <emikulic@gmail.com>
Sat, 25 Jan 2014 14:07:28 +0000 (01:07 +1100)
Makefile.in
now.c
str.h

index 907af0e..847d1b2 100644 (file)
@@ -148,6 +148,6 @@ http.o: http.c cdefs.h config.h conv.h err.h graph_db.h hosts_db.h addr.h \
 localip.o: localip.c addr.h bsd.h config.h conv.h err.h cdefs.h localip.h \
  now.h
 ncache.o: ncache.c conv.h err.h cdefs.h ncache.h tree.h bsd.h config.h
-now.o: now.c err.h cdefs.h now.h
+now.o: now.c err.h cdefs.h now.h str.h
 pidfile.o: pidfile.c err.h cdefs.h str.h pidfile.h
 str.o: str.c conv.h err.h cdefs.h str.h
diff --git a/now.c b/now.c
index dee49e3..ab72efa 100644 (file)
--- a/now.c
+++ b/now.c
@@ -17,6 +17,7 @@
  */
 #include "err.h"
 #include "now.h"
+#include "str.h"
 
 #include <assert.h>
 #include <string.h>
@@ -80,6 +81,17 @@ static int before(const struct timespec *a, const struct timespec *b) {
    return 0;
 }
 
+static void warn_backwards(const char *name,
+                           const struct timespec * const t0,
+                           const struct timespec * const t1) {
+   verbosef("%s clock went backwards from %lld.%09lld to %lld.%09lld",
+            name,
+            (lld)t0->tv_sec,
+            (lld)t0->tv_nsec,
+            (lld)t1->tv_sec,
+            (lld)t1->tv_nsec);
+}
+
 static void clock_update(const clockid_t clk_id,
                          struct timespec *dest,
                          const char *name) {
@@ -87,12 +99,7 @@ static void clock_update(const clockid_t clk_id,
 
    clock_gettime(clk_id, &t);
    if (now_initialized && before(&t, dest)) {
-      verbosef("%s clock went backwards from %ld.%09ld to %ld.%09ld",
-               name,
-               (long)dest->tv_sec,
-               (long)dest->tv_nsec,
-               (long)t.tv_sec,
-               (long)t.tv_nsec);
+      warn_backwards(name, &t, dest);
    }
    memcpy(dest, &t, sizeof(t));
 }
@@ -133,20 +140,24 @@ static int64_t ts_diff(const struct timespec * const a,
           a->tv_nsec - b->tv_nsec;
 }
 
-void timer_stop(const struct timespec * const t,
+void timer_stop(const struct timespec * const t0,
                 const int64_t nsec,
                 const char *warning) {
-   struct timespec t2;
+   struct timespec t1;
    int64_t diff;
 
-   clock_gettime(CLOCK_MONOTONIC, &t2);
-   diff = ts_diff(&t2, t);
-   assert(diff > 0);
-   if (diff > nsec)
+   clock_gettime(CLOCK_MONOTONIC, &t1);
+   if (before(&t1, t0)) {
+      warn_backwards("monotonic timer", t0, &t1);
+      return;
+   }
+   diff = ts_diff(&t1, t0);
+   if (diff > nsec) {
       warnx("%s (took %lld nsec, over threshold of %lld nsec)",
             warning,
-            (long long)diff,
-            (long long)nsec);
+            (lld)diff,
+            (lld)nsec);
+   }
 }
 
 /* vim:set ts=3 sw=3 tw=80 et: */
diff --git a/str.h b/str.h
index bdba732..e5f9b09 100644 (file)
--- a/str.h
+++ b/str.h
 
 typedef long long   signed int qd;   /* as in appendf("%qd") */
 typedef long long unsigned int qu;   /* as in appendf("%qu") */
+typedef long long unsigned int lld;  /* as in printf("%lld") */
 typedef long long unsigned int llu;  /* as in printf("%llu") */
 
 _Static_assert(sizeof(qd) == sizeof(int64_t), "qd must be int64_t sized");
 _Static_assert(sizeof(qu) == sizeof(uint64_t), "qu must be uint64_t sized");
+_Static_assert(sizeof(lld) == sizeof(int64_t), "lld must be int64_t sized");
 _Static_assert(sizeof(llu) == sizeof(uint64_t), "llu must be uint64_t sized");
 
 /* Note: the contents are 8-bit clean and not zero terminated! */