Browse Source

std::chrono-ize hsTimer.

Darryl Pogue 11 years ago
parent
commit
5b0652cb7e
  1. 37
      Sources/Plasma/NucleusLib/inc/hsTimer.h
  2. 160
      Sources/Plasma/NucleusLib/pnTimer/hsTimer.cpp

37
Sources/Plasma/NucleusLib/inc/hsTimer.h

@ -42,13 +42,17 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#ifndef hsTimer_Defined #ifndef hsTimer_Defined
#define hsTimer_Defined #define hsTimer_Defined
#include "hsWide.h" #include <chrono>
class plTimerShare class plTimerShare
{ {
typedef std::chrono::high_resolution_clock Clock;
typedef std::chrono::time_point<Clock> TimePoint;
typedef Clock::duration Duration;
protected: protected:
mutable bool fFirstTime; mutable bool fFirstTime;
mutable hsWide fRawTimeZero; mutable TimePoint fRawTimeZero;
mutable bool fResetSmooth; mutable bool fResetSmooth;
enum { enum {
@ -67,16 +71,10 @@ protected:
float fSmoothingClampSecs; float fSmoothingClampSecs;
bool fClamping; bool fClamping;
hsWide* FactorInTimeZero(hsWide* ticks) const;
double GetSeconds() const; double GetSeconds() const;
double GetMilliSeconds() const; double GetMilliSeconds() const;
hsWide* GetRawTicks(hsWide* ticks) const;
double RawTicksToDSeconds(const hsWide& ticks);
hsWide DSecondsToRawTicks(double secs);
float GetDelSysSeconds() const { return fDelSysSeconds; } float GetDelSysSeconds() const { return fDelSysSeconds; }
double GetSysSeconds() const { return fSysSeconds; } double GetSysSeconds() const { return fSysSeconds; }
double IncSysSeconds(); double IncSysSeconds();
@ -95,33 +93,28 @@ protected:
bool IsClamping() const { return fClamping; } bool IsClamping() const { return fClamping; }
friend class hsTimer; friend class hsTimer;
private:
Duration GetRawTicks() const;
public: public:
plTimerShare(); plTimerShare();
~plTimerShare(); ~plTimerShare();
}; };
class hsTimer class hsTimer
{ {
protected: protected:
static const double fPrecTicksPerSec;
static const hsWide fRawBase;
static hsWide IInitRawBase();
static plTimerShare* fTimer; static plTimerShare* fTimer;
public:
static bool VerifyRawBase() { return fRawBase == IInitRawBase(); }
static const hsWide& GetRawBase() { return fRawBase; }
static hsWide* GetRawTicks(hsWide* ticks) { return fTimer->GetRawTicks(ticks); }
public:
static double GetSeconds() { return fTimer->GetSeconds(); } static double GetSeconds() { return fTimer->GetSeconds(); }
static double GetMilliSeconds() { return fTimer->GetMilliSeconds(); } static double GetMilliSeconds() { return fTimer->GetMilliSeconds(); }
static double RawTicksToDSeconds(const hsWide& ticks) { return fTimer->RawTicksToDSeconds(ticks); }
static hsWide DSecondsToRawTicks(double secs) { return fTimer->DSecondsToRawTicks(secs); }
static float GetDelSysSeconds() { return fTimer->GetDelSysSeconds(); } static float GetDelSysSeconds() { return fTimer->GetDelSysSeconds(); }
static double GetSysSeconds() { return fTimer->GetSysSeconds(); } static double GetSysSeconds() { return fTimer->GetSysSeconds(); }
@ -145,9 +138,7 @@ public:
/////////////////////////// ///////////////////////////
static uint32_t GetPrecTickCount(); static uint32_t GetPrecTickCount();
static double GetPrecTicksPerSec(); static double GetPrecTicksPerSec();
static uint32_t PrecSecsToTicks(float secs);
static double PrecTicksToSecs(uint32_t ticks); static double PrecTicksToSecs(uint32_t ticks);
static double PrecTicksToHz(uint32_t ticks);
// If you need to time something longer than 20 seconds, use this instead of // If you need to time something longer than 20 seconds, use this instead of
// the precision timer. It works the same, it just gives you full resolution. // the precision timer. It works the same, it just gives you full resolution.

160
Sources/Plasma/NucleusLib/pnTimer/hsTimer.cpp

@ -41,10 +41,12 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
*==LICENSE==*/ *==LICENSE==*/
#include "hsTimer.h" #include "hsTimer.h"
#include "HeadSpin.h" #include "HeadSpin.h"
#include "hsWindows.h"
#include "plTweak.h" #include "plTweak.h"
typedef std::chrono::duration<double> dSeconds;
typedef std::chrono::duration<double, std::milli> dMilliseconds;
// //
// plTimerShare - the actual worker. All process spaces should share a single // plTimerShare - the actual worker. All process spaces should share a single
// plTimerShare to keep time synchronized across spaces. // plTimerShare to keep time synchronized across spaces.
@ -71,45 +73,12 @@ plTimerShare::~plTimerShare()
double plTimerShare::GetSeconds() const double plTimerShare::GetSeconds() const
{ {
hsWide ticks; return dSeconds(GetRawTicks()).count();
return hsTimer::GetRawTicks(&ticks)->AsDouble() / hsTimer::GetRawBase().AsDouble();
} }
double plTimerShare::GetMilliSeconds() const double plTimerShare::GetMilliSeconds() const
{ {
return GetSeconds() * 1.e3; return dMilliseconds(GetRawTicks()).count();
}
hsWide plTimerShare::DSecondsToRawTicks(double secs)
{
hsWide retVal;
double ticks = secs * hsTimer::GetRawBase().AsDouble();
double hi = ticks / double(65536) / double(65536);
ticks -= hi;
retVal.fHi = int32_t(hi);
retVal.fLo = int32_t(ticks);
return retVal;
}
double plTimerShare::RawTicksToDSeconds(const hsWide& ticks)
{
return ticks.AsDouble() / hsTimer::GetRawBase().AsDouble();
}
inline hsWide* plTimerShare::FactorInTimeZero(hsWide* ticks) const
{
if( fFirstTime )
{
fFirstTime = false;
fRawTimeZero = *ticks;
ticks->Set(0, 0);
}
else
{
ticks->Sub(&fRawTimeZero);
}
return ticks;
} }
double plTimerShare::IncSysSeconds() double plTimerShare::IncSysSeconds()
@ -206,63 +175,23 @@ void plTimerShare::SetRealTime(bool realTime)
} }
} }
#if HS_BUILD_FOR_WIN32
hsWide* plTimerShare::GetRawTicks(hsWide* ticks) const plTimerShare::Duration plTimerShare::GetRawTicks() const
{ {
LARGE_INTEGER large; plTimerShare::TimePoint tp = Clock::now();
if (::QueryPerformanceCounter(&large)) if (fFirstTime)
{
ticks->Set(large.HighPart, large.LowPart);
}
else
{ {
ticks->Set(0, ::GetTickCount()); fFirstTime = false;
} fRawTimeZero = tp;
return plTimerShare::Duration(0);
return FactorInTimeZero(ticks);
} }
hsWide hsTimer::IInitRawBase()
{
hsWide base;
LARGE_INTEGER large;
if (::QueryPerformanceFrequency(&large))
base.Set(large.HighPart, large.LowPart);
else else
base.Set(0, 1000);
return base;
}
#elif HS_BUILD_FOR_UNIX
#include <sys/time.h>
#define kMicroSecondsUnit 1000000
static uint32_t gBaseTime = 0;
hsWide* plTimerShare::GetRawTicks(hsWide* ticks) const
{ {
timeval tv; return plTimerShare::Duration(tp - fRawTimeZero);
(void)::gettimeofday(&tv, nil);
if (gBaseTime == 0)
gBaseTime = tv.tv_sec;
ticks->Mul(tv.tv_sec - gBaseTime, kMicroSecondsUnit)->Add(tv.tv_usec);
return ticks;
} }
hsWide hsTimer::IInitRawBase()
{
hsWide base;
base.Set(0, kMicroSecondsUnit);
return base;
} }
#endif
// //
// hsTimer - thin static interface to plTimerShare. Also keeps a couple of // hsTimer - thin static interface to plTimerShare. Also keeps a couple of
@ -270,85 +199,34 @@ hsWide hsTimer::IInitRawBase()
// //
static plTimerShare staticTimer; static plTimerShare staticTimer;
plTimerShare* hsTimer::fTimer = &staticTimer; // until overridden. plTimerShare* hsTimer::fTimer = &staticTimer; // until overridden.
const double hsTimer::fPrecTicksPerSec = hsTimer::GetPrecTicksPerSec();
const hsWide hsTimer::fRawBase = hsTimer::IInitRawBase();
void hsTimer::SetTheTimer(plTimerShare* timer) void hsTimer::SetTheTimer(plTimerShare* timer)
{ {
fTimer = timer; fTimer = timer;
} }
///////////////////////////
// Precision timer routines
// These remain as statics
// since they are stateless
// anyway.
///////////////////////////
double hsTimer::GetPrecTicksPerSec() double hsTimer::GetPrecTicksPerSec()
{ {
#if HS_BUILD_FOR_WIN32 return double(plTimerShare::Clock::period::num) /
LARGE_INTEGER freq; double(plTimerShare::Clock::period::den);
if( !QueryPerformanceFrequency(&freq) )
{
return 1000.f;
}
return ((double) freq.LowPart);
#endif
return 1;
} }
uint32_t hsTimer::GetPrecTickCount() uint32_t hsTimer::GetPrecTickCount()
{ {
#if HS_BUILD_FOR_WIN32 return uint32_t(plTimerShare::Clock::now().time_since_epoch().count());
LARGE_INTEGER ti;
if( !QueryPerformanceCounter(&ti) )
return GetTickCount();
return ti.LowPart;
#else
return 1;
#endif
}
uint32_t hsTimer::PrecSecsToTicks(float secs)
{
return (uint32_t)(((double)secs) * fPrecTicksPerSec);
} }
double hsTimer::PrecTicksToSecs(uint32_t ticks) double hsTimer::PrecTicksToSecs(uint32_t ticks)
{ {
return ((double)ticks) / fPrecTicksPerSec; return dSeconds(plTimerShare::Duration(ticks)).count();
}
double hsTimer::PrecTicksToHz(uint32_t ticks)
{
return fPrecTicksPerSec / ((double)ticks);
} }
uint64_t hsTimer::GetFullTickCount() uint64_t hsTimer::GetFullTickCount()
{ {
#if HS_BUILD_FOR_WIN32 return uint64_t(plTimerShare::Clock::now().time_since_epoch().count());
LARGE_INTEGER ticks;
QueryPerformanceCounter(&ticks);
return ticks.QuadPart;
#else
return 0;
#endif
} }
float hsTimer::FullTicksToMs(uint64_t ticks) float hsTimer::FullTicksToMs(uint64_t ticks)
{ {
#ifdef HS_BUILD_FOR_WIN32 return float(dMilliseconds(plTimerShare::Duration(ticks)).count());
static uint64_t ticksPerTenthMs = 0;
if (ticksPerTenthMs == 0)
{
LARGE_INTEGER perfFreq;
QueryPerformanceFrequency(&perfFreq);
ticksPerTenthMs = perfFreq.QuadPart / 10000;
}
return float(ticks / ticksPerTenthMs) / 10.f;
#else
return 0.f;
#endif
} }

Loading…
Cancel
Save