Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
295 lines (212 sloc) 7.05 KB
////////////////////////////////////////////////////////////////////////////////
// -------------------------------------------------------------------------- //
// //
// (C) 2010-2016 Robot Developers //
// See LICENSE for licensing info //
// //
// -------------------------------------------------------------------------- //
////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------//
// Prefaces //
//----------------------------------------------------------------------------//
#include "Timer.h"
#ifdef ROBOT_OS_LINUX
#include <time.h>
#include <unistd.h>
#endif
#ifdef ROBOT_OS_MAC
#include <unistd.h>
#include <mach/mach_time.h>
#endif
#ifdef ROBOT_OS_WIN
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#endif
ROBOT_NS_BEGIN
//----------------------------------------------------------------------------//
// Locals //
//----------------------------------------------------------------------------//
////////////////////////////////////////////////////////////////////////////////
static const uint64 gInvalid
= 0x8000000000000000;
//----------------------------------------------------------------------------//
// Constructors Timer //
//----------------------------------------------------------------------------//
////////////////////////////////////////////////////////////////////////////////
Timer::Timer (void)
{
mStarted = gInvalid;
}
//----------------------------------------------------------------------------//
// Functions Timer //
//----------------------------------------------------------------------------//
////////////////////////////////////////////////////////////////////////////////
void Timer::Start (void)
{
mStarted = GetCpuTime();
}
////////////////////////////////////////////////////////////////////////////////
uint64 Timer::Reset (void)
{
// Check if timer started
if (mStarted == gInvalid)
return 0;
else
{
auto old = mStarted;
mStarted = gInvalid;
return GetCpuTime() - old;
}
}
////////////////////////////////////////////////////////////////////////////////
uint64 Timer::Restart (void)
{
// Check if timer started
if (mStarted == gInvalid)
{
mStarted = GetCpuTime();
return 0;
}
else
{
auto old = mStarted;
mStarted = GetCpuTime();
return mStarted - old;
}
}
////////////////////////////////////////////////////////////////////////////////
uint64 Timer::GetElapsed (void) const
{
// Check if timer started
if (mStarted == gInvalid)
return 0;
return GetCpuTime() - mStarted;
}
////////////////////////////////////////////////////////////////////////////////
bool Timer::HasStarted (void) const
{
return mStarted != gInvalid;
}
////////////////////////////////////////////////////////////////////////////////
bool Timer::HasExpired (uint64 time) const
{
// Check if timer started
if (mStarted == gInvalid)
return true;
return GetElapsed() > time;
}
////////////////////////////////////////////////////////////////////////////////
void Timer::Sleep (const Range& time)
{
// Generate a random range
int32 d = time.GetRandom();
// Skip negatives
if (d < 0) return;
#ifdef ROBOT_OS_LINUX
usleep (d * 1000);
#endif
#ifdef ROBOT_OS_MAC
usleep (d * 1000);
#endif
#ifdef ROBOT_OS_WIN
::Sleep (d);
#endif
}
////////////////////////////////////////////////////////////////////////////////
void Timer::Sleep
(uint32 minimum, uint32 maximum)
{
Sleep (Range (minimum, maximum));
}
////////////////////////////////////////////////////////////////////////////////
uint64 Timer::GetCpuTime (void)
{
#ifdef ROBOT_OS_LINUX
// Gets the current time and returns it in milliseconds
timespec time; clock_gettime (CLOCK_MONOTONIC, &time);
return (time.tv_sec * 1000) + (time.tv_nsec / 1000000);
#endif
#ifdef ROBOT_OS_MAC
// Initialize the mach timebase info one time
static mach_timebase_info_data_t info = { 0 };
if (info.denom == 0) mach_timebase_info (&info);
// Retrieve current absolute time
uint64 time = mach_absolute_time();
// Return the current absolute time in milliseconds
return (time * info.numer) / (info.denom * 1000000);
#endif
#ifdef ROBOT_OS_WIN
// Initialize timer info once
static uint64 frequency = 0;
static bool initialized = false;
if (!initialized)
{
// Get performance counter frequency
initialized = true; LARGE_INTEGER f;
if (QueryPerformanceFrequency (&f))
frequency = (uint64) f.QuadPart;
}
if (frequency > 0)
{
// Retrieve performance counter value
uint64 time = 0; LARGE_INTEGER counter;
if (QueryPerformanceCounter (&counter))
time = (uint64) counter.QuadPart;
// Return result in milliseconds
return (time * 1000) / frequency;
}
// Should never happen
return GetTickCount64();
#endif
}
//----------------------------------------------------------------------------//
// Operators Timer //
//----------------------------------------------------------------------------//
////////////////////////////////////////////////////////////////////////////////
uint64 Timer::operator () (void) const
{
// Check if timer started
if (mStarted == gInvalid)
return 0;
return GetCpuTime() - mStarted;
}
////////////////////////////////////////////////////////////////////////////////
bool Timer::operator < (const Timer& timer) const
{
if (timer.mStarted == gInvalid) return false;
if (this->mStarted == gInvalid) return true;
return mStarted > timer.mStarted;
}
////////////////////////////////////////////////////////////////////////////////
bool Timer::operator > (const Timer& timer) const
{
if (this->mStarted == gInvalid) return false;
if (timer.mStarted == gInvalid) return true;
return mStarted < timer.mStarted;
}
////////////////////////////////////////////////////////////////////////////////
bool Timer::operator <= (const Timer& timer) const
{
if (this->mStarted == gInvalid) return true;
if (timer.mStarted == gInvalid) return false;
return mStarted >= timer.mStarted;
}
////////////////////////////////////////////////////////////////////////////////
bool Timer::operator >= (const Timer& timer) const
{
if (timer.mStarted == gInvalid) return true;
if (this->mStarted == gInvalid) return false;
return mStarted <= timer.mStarted;
}
////////////////////////////////////////////////////////////////////////////////
bool Timer::operator == (const Timer& timer) const
{
return mStarted == timer.mStarted;
}
////////////////////////////////////////////////////////////////////////////////
bool Timer::operator != (const Timer& timer) const
{
return mStarted != timer.mStarted;
}
ROBOT_NS_END