wxLogMessage("And calling it twice took $ldms in all", sw.Time());
@endcode
+ Since wxWidgets 2.9.3 this class uses @c ::QueryPerformanceCounter()
+ function under MSW to measure the elapsed time. It provides higher
+ precision than the usual timer functions but can suffer from bugs in its
+ implementation in some Windows XP versions. If you encounter such problems,
+ installing a Microsoft hot fix from http://support.microsoft.com/?id=896256
+ could be necessary.
+
@library{wxbase}
@category{misc}
#if wxUSE_STOPWATCH
+#ifdef __WXMSW__
+
+namespace
+{
+
+struct PerfCounter
+{
+ PerfCounter()
+ {
+ init = false;
+ }
+
+ bool CanBeUsed() const
+ {
+ return freq.QuadPart != 0;
+ }
+
+ wxCriticalSection cs;
+ LARGE_INTEGER freq;
+ bool init;
+} gs_perfCounter;
+
+} // anonymous namespace
+
+#endif // __WXMSW__
+
void wxStopWatch::Start(long t)
{
-#if 0
-// __WXMSW__
- LARGE_INTEGER frequency_li;
- ::QueryPerformanceFrequency( &frequency_li );
- m_frequency = frequency_li.QuadPart;
- if (m_frequency == 0)
+#ifdef __WXMSW__
+ if ( !gs_perfCounter.init )
{
- m_t0 = wxGetLocalTimeMillis() - t;
+ wxCriticalSectionLocker lock(gs_perfCounter.cs);
+ ::QueryPerformanceFrequency(&gs_perfCounter.freq);
+ gs_perfCounter.init = true;
}
- else
+
+ LARGE_INTEGER counter;
+ if ( gs_perfCounter.CanBeUsed() && ::QueryPerformanceCounter(&counter) )
{
- LARGE_INTEGER counter_li;
- ::QueryPerformanceCounter( &counter_li );
- wxLongLong counter = counter_li.QuadPart;
- m_t0 = (counter * 10000 / m_frequency) - t*10;
+ m_t0 = counter.QuadPart - t*gs_perfCounter.freq.QuadPart/1000;
}
-#else
- m_t0 = wxGetLocalTimeMillis() - t;
-#endif
+ else // Fall back to the generic code below.
+#endif // __WXMSW__
+ {
+ m_t0 = wxGetLocalTimeMillis() - t;
+ }
+
m_pause = 0;
m_pauseCount = 0;
}
long wxStopWatch::GetElapsedTime() const
{
-#if 0
-//__WXMSW__
- if (m_frequency == 0)
+#ifdef __WXMSW__
+ LARGE_INTEGER counter;
+ if ( gs_perfCounter.CanBeUsed() && ::QueryPerformanceCounter(&counter) )
{
- return (wxGetLocalTimeMillis() - m_t0).GetLo();
- }
- else
- {
- LARGE_INTEGER counter_li;
- ::QueryPerformanceCounter( &counter_li );
- wxLongLong counter = counter_li.QuadPart;
- wxLongLong res = (counter * 10000 / m_frequency) - m_t0;
- return res.GetLo() / 10;
+ wxLongLong delta(counter.QuadPart);
+ delta -= m_t0;
+
+ return ((delta*1000)/gs_perfCounter.freq.QuadPart).GetLo();
}
-#else
- return (wxGetLocalTimeMillis() - m_t0).GetLo();
#endif
+ return (wxGetLocalTimeMillis() - m_t0).GetLo();
}
long wxStopWatch::Time() const