summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSebastian Hartte <sebastian@hartte.de>2010-06-18 23:54:45 (GMT)
committerJoerg Bornemann <joerg.bornemann@nokia.com>2010-06-21 13:55:39 (GMT)
commit7113c6d4be87ead4f2be9afe64c6e81e3f6720a3 (patch)
treec5ddd5ac05dd5650ea1d49fe05aca7985cb47602 /src
parenta4376f3760fae97b3ae45c9ae7b62ed505bfa05d (diff)
downloadQt-7113c6d4be87ead4f2be9afe64c6e81e3f6720a3.zip
Qt-7113c6d4be87ead4f2be9afe64c6e81e3f6720a3.tar.gz
Qt-7113c6d4be87ead4f2be9afe64c6e81e3f6720a3.tar.bz2
QElapsedTimer/Win: use QueryPerformanceCounter if available
Added a clock type to reflect this. Merge-request: 697 Reviewed-by: joerg Reviewed-by: thiago
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qelapsedtimer.cpp23
-rw-r--r--src/corelib/tools/qelapsedtimer.h3
-rw-r--r--src/corelib/tools/qelapsedtimer_win.cpp53
3 files changed, 68 insertions, 11 deletions
diff --git a/src/corelib/tools/qelapsedtimer.cpp b/src/corelib/tools/qelapsedtimer.cpp
index cb5e701..4adddf9 100644
--- a/src/corelib/tools/qelapsedtimer.cpp
+++ b/src/corelib/tools/qelapsedtimer.cpp
@@ -136,10 +136,11 @@ QT_BEGIN_NAMESPACE
implementations, to guarantee that the same reference clock is being
used.
- \value SystemTime The human-readable system time. This clock is not monotonic.
- \value MonotonicClock The system's monotonic clock, usually found in Unix systems. This clock is monotonic and does not overflow.
- \value TickCounter The system's tick counter, used on Windows and Symbian systems. This clock may overflow.
- \value MachAbsoluteTime The Mach kernel's absolute time (Mac OS X). This clock is monotonic and does not overflow.
+ \value SystemTime The human-readable system time. This clock is not monotonic.
+ \value MonotonicClock The system's monotonic clock, usually found in Unix systems. This clock is monotonic and does not overflow.
+ \value TickCounter The system's tick counter, used on Windows and Symbian systems. This clock may overflow.
+ \value MachAbsoluteTime The Mach kernel's absolute time (Mac OS X). This clock is monotonic and does not overflow.
+ \value PerformanceCounter The high-resolution performance counter provided by Windows. This clock is monotonic and does not overflow.
\section2 SystemTime
@@ -163,7 +164,9 @@ QT_BEGIN_NAMESPACE
The tick counter clock type is based on the system's or the processor's
tick counter, multiplied by the duration of a tick. This clock type is
- used on Windows and Symbian platforms.
+ used on Windows and Symbian platforms. If the high-precision performance
+ counter is available on Windows, the \tt{PerformanceCounter} clock type
+ is used instead.
The TickCounter clock type is the only clock type that may overflow.
Windows Vista and Windows Server 2008 support the extended 64-bit tick
@@ -191,6 +194,16 @@ QT_BEGIN_NAMESPACE
This clock is monotonic and does not overflow.
+ \section2 PerformanceCounter
+
+ This clock uses the Windows functions \tt{QueryPerformanceCounter} and
+ \tt{QueryPerformanceFrequency} to access the system's high-precision
+ performance counter. Since this counter may not be available on all
+ systems, QElapsedTimer will fall back to the \tt{TickCounter} clock
+ automatically, if this clock cannot be used.
+
+ This clock is monotonic and does not overflow.
+
\sa clockType(), isMonotonic()
*/
diff --git a/src/corelib/tools/qelapsedtimer.h b/src/corelib/tools/qelapsedtimer.h
index 0d6f0be..b996f6a 100644
--- a/src/corelib/tools/qelapsedtimer.h
+++ b/src/corelib/tools/qelapsedtimer.h
@@ -57,7 +57,8 @@ public:
SystemTime,
MonotonicClock,
TickCounter,
- MachAbsoluteTime
+ MachAbsoluteTime,
+ PerformanceCounter
};
static ClockType clockType();
static bool isMonotonic();
diff --git a/src/corelib/tools/qelapsedtimer_win.cpp b/src/corelib/tools/qelapsedtimer_win.cpp
index 135196a..c7c160d 100644
--- a/src/corelib/tools/qelapsedtimer_win.cpp
+++ b/src/corelib/tools/qelapsedtimer_win.cpp
@@ -42,6 +42,9 @@
#include "qelapsedtimer.h"
#include <windows.h>
+// Result of QueryPerformanceFrequency, 0 indicates that the high resolution timer is unavailable
+static quint64 counterFrequency = 0;
+
typedef ULONGLONG (WINAPI *PtrGetTickCount64)(void);
static PtrGetTickCount64 ptrGetTickCount64 = 0;
@@ -65,12 +68,44 @@ static void resolveLibs()
ptrGetTickCount64 = (PtrGetTickCount64)GetProcAddress(kernel32, "GetTickCount64");
#endif
+ // Retrieve the number of high-resolution performance counter ticks per second
+ LARGE_INTEGER frequency;
+ if (!QueryPerformanceFrequency(&frequency)) {
+ counterFrequency = 0;
+ } else {
+ counterFrequency = frequency.QuadPart;
+ }
+
done = true;
}
+static qint64 ticksToMilliseconds(qint64 ticks)
+{
+ if (counterFrequency > 0) {
+ // QueryPerformanceCounter uses an arbitrary frequency
+ return ticks * 1000 / counterFrequency;
+ } else {
+ // GetTickCount(64) return milliseconds
+ return ticks;
+ }
+}
+
static quint64 getTickCount()
{
resolveLibs();
+
+ // This avoids a division by zero and disables the high performance counter if it's not available
+ if (counterFrequency > 0) {
+ LARGE_INTEGER counter;
+
+ if (QueryPerformanceCounter(&counter)) {
+ return counter.QuadPart;
+ } else {
+ qWarning("QueryPerformanceCounter failed, although QueryPerformanceFrequency succeeded.");
+ return 0;
+ }
+ }
+
if (ptrGetTickCount64)
return ptrGetTickCount64();
@@ -85,7 +120,13 @@ static quint64 getTickCount()
QElapsedTimer::ClockType QElapsedTimer::clockType()
{
- return TickCounter;
+ resolveLibs();
+
+ if (counterFrequency > 0) {
+ return PerformanceCounter;
+ } else {
+ return TickCounter;
+ }
}
bool QElapsedTimer::isMonotonic()
@@ -104,22 +145,24 @@ qint64 QElapsedTimer::restart()
qint64 oldt1 = t1;
t1 = getTickCount();
t2 = 0;
- return t1 - oldt1;
+ return ticksToMilliseconds(t1 - oldt1);
}
qint64 QElapsedTimer::elapsed() const
{
- return getTickCount() - t1;
+ qint64 elapsed = getTickCount() - t1;
+ return ticksToMilliseconds(elapsed);
}
qint64 QElapsedTimer::msecsSinceReference() const
{
- return t1;
+ return ticksToMilliseconds(t1);
}
qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const
{
- return other.t1 - t1;
+ qint64 difference = other.t1 - t1;
+ return ticksToMilliseconds(difference);
}
qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const