From 8560e1c1461c6eed16d2bb3e4a9518fae4157f0d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 27 Jul 2012 22:26:49 +0200 Subject: [PATCH] Added: Function to prefer high resolution local time --- code/nel/include/nel/misc/time_nl.h | 8 +++++- code/nel/src/misc/time_nl.cpp | 44 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/misc/time_nl.h b/code/nel/include/nel/misc/time_nl.h index 9e44b4b36..62161e304 100644 --- a/code/nel/include/nel/misc/time_nl.h +++ b/code/nel/include/nel/misc/time_nl.h @@ -86,7 +86,13 @@ public: * 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. */ - 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. * If the performance time is not supported on this hardware, it returns 0. diff --git a/code/nel/src/misc/time_nl.cpp b/code/nel/src/misc/time_nl.cpp index 4a3586baa..11a920a79 100644 --- a/code/nel/src/misc/time_nl.cpp +++ b/code/nel/src/misc/time_nl.cpp @@ -37,6 +37,12 @@ namespace NLMISC { +namespace { +#ifdef NL_OS_WINDOWS +bool a_HaveQueryPerformance = false; +#endif +} + void CTime::probeTimerInfo(CTime::CTimerInfo &result) { breakable @@ -65,6 +71,7 @@ void CTime::probeTimerInfo(CTime::CTimerInfo &result) result.IsHighPrecisionAvailable = false; result.HighPrecisionResolution = 1000; } + a_HaveQueryPerformance = result.IsHighPrecisionAvailable; if (!result.IsHighPrecisionAvailable) { lowResTime = timeGetTime(); @@ -292,6 +299,43 @@ TTime CTime::getLocalTime () #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. * If the performance time is not supported on this hardware, it returns 0.