#include <sys/time.h>
#include <sys/resource.h>
-#if NEED_TIMERCLEAR
-inline
-void timerclear(struct timeval& a)
-{
- tv.sec = tv.usec = 0;
-}
+#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
inline
struct timeval operator+(const struct timeval& a, const struct timeval& b)
{
struct timeval result;
+#ifdef HAVE_TIMERADD
+ timeradd(&a, &b, &result);
+#else
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_sec;
result.tv_usec -= 1000000;
}
+#endif
return result;
}
struct timeval operator-(const struct timeval& a, const struct timeval& b)
{
struct timeval result;
+#ifdef HAVE_TIMERSUB
+ timersub(&a, &b, &result);
+#else
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_sec;
result.tv_usec += 1000000;
}
+#endif
return result;
}
-double timertod(const struct timeval& a)
-{
- return a.tv_sec + a.tv_usec / 1e6;
-}
-
class timestamp {
+public:
+ enum clock_type { wallclock_time, cpu_time };
+
+ timestamp(clock_type ct);
+ ~timestamp();
+ void reset();
+
+ void start();
+ void stop();
+
+ struct timeval tv_duration() const;
+ double duration() const;
+
private:
- struct rusage before;
- struct rusage after;
+ clock_type clk;
+ struct timeval before;
+ struct timeval after;
struct timeval difference;
-public:
- timestamp()
- {
- reset();
- }
+ void get_time(struct timeval& tv);
- void reset()
- {
- timerclear(&before.ru_utime);
- timerclear(&before.ru_stime);
- timerclear(&after.ru_utime);
- timerclear(&after.ru_stime);
- timerclear(&difference);
- }
+ static void tv_clear(struct timeval& a);
+ static double timertod(const struct timeval& a);
+};
- void start()
- {
- getrusage(RUSAGE_SELF, &before);
- }
+inline
+timestamp::timestamp(clock_type ct): clk(ct)
+{
+ reset();
+}
- void stop()
- {
- getrusage(RUSAGE_SELF, &after);
- difference = difference + ((after.ru_utime + after.ru_stime) -
- (before.ru_utime + before.ru_stime));
- }
+inline
+timestamp::~timestamp()
+{
+}
- struct timeval tv_duration() const
- {
- return difference;
- }
+inline
+void timestamp::reset()
+{
+ tv_clear(before);
+ tv_clear(after);
+ tv_clear(difference);
+}
- double duration() const
- {
- return timertod(difference);
+inline
+void timestamp::start()
+{
+ get_time(before);
+}
+
+inline
+void timestamp::stop()
+{
+ get_time(after);
+ difference = difference + (after - before);
+}
+
+inline
+struct timeval timestamp::tv_duration() const
+{
+ return difference;
+}
+
+inline
+double timestamp::duration() const
+{
+ return timertod(difference);
+}
+
+inline
+void timestamp::get_time(struct timeval& tv)
+{
+ switch (clk) {
+ case cpu_time: {
+ struct rusage usage;
+ getrusage(RUSAGE_SELF, &usage);
+ tv = usage.ru_utime + usage.ru_stime;
+ break;
}
-};
+ case wallclock_time:
+ gettimeofday(&tv, NULL);
+ break;
+ }
+}
+
+inline
+void timestamp::tv_clear(struct timeval& a)
+{
+#ifdef HAVE_TIMERCLEAR
+ timerclear(&a);
+#else
+ tv.sec = tv.usec = 0;
+#endif
+}
+
+inline
+double timestamp::timertod(const struct timeval& a)
+{
+ return a.tv_sec + a.tv_usec / 1e6;
+}
#endif // !TIMER_H