blob: 97e3469799c4ca9908f4c190655404d34c5df9b6 [file] [log] [blame]
#ifndef __STOUT_STOPWATCH_HPP__
#define __STOUT_STOPWATCH_HPP__
#include <time.h>
#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif // __MACH__
#include <sys/time.h>
#include "duration.hpp"
class Stopwatch
{
public:
Stopwatch()
: running(false)
{
started.tv_sec = 0;
started.tv_nsec = 0;
stopped.tv_sec = 0;
stopped.tv_nsec = 0;
}
void start()
{
started = now();
running = true;
}
void stop()
{
stopped = now();
running = false;
}
Nanoseconds elapsed()
{
if (!running) {
return Nanoseconds(diff(stopped, started));
}
return Nanoseconds(diff(now(), started));
}
private:
static timespec now()
{
timespec ts;
#ifdef __MACH__
// OS X does not have clock_gettime, use clock_get_time.
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
ts.tv_sec = mts.tv_sec;
ts.tv_nsec = mts.tv_nsec;
#else
clock_gettime(CLOCK_REALTIME, &ts);
#endif // __MACH__
return ts;
}
static uint64_t diff(const timespec& from, const timespec& to)
{
return ((from.tv_sec - to.tv_sec) * 1000000000LL)
+ (from.tv_nsec - to.tv_nsec);
}
bool running;
timespec started, stopped;
};
#endif // __STOUT_STOPWATCH_HPP__