#ifndef __DNBTimer_h__
#define __DNBTimer_h__
#include <sys/time.h>
#include <stdint.h>
#include <memory>
#include "PThreadMutex.h"
class DNBTimer
{
public:
DNBTimer (bool threadSafe) :
m_mutexAP()
{
if (threadSafe)
m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE));
Reset();
}
DNBTimer (const DNBTimer& rhs) :
m_mutexAP()
{
if (rhs.IsThreadSafe())
m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE));
m_timeval = rhs.m_timeval;
}
DNBTimer& operator= (const DNBTimer& rhs)
{
if (rhs.IsThreadSafe())
m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE));
m_timeval = rhs.m_timeval;
return *this;
}
~DNBTimer ()
{
}
bool
IsThreadSafe() const
{
return m_mutexAP.get() != NULL;
}
void
Reset ()
{
PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get());
gettimeofday (&m_timeval, NULL);
}
uint64_t
TotalMicroSeconds () const
{
PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get());
return (uint64_t)(m_timeval.tv_sec) * 1000000ull + (uint64_t)m_timeval.tv_usec;
}
void
GetTime (uint32_t& sec, uint32_t& usec) const
{
PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get());
sec = m_timeval.tv_sec;
usec = m_timeval.tv_usec;
}
uint64_t
ElapsedMicroSeconds (bool update)
{
PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get());
struct timeval now;
gettimeofday (&now, NULL);
uint64_t now_usec = (uint64_t)(now.tv_sec) * 1000000ull + (uint64_t)now.tv_usec;
uint64_t this_usec = (uint64_t)(m_timeval.tv_sec) * 1000000ull + (uint64_t)m_timeval.tv_usec;
uint64_t elapsed = now_usec - this_usec;
if (update)
m_timeval = now;
return elapsed;
}
static uint64_t GetTimeOfDay()
{
struct timeval now;
gettimeofday (&now, NULL);
uint64_t now_usec = (uint64_t)(now.tv_sec) * 1000000ull + (uint64_t)now.tv_usec;
return now_usec;
}
static void OffsetTimeOfDay (struct timespec* ts, __darwin_time_t sec_offset = 0, long nsec_offset = 0)
{
if (ts == NULL)
return;
struct timeval now;
gettimeofday (&now, NULL);
TIMEVAL_TO_TIMESPEC(&now, ts);
if (sec_offset != 0 || nsec_offset != 0)
{
ts->tv_nsec += nsec_offset;
ts->tv_sec = ts->tv_sec + ts->tv_nsec / 1000000000 + sec_offset;
ts->tv_nsec = ts->tv_nsec % 1000000000;
}
}
static bool TimeOfDayLaterThan (struct timespec &ts)
{
struct timespec now;
OffsetTimeOfDay(&now);
if (now.tv_sec > ts.tv_sec)
return true;
else if (now.tv_sec < ts.tv_sec)
return false;
else
{
if (now.tv_nsec > ts.tv_nsec)
return true;
else
return false;
}
}
protected:
std::auto_ptr<PThreadMutex> m_mutexAP;
struct timeval m_timeval;
};
#endif // #ifndef __DNBTimer_h__