blob: 717e1563be5a81ff4ad176ea8fb80731734b51a8 [file] [log] [blame]
//===-- DNBTimer.h ----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Created by Greg Clayton on 12/13/07.
//
//===----------------------------------------------------------------------===//
#ifndef __DNBTimer_h__
#define __DNBTimer_h__
#include <sys/time.h>
#include <stdint.h>
#include <memory>
#include "DNBDefs.h"
#include "PThreadMutex.h"
class DNBTimer
{
public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
DNBTimer (bool threadSafe) :
m_mutexAP()
{
if (threadSafe)
m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE));
Reset();
}
DNBTimer (const DNBTimer& rhs) :
m_mutexAP()
{
// Create a new mutex to make this timer thread safe as well if
// the timer we are copying is thread safe
if (rhs.IsThreadSafe())
m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE));
m_timeval = rhs.m_timeval;
}
DNBTimer& operator= (const DNBTimer& rhs)
{
// Create a new mutex to make this timer thread safe as well if
// the timer we are copying is thread safe
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;
}
//------------------------------------------------------------------
// Reset the time value to now
//------------------------------------------------------------------
void
Reset ()
{
PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get());
gettimeofday (&m_timeval, NULL);
}
//------------------------------------------------------------------
// Get the total mircoseconds since Jan 1, 1970
//------------------------------------------------------------------
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;
}
//------------------------------------------------------------------
// Return the number of microseconds elapsed between now and the
// m_timeval
//------------------------------------------------------------------
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;
// Update the timer time value if requeseted
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;
// Get the current time in a timeval structure
struct timeval now;
gettimeofday (&now, NULL);
// Morph it into a timespec
TIMEVAL_TO_TIMESPEC(&now, ts);
// Offset the timespec if requested
if (sec_offset != 0 || nsec_offset != 0)
{
// Offset the nano seconds
ts->tv_nsec += nsec_offset;
// Offset the seconds taking into account a nano-second overflow
ts->tv_sec = ts->tv_sec + ts->tv_nsec / 1000000000 + sec_offset;
// Trim the nanoseconds back there was an overflow
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:
//------------------------------------------------------------------
// Classes that inherit from DNBTimer can see and modify these
//------------------------------------------------------------------
std::unique_ptr<PThreadMutex> m_mutexAP;
struct timeval m_timeval;
};
#endif // #ifndef __DNBTimer_h__