#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:
- enum clock_type { wallclock_time, cpu_time };
+ enum class clock_type { WALLCLOCK, CPU };
timestamp(clock_type ct);
~timestamp();
void start();
void stop();
- struct timeval tv_duration() const;
+ struct timespec tv_duration() const;
double duration() const;
private:
clock_type clk;
- struct timeval before;
- struct timeval after;
- struct timeval difference;
+ struct timespec before;
+ struct timespec after;
+ struct timespec difference;
- void get_time(struct timeval& tv);
+ void get_time(struct timespec& tv);
- static void tv_clear(struct timeval& a);
- static double timertod(const struct timeval& a);
+ static void tv_clear(struct timespec& a);
+ static double timertod(const struct timespec& a);
};
inline
}
inline
-struct timeval timestamp::tv_duration() const
+struct timespec timestamp::tv_duration() const
{
return difference;
}
}
inline
-void timestamp::get_time(struct timeval& tv)
+void timestamp::get_time(struct timespec& tv)
{
switch (clk) {
- case cpu_time: {
- struct rusage usage;
- getrusage(RUSAGE_SELF, &usage);
- tv = usage.ru_utime + usage.ru_stime;
+ case clock_type::CPU: {
+ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv);
break;
}
- case wallclock_time:
- gettimeofday(&tv, NULL);
+ 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 timeval& a)
+void timestamp::tv_clear(struct timespec& a)
{
-#ifdef HAVE_TIMERCLEAR
- timerclear(&a);
-#else
- tv.sec = tv.usec = 0;
-#endif
+ 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