X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/loba.git/blobdiff_plain/f29b38ef2a056daa14bbfda2fce78063faa773d4..24e97d18003e65787648061db7c23f0882f98d1a:/timer.h?ds=sidebyside

diff --git a/timer.h b/timer.h
index 6ae15eb..9f00cd2 100644
--- a/timer.h
+++ b/timer.h
@@ -1,91 +1,134 @@
 #ifndef TIMER_H
 #define TIMER_H
 
-#include <sys/time.h>
-#include <sys/resource.h>
+#include <ctime>
 
-#if NEED_TIMERCLEAR
 inline
-void timerclear(struct timeval& a)
+struct timespec operator+(const struct timespec& a, const struct timespec& b)
 {
-    tv.sec = tv.usec = 0;
-}
-#endif
-
-inline
-struct timeval operator+(const struct timeval& a, const struct timeval& b)
-{
-    struct timeval result;
+    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;
     }
     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)
 {
-    timeval result;
+    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_sec;
-        result.tv_usec += 1000000;
+    result.tv_nsec = a.tv_nsec - b.tv_nsec;
+    if (result.tv_nsec < 0) {
+        --result.tv_sec;
+        result.tv_nsec += 1000000000L;
     }
     return result;
 }
 
-double timertod(const timeval& a)
+class timestamp {
+public:
+    enum class clock_type { WALLCLOCK, CPU };
+
+    timestamp(clock_type ct);
+    ~timestamp();
+    void reset();
+
+    void start();
+    void stop();
+
+    struct timespec tv_duration() const;
+    double duration() const;
+
+private:
+    clock_type clk;
+    struct timespec before;
+    struct timespec after;
+    struct timespec difference;
+
+    void get_time(struct timespec& tv);
+
+    static void tv_clear(struct timespec& a);
+    static double timertod(const struct timespec& a);
+};
+
+inline
+timestamp::timestamp(clock_type ct): clk(ct)
 {
-    return a.tv_sec + a.tv_usec / 1e6;
+    reset();
 }
 
-class timestamp {
-private:
-    struct rusage before;
-    struct rusage after;
-    struct timeval difference;
+inline
+timestamp::~timestamp()
+{
+}
 
-public:
-    timestamp()
-    {
-        reset();
-    }
+inline
+void timestamp::reset()
+{
+    tv_clear(before);
+    tv_clear(after);
+    tv_clear(difference);
+}
 
-    void reset()
-    {
-        timerclear(&before.ru_utime);
-        timerclear(&before.ru_stime);
-        timerclear(&after.ru_utime);
-        timerclear(&after.ru_stime);
-        timerclear(&difference);
-    }
+inline
+void timestamp::start()
+{
+    get_time(before);
+}
 
-    void start()
-    {
-        getrusage(RUSAGE_SELF, &before);        
-    }
+inline
+void timestamp::stop()
+{
+    get_time(after);
+    difference = difference + (after - before);
+}
 
-    void stop()
-    {
-        getrusage(RUSAGE_SELF, &after);        
-        difference = difference + ((after.ru_utime + after.ru_stime) -
-                                   (before.ru_utime + before.ru_stime));
-    }
+inline
+struct timespec timestamp::tv_duration() const
+{
+    return difference;
+}
 
-    struct timeval tv_duration() const
-    {
-        return difference;
-    }
+inline
+double timestamp::duration() const
+{
+    return timertod(difference);
+}
 
-    double duration() const
-    {
-        return timertod(difference);
+inline
+void timestamp::get_time(struct timespec& tv)
+{
+    switch (clk) {
+    case clock_type::CPU: {
+        clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv);
+        break;
     }
-};
+    case clock_type::WALLCLOCK:
+#ifdef CLOCK_MONOTONIC_RAW
+        clock_gettime(CLOCK_MONOTONIC_RAW, &tv);
+#else
+        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 timespec& a)
+{
+    return a.tv_sec + a.tv_nsec / 1e9;
+}
 
 #endif // !TIMER_H