Qt 4.8
qelapsedtimer_win.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qelapsedtimer.h"
43 #include <windows.h>
44 
45 #include <private/qsystemlibrary_p.h>
46 
47 typedef ULONGLONG (WINAPI *PtrGetTickCount64)(void);
49 
51 
52 // Result of QueryPerformanceFrequency, 0 indicates that the high resolution timer is unavailable
54 
55 static void resolveLibs()
56 {
57  static volatile bool done = false;
58  if (done)
59  return;
60 
61  // try to get GetTickCount64 from the system
62  QSystemLibrary kernel32(QLatin1String("kernel32"));
63  if (!kernel32.load())
64  return;
65 
66  // does this function exist on WinCE, or will ever exist?
67  ptrGetTickCount64 = (PtrGetTickCount64)kernel32.resolve("GetTickCount64");
68 
69  // Retrieve the number of high-resolution performance counter ticks per second
70  LARGE_INTEGER frequency;
71  if (!QueryPerformanceFrequency(&frequency)) {
72  counterFrequency = 0;
73  } else {
74  counterFrequency = frequency.QuadPart;
75  }
76 
77  done = true;
78 }
79 
80 static inline qint64 ticksToNanoseconds(qint64 ticks)
81 {
82  if (counterFrequency > 0) {
83  // QueryPerformanceCounter uses an arbitrary frequency
84  qint64 seconds = ticks / counterFrequency;
85  qint64 nanoSeconds = (ticks - seconds * counterFrequency) * 1000000000 / counterFrequency;
86  return seconds * 1000000000 + nanoSeconds;
87  } else {
88  // GetTickCount(64) return milliseconds
89  return ticks * 1000000;
90  }
91 }
92 
94 {
95  resolveLibs();
96 
97  // This avoids a division by zero and disables the high performance counter if it's not available
98  if (counterFrequency > 0) {
99  LARGE_INTEGER counter;
100 
101  if (QueryPerformanceCounter(&counter)) {
102  return counter.QuadPart;
103  } else {
104  qWarning("QueryPerformanceCounter failed, although QueryPerformanceFrequency succeeded.");
105  return 0;
106  }
107  }
108 
109  if (ptrGetTickCount64)
110  return ptrGetTickCount64();
111 
112  static quint32 highdword = 0;
113  static quint32 lastval = 0;
114  quint32 val = GetTickCount();
115  if (val < lastval)
116  ++highdword;
117  lastval = val;
118  return val | (quint64(highdword) << 32);
119 }
120 
122 {
123  resolveLibs();
124 
125  if (counterFrequency > 0)
126  return PerformanceCounter;
127  else
128  return TickCounter;
129 }
130 
132 {
133  return true;
134 }
135 
137 {
138  t1 = getTickCount();
139  t2 = 0;
140 }
141 
143 {
144  qint64 oldt1 = t1;
145  t1 = getTickCount();
146  t2 = 0;
147  return ticksToNanoseconds(t1 - oldt1) / 1000000;
148 }
149 
151 {
153  return ticksToNanoseconds(elapsed);
154 }
155 
157 {
159  return ticksToNanoseconds(elapsed) / 1000000;
160 }
161 
163 {
164  return ticksToNanoseconds(t1) / 1000000;
165 }
166 
167 qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const
168 {
169  qint64 difference = other.t1 - t1;
170  return ticksToNanoseconds(difference) / 1000000;
171 }
172 
173 qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const
174 {
175  return msecsTo(other) / 1000;
176 }
177 
178 bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2)
179 {
180  return (v1.t1 - v2.t1) < 0;
181 }
182 
ClockType
This enum contains the different clock types that QElapsedTimer may use.
Definition: qelapsedtimer.h:56
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
qint64 msecsTo(const QElapsedTimer &other) const
Returns the number of milliseconds between this QElapsedTimer and other.
static qint64 ticksToNanoseconds(qint64 ticks)
friend bool Q_CORE_EXPORT operator<(const QElapsedTimer &v1, const QElapsedTimer &v2)
Returns true if v1 was started before v2, false otherwise.
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
bool load(bool onlySystemDirectory=true)
The QElapsedTimer class provides a fast way to calculate elapsed times.
Definition: qelapsedtimer.h:53
static bool isMonotonic()
Returns true if this is a monotonic clock, false otherwise.
qint64 elapsed() const
Returns the number of milliseconds since this QElapsedTimer was last started.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static quint64 counterFrequency
qint64 restart()
Restarts the timer and returns the time elapsed since the previous start.
unsigned __int64 quint64
Definition: qglobal.h:943
Q_CORE_EXPORT void qWarning(const char *,...)
static void resolveLibs()
qint64 nsecsElapsed() const
Returns the number of nanoseconds since this QElapsedTimer was last started.
ULONGLONG(WINAPI * PtrGetTickCount64)(void)
__int64 qint64
Definition: qglobal.h:942
static ClockType clockType()
Returns the clock type that this QElapsedTimer implementation uses.
static quint64 getTickCount()
void * resolve(const char *symbol)
static PtrGetTickCount64 ptrGetTickCount64
qint64 msecsSinceReference() const
Returns the number of milliseconds between last time this QElapsedTimer object was started and its re...
unsigned int quint32
Definition: qglobal.h:938
void start()
Starts this timer.
qint64 secsTo(const QElapsedTimer &other) const
Returns the number of seconds between this QElapsedTimer and other.