Added: Function to prefer high resolution local time

This commit is contained in:
kaetemi 2012-07-27 22:26:49 +02:00
parent e999a92369
commit e46a301ad0
2 changed files with 51 additions and 1 deletions

View file

@ -86,7 +86,13 @@ public:
* time that is the same on all computers. * time that is the same on all computers.
* \warning On Win32, the value is on 32 bits only. It wraps around to 0 every about 49.71 days. * \warning On Win32, the value is on 32 bits only. It wraps around to 0 every about 49.71 days.
*/ */
static TTime getLocalTime (); static TTime getLocalTime();
/** Same as getLocalTime, but prefers high resolution timers.
* Must call probe once in the beginning of the application before using,
* to ensure the correct settings are applied.
*/
static TTime getLocalTimeHR();
/** Return the time in processor ticks. Use it for profile purpose. /** Return the time in processor ticks. Use it for profile purpose.
* If the performance time is not supported on this hardware, it returns 0. * If the performance time is not supported on this hardware, it returns 0.

View file

@ -37,6 +37,12 @@
namespace NLMISC namespace NLMISC
{ {
namespace {
#ifdef NL_OS_WINDOWS
bool a_HaveQueryPerformance = false;
#endif
}
void CTime::probeTimerInfo(CTime::CTimerInfo &result) void CTime::probeTimerInfo(CTime::CTimerInfo &result)
{ {
breakable breakable
@ -65,6 +71,7 @@ void CTime::probeTimerInfo(CTime::CTimerInfo &result)
result.IsHighPrecisionAvailable = false; result.IsHighPrecisionAvailable = false;
result.HighPrecisionResolution = 1000; result.HighPrecisionResolution = 1000;
} }
a_HaveQueryPerformance = result.IsHighPrecisionAvailable;
if (!result.IsHighPrecisionAvailable) if (!result.IsHighPrecisionAvailable)
{ {
lowResTime = timeGetTime(); lowResTime = timeGetTime();
@ -292,6 +299,43 @@ TTime CTime::getLocalTime ()
#endif #endif
} }
#ifdef NL_OS_WINDOWS
namespace {
struct CQPFProvider
{
CQPFProvider()
{
QueryPerformanceFrequency(&Frequency);
}
LARGE_INTEGER Frequency;
};
CQPFProvider s_QPFProvider;
}
#endif
/// Same as above but prefer high resolution timer
TTime CTime::getLocalTimeHR()
{
#ifdef NL_OS_WINDOWS
if (a_HaveQueryPerformance)
{
// On a (fast) 15MHz timer this rolls over after 7000 days.
// If my calculations are right.
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
counter.QuadPart *= 1000;
counter.QuadPart /= s_QPFProvider.Frequency.QuadPart;
}
else
{
// Use default reliable low resolution timer.
return getLocalTime();
}
#else
// Other OS always use the best available high resolution timer.
return getLocalTime();
#endif
}
/* Return the time in processor ticks. Use it for profile purpose. /* Return the time in processor ticks. Use it for profile purpose.
* If the performance time is not supported on this hardware, it returns 0. * If the performance time is not supported on this hardware, it returns 0.