]> AND Private Git Repository - loba.git/blobdiff - timer.h
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Bug fix: credit can be negative.
[loba.git] / timer.h
diff --git a/timer.h b/timer.h
index ccb115bcba15736b7012599aa9f5713e1b5ef15e..52502a1f10eca8c23935491fc693acd9b7c5ecaf 100644 (file)
--- a/timer.h
+++ b/timer.h
@@ -1,77 +1,62 @@
 #ifndef TIMER_H
 #define TIMER_H
 
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#ifdef _BSD_SOURCE
-#  define HAVE_TIMERADD
-#  define HAVE_TIMERSUB
-#  define HAVE_TIMERCLEAR
-#else
-#  warning _BSD_SOURCE not defined
-#  undef HAVE_TIMERADD
-#  undef HAVE_TIMERSUB
-#  undef HAVE_TIMERCLEAR
-#endif
+#include <ctime>
 
 inline
-struct timeval operator+(const struct timeval& a, const struct timeval& b)
+struct timespec operator+(const struct timespec& a, const struct timespec& b)
 {
-    struct timeval result;
-#ifdef HAVE_TIMERADD
-    timeradd(&a, &b, &result);
-#else
+    struct timespec result;
     result.tv_sec = a.tv_sec + b.tv_sec;
-    result.tv_usec = a.tv_usec + b.tv_usec;
-    if (result.tv_usec >= 1000000) {
+    result.tv_nsec = a.tv_nsec + b.tv_nsec;
+    if (result.tv_nsec >= 1000000000L) {
         ++result.tv_sec;
-        result.tv_usec -= 1000000;
+        result.tv_nsec -= 1000000000L;
     }
-#endif
     return result;
 }
 
 inline
-struct timeval operator-(const struct timeval& a, const struct timeval& b)
+struct timespec operator-(const struct timespec& a, const struct timespec& b)
 {
-    struct timeval result;
-#ifdef HAVE_TIMERSUB
-    timersub(&a, &b, &result);
-#else
+    struct timespec result;
     result.tv_sec = a.tv_sec - b.tv_sec;
-    result.tv_usec = a.tv_usec - b.tv_usec;
-    if (result.tv_usec < 0) {
+    result.tv_nsec = a.tv_nsec - b.tv_nsec;
+    if (result.tv_nsec < 0) {
         --result.tv_sec;
-        result.tv_usec += 1000000;
+        result.tv_nsec += 1000000000L;
     }
-#endif
     return result;
 }
 
 class timestamp {
 public:
-    timestamp();
+    enum clock_type { wallclock_time, cpu_time };
+
+    timestamp(clock_type ct);
     ~timestamp();
     void reset();
 
     void start();
     void stop();
 
-    struct timeval tv_duration() const;
+    struct timespec tv_duration() const;
     double duration() const;
 
 private:
-    struct rusage before;
-    struct rusage after;
-    struct timeval difference;
+    clock_type clk;
+    struct timespec before;
+    struct timespec after;
+    struct timespec difference;
 
-    static void tv_clear(struct timeval& a);
-    static double timertod(const struct timeval& a);
+    void get_time(struct timespec& tv);
+
+    static void tv_clear(struct timespec& a);
+    static double timertod(const struct timespec& a);
 };
 
 inline
-timestamp::timestamp()
+timestamp::timestamp(clock_type ct): clk(ct)
 {
     reset();
 }
@@ -84,29 +69,26 @@ timestamp::~timestamp()
 inline
 void timestamp::reset()
 {
-    tv_clear(before.ru_utime);
-    tv_clear(before.ru_stime);
-    tv_clear(after.ru_utime);
-    tv_clear(after.ru_stime);
+    tv_clear(before);
+    tv_clear(after);
     tv_clear(difference);
 }
 
 inline
 void timestamp::start()
 {
-    getrusage(RUSAGE_SELF, &before);
+    get_time(before);
 }
 
 inline
 void timestamp::stop()
 {
-    getrusage(RUSAGE_SELF, &after);
-    difference = difference + ((after.ru_utime + after.ru_stime) -
-                               (before.ru_utime + before.ru_stime));
+    get_time(after);
+    difference = difference + (after - before);
 }
 
 inline
-struct timeval timestamp::tv_duration() const
+struct timespec timestamp::tv_duration() const
 {
     return difference;
 }
@@ -118,19 +100,34 @@ double timestamp::duration() const
 }
 
 inline
-void timestamp::tv_clear(struct timeval& a)
+void timestamp::get_time(struct timespec& tv)
 {
-#ifdef HAVE_TIMERCLEAR
-    timerclear(&a);
+    switch (clk) {
+    case cpu_time: {
+        clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv);
+        break;
+    }
+    case wallclock_time:
+#ifdef CLOCK_MONOTONIC_RAW
+        clock_gettime(CLOCK_MONOTONIC_RAW, &tv);
 #else
-    tv.sec = tv.usec = 0;
+        clock_gettime(CLOCK_MONOTONIC, &tv);
 #endif
+        break;
+    }
+}
+
+inline
+void timestamp::tv_clear(struct timespec& a)
+{
+    a.tv_sec = 0;
+    a.tv_nsec = 0;
 }
 
 inline
-double timestamp::timertod(const struct timeval& a)
+double timestamp::timertod(const struct timespec& a)
 {
-    return a.tv_sec + a.tv_usec / 1e6;
+    return a.tv_sec + a.tv_nsec / 1e9;
 }
 
 #endif // !TIMER_H