From 169f1beaf55770c2a26d76ad9a63dfd3474cff91 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 26 Apr 2016 21:20:11 -0700 Subject: Move QElapsedTimer to src/corelib/kernel It's really a kernel functionality, as it implements really low-level functionality and it's used by the event dispatcher. It was in tools/ only because QTime is. QDeadlineTimer is also coming to kernel/. Change-Id: Ifea6e497f11a461db432ffff14491c6d9b839eb0 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/corelib/kernel/kernel.pri | 7 + src/corelib/kernel/qelapsedtimer.cpp | 267 +++++++++++++++++++++++++++ src/corelib/kernel/qelapsedtimer.h | 95 ++++++++++ src/corelib/kernel/qelapsedtimer_generic.cpp | 204 ++++++++++++++++++++ src/corelib/kernel/qelapsedtimer_mac.cpp | 149 +++++++++++++++ src/corelib/kernel/qelapsedtimer_unix.cpp | 251 +++++++++++++++++++++++++ src/corelib/kernel/qelapsedtimer_win.cpp | 164 ++++++++++++++++ src/corelib/tools/qelapsedtimer.cpp | 267 --------------------------- src/corelib/tools/qelapsedtimer.h | 95 ---------- src/corelib/tools/qelapsedtimer_generic.cpp | 204 -------------------- src/corelib/tools/qelapsedtimer_mac.cpp | 149 --------------- src/corelib/tools/qelapsedtimer_unix.cpp | 251 ------------------------- src/corelib/tools/qelapsedtimer_win.cpp | 164 ---------------- src/corelib/tools/tools.pri | 15 +- 14 files changed, 1143 insertions(+), 1139 deletions(-) create mode 100644 src/corelib/kernel/qelapsedtimer.cpp create mode 100644 src/corelib/kernel/qelapsedtimer.h create mode 100644 src/corelib/kernel/qelapsedtimer_generic.cpp create mode 100644 src/corelib/kernel/qelapsedtimer_mac.cpp create mode 100644 src/corelib/kernel/qelapsedtimer_unix.cpp create mode 100644 src/corelib/kernel/qelapsedtimer_win.cpp delete mode 100644 src/corelib/tools/qelapsedtimer.cpp delete mode 100644 src/corelib/tools/qelapsedtimer.h delete mode 100644 src/corelib/tools/qelapsedtimer_generic.cpp delete mode 100644 src/corelib/tools/qelapsedtimer_mac.cpp delete mode 100644 src/corelib/tools/qelapsedtimer_unix.cpp delete mode 100644 src/corelib/tools/qelapsedtimer_win.cpp (limited to 'src') diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 991b73812a..39fe61ea4e 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -4,6 +4,7 @@ HEADERS += \ kernel/qabstracteventdispatcher.h \ kernel/qabstractnativeeventfilter.h \ kernel/qbasictimer.h \ + kernel/qelapsedtimer.h \ kernel/qeventloop.h\ kernel/qpointer.h \ kernel/qcorecmdlineargs_p.h \ @@ -45,6 +46,7 @@ SOURCES += \ kernel/qabstracteventdispatcher.cpp \ kernel/qabstractnativeeventfilter.cpp \ kernel/qbasictimer.cpp \ + kernel/qelapsedtimer.cpp \ kernel/qeventloop.cpp \ kernel/qcoreapplication.cpp \ kernel/qcoreevent.cpp \ @@ -69,6 +71,7 @@ SOURCES += \ win32 { SOURCES += \ kernel/qcoreapplication_win.cpp \ + kernel/qelapsedtimer_win.cpp \ kernel/qwineventnotifier.cpp \ kernel/qsharedmemory_win.cpp \ kernel/qsystemsemaphore_win.cpp @@ -103,6 +106,7 @@ mac { kernel/qcoreapplication_mac.cpp \ kernel/qcore_mac.cpp \ kernel/qcore_foundation.mm + !nacl: SOURCES += kernel/qelapsedtimer_mac.cpp OBJECTIVE_SOURCES += \ kernel/qcore_mac_objc.mm \ @@ -131,6 +135,7 @@ unix|integrity { kernel/qcrashhandler.cpp \ kernel/qeventdispatcher_unix.cpp \ kernel/qtimerinfo_unix.cpp + !darwin|nacl: SOURCES += kernel/qelapsedtimer_unix.cpp HEADERS += \ kernel/qcore_unix_p.h \ @@ -196,3 +201,5 @@ android { kernel/qjnihelpers_p.h \ kernel/qjni_p.h } + +!darwin:!unix:!win32: SOURCES += kernel/qelapsedtimer_generic.cpp diff --git a/src/corelib/kernel/qelapsedtimer.cpp b/src/corelib/kernel/qelapsedtimer.cpp new file mode 100644 index 0000000000..2eabb4c3a3 --- /dev/null +++ b/src/corelib/kernel/qelapsedtimer.cpp @@ -0,0 +1,267 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QElapsedTimer + \inmodule QtCore + \brief The QElapsedTimer class provides a fast way to calculate elapsed times. + \since 4.7 + + \reentrant + \ingroup tools + + The QElapsedTimer class is usually used to quickly calculate how much + time has elapsed between two events. Its API is similar to that of QTime, + so code that was using that can be ported quickly to the new class. + + However, unlike QTime, QElapsedTimer tries to use monotonic clocks if + possible. This means it's not possible to convert QElapsedTimer objects + to a human-readable time. + + The typical use-case for the class is to determine how much time was + spent in a slow operation. The simplest example of such a case is for + debugging purposes, as in the following example: + + \snippet qelapsedtimer/main.cpp 0 + + In this example, the timer is started by a call to start() and the + elapsed timer is calculated by the elapsed() function. + + The time elapsed can also be used to recalculate the time available for + another operation, after the first one is complete. This is useful when + the execution must complete within a certain time period, but several + steps are needed. The \tt{waitFor}-type functions in QIODevice and its + subclasses are good examples of such need. In that case, the code could + be as follows: + + \snippet qelapsedtimer/main.cpp 1 + + Another use-case is to execute a certain operation for a specific + timeslice. For this, QElapsedTimer provides the hasExpired() convenience + function, which can be used to determine if a certain number of + milliseconds has already elapsed: + + \snippet qelapsedtimer/main.cpp 2 + + \section1 Reference Clocks + + QElapsedTimer will use the platform's monotonic reference clock in all + platforms that support it (see QElapsedTimer::isMonotonic()). This has + the added benefit that QElapsedTimer is immune to time adjustments, such + as the user correcting the time. Also unlike QTime, QElapsedTimer is + immune to changes in the timezone settings, such as daylight-saving + periods. + + On the other hand, this means QElapsedTimer values can only be compared + with other values that use the same reference. This is especially true if + the time since the reference is extracted from the QElapsedTimer object + (QElapsedTimer::msecsSinceReference()) and serialised. These values + should never be exchanged across the network or saved to disk, since + there's no telling whether the computer node receiving the data is the + same as the one originating it or if it has rebooted since. + + It is, however, possible to exchange the value with other processes + running on the same machine, provided that they also use the same + reference clock. QElapsedTimer will always use the same clock, so it's + safe to compare with the value coming from another process in the same + machine. If comparing to values produced by other APIs, you should check + that the clock used is the same as QElapsedTimer (see + QElapsedTimer::clockType()). + + \section2 32-bit overflows + + Some of the clocks used by QElapsedTimer have a limited range and may + overflow after hitting the upper limit (usually 32-bit). QElapsedTimer + deals with this overflow issue and presents a consistent timing. However, + when extracting the time since reference from QElapsedTimer, two + different processes in the same machine may have different understanding + of how much time has actually elapsed. + + The information on which clocks types may overflow and how to remedy that + issue is documented along with the clock types. + + \sa QTime, QTimer +*/ + +/*! + \enum QElapsedTimer::ClockType + + This enum contains the different clock types that QElapsedTimer may use. + + QElapsedTimer will always use the same clock type in a particular + machine, so this value will not change during the lifetime of a program. + It is provided so that QElapsedTimer can be used with other non-Qt + 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 systems. This clock may overflow. + \value MachAbsoluteTime The Mach kernel's absolute time (OS X and iOS). 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 + + The system time clock is purely the real time, expressed in milliseconds + since Jan 1, 1970 at 0:00 UTC. It's equivalent to the value returned by + the C and POSIX \tt{time} function, with the milliseconds added. This + clock type is currently only used on Unix systems that do not support + monotonic clocks (see below). + + This is the only non-monotonic clock that QElapsedTimer may use. + + \section2 MonotonicClock + + This is the system's monotonic clock, expressed in milliseconds since an + arbitrary point in the past. This clock type is used on Unix systems + which support POSIX monotonic clocks (\tt{_POSIX_MONOTONIC_CLOCK}). + + This clock does not overflow. + + \section2 TickCounter + + 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 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 + counter, which allows avoiding the overflow. + + On Windows systems, the clock overflows after 2^32 milliseconds, which + corresponds to roughly 49.7 days. This means two processes' reckoning of + the time since the reference may be different by multiples of 2^32 + milliseconds. When comparing such values, it's recommended that the high + 32 bits of the millisecond count be masked off. + + \section2 MachAbsoluteTime + + This clock type is based on the absolute time presented by Mach kernels, + such as that found on OS X. This clock type is presented separately + from MonotonicClock since OS X and iOS are also Unix systems and may support + a POSIX monotonic clock with values differing from the Mach absolute + time. + + 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() +*/ + +/*! + \fn QElapsedTimer::QElapsedTimer() + \since 5.4 + + Constructs an invalid QElapsedTimer. A timer becomes valid once it has been + started. + + \sa isValid(), start() +*/ + + +/*! + \fn bool QElapsedTimer::operator ==(const QElapsedTimer &other) const + + Returns \c true if this object and \a other contain the same time. +*/ + +/*! + \fn bool QElapsedTimer::operator !=(const QElapsedTimer &other) const + + Returns \c true if this object and \a other contain different times. +*/ + +static const qint64 invalidData = Q_INT64_C(0x8000000000000000); + +/*! + Marks this QElapsedTimer object as invalid. + + An invalid object can be checked with isValid(). Calculations of timer + elapsed since invalid data are undefined and will likely produce bizarre + results. + + \sa isValid(), start(), restart() +*/ +void QElapsedTimer::invalidate() Q_DECL_NOTHROW +{ + t1 = t2 = invalidData; +} + +/*! + Returns \c false if the timer has never been started or invalidated by a + call to invalidate(). + + \sa invalidate(), start(), restart() +*/ +bool QElapsedTimer::isValid() const Q_DECL_NOTHROW +{ + return t1 != invalidData && t2 != invalidData; +} + +/*! + Returns \c true if this QElapsedTimer has already expired by \a timeout + milliseconds (that is, more than \a timeout milliseconds have elapsed). + The value of \a timeout can be -1 to indicate that this timer does not + expire, in which case this function will always return false. + + \sa elapsed() +*/ +bool QElapsedTimer::hasExpired(qint64 timeout) const Q_DECL_NOTHROW +{ + // if timeout is -1, quint64(timeout) is LLINT_MAX, so this will be + // considered as never expired + return quint64(elapsed()) > quint64(timeout); +} + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qelapsedtimer.h b/src/corelib/kernel/qelapsedtimer.h new file mode 100644 index 0000000000..7954b41bf4 --- /dev/null +++ b/src/corelib/kernel/qelapsedtimer.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QELAPSEDTIMER_H +#define QELAPSEDTIMER_H + +#include + +QT_BEGIN_NAMESPACE + + +class Q_CORE_EXPORT QElapsedTimer +{ +public: + enum ClockType { + SystemTime, + MonotonicClock, + TickCounter, + MachAbsoluteTime, + PerformanceCounter + }; + + Q_DECL_CONSTEXPR QElapsedTimer() + : t1(Q_INT64_C(0x8000000000000000)), + t2(Q_INT64_C(0x8000000000000000)) + { + } + + static ClockType clockType() Q_DECL_NOTHROW; + static bool isMonotonic() Q_DECL_NOTHROW; + + void start() Q_DECL_NOTHROW; + qint64 restart() Q_DECL_NOTHROW; + void invalidate() Q_DECL_NOTHROW; + bool isValid() const Q_DECL_NOTHROW; + + qint64 nsecsElapsed() const Q_DECL_NOTHROW; + qint64 elapsed() const Q_DECL_NOTHROW; + bool hasExpired(qint64 timeout) const Q_DECL_NOTHROW; + + qint64 msecsSinceReference() const Q_DECL_NOTHROW; + qint64 msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW; + qint64 secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW; + + bool operator==(const QElapsedTimer &other) const Q_DECL_NOTHROW + { return t1 == other.t1 && t2 == other.t2; } + bool operator!=(const QElapsedTimer &other) const Q_DECL_NOTHROW + { return !(*this == other); } + + friend bool Q_CORE_EXPORT operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW; + +private: + qint64 t1; + qint64 t2; +}; + +QT_END_NAMESPACE + +#endif // QELAPSEDTIMER_H diff --git a/src/corelib/kernel/qelapsedtimer_generic.cpp b/src/corelib/kernel/qelapsedtimer_generic.cpp new file mode 100644 index 0000000000..8c724247be --- /dev/null +++ b/src/corelib/kernel/qelapsedtimer_generic.cpp @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" +#include "qdatetime.h" + +QT_BEGIN_NAMESPACE + +/*! + Returns the clock type that this QElapsedTimer implementation uses. + + \sa isMonotonic() +*/ +QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW +{ + return SystemTime; +} + +/*! + Returns \c true if this is a monotonic clock, false otherwise. See the + information on the different clock types to understand which ones are + monotonic. + + \sa clockType(), QElapsedTimer::ClockType +*/ +bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW +{ + return false; +} + +/*! + Starts this timer. Once started, a timer value can be checked with elapsed() or msecsSinceReference(). + + Normally, a timer is started just before a lengthy operation, such as: + \snippet qelapsedtimer/main.cpp 0 + + Also, starting a timer makes it valid again. + + \sa restart(), invalidate(), elapsed() +*/ +void QElapsedTimer::start() Q_DECL_NOTHROW +{ + restart(); +} + +/*! + Restarts the timer and returns the time elapsed since the previous start. + This function is equivalent to obtaining the elapsed time with elapsed() + and then starting the timer again with start(), but it does so in one + single operation, avoiding the need to obtain the clock value twice. + + Calling this function on a QElapsedTimer that is invalid + results in undefined behavior. + + The following example illustrates how to use this function to calibrate a + parameter to a slow operation (for example, an iteration count) so that + this operation takes at least 250 milliseconds: + + \snippet qelapsedtimer/main.cpp 3 + + \sa start(), invalidate(), elapsed(), isValid() +*/ +qint64 QElapsedTimer::restart() Q_DECL_NOTHROW +{ + qint64 old = t1; + t1 = QDateTime::currentMSecsSinceEpoch(); + t2 = 0; + return t1 - old; +} + +/*! \since 4.8 + + Returns the number of nanoseconds since this QElapsedTimer was last + started. + + Calling this function on a QElapsedTimer that is invalid + results in undefined behavior. + + On platforms that do not provide nanosecond resolution, the value returned + will be the best estimate available. + + \sa start(), restart(), hasExpired(), invalidate() +*/ +qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW +{ + return elapsed() * 1000000; +} + +/*! + Returns the number of milliseconds since this QElapsedTimer was last + started. + + Calling this function on a QElapsedTimer that is invalid + results in undefined behavior. + + \sa start(), restart(), hasExpired(), isValid(), invalidate() +*/ +qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW +{ + return QDateTime::currentMSecsSinceEpoch() - t1; +} + +/*! + Returns the number of milliseconds between last time this QElapsedTimer + object was started and its reference clock's start. + + This number is usually arbitrary for all clocks except the + QElapsedTimer::SystemTime clock. For that clock type, this number is the + number of milliseconds since January 1st, 1970 at 0:00 UTC (that is, it + is the Unix time expressed in milliseconds). + + On Linux, Windows and OS X/iOS systems, this value is usually the time + since the system boot, though it usually does not include the time the + system has spent in sleep states. + + \sa clockType(), elapsed() +*/ +qint64 QElapsedTimer::msecsSinceReference() const Q_DECL_NOTHROW +{ + return t1; +} + +/*! + Returns the number of milliseconds between this QElapsedTimer and \a + other. If \a other was started before this object, the returned value + will be negative. If it was started later, the returned value will be + positive. + + The return value is undefined if this object or \a other were invalidated. + + \sa secsTo(), elapsed() +*/ +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + qint64 diff = other.t1 - t1; + return diff; +} + +/*! + Returns the number of seconds between this QElapsedTimer and \a other. If + \a other was started before this object, the returned value will be + negative. If it was started later, the returned value will be positive. + + Calling this function on or with a QElapsedTimer that is invalid + results in undefined behavior. + + \sa msecsTo(), elapsed() +*/ +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + return msecsTo(other) / 1000; +} + +/*! + \relates QElapsedTimer + + Returns \c true if \a v1 was started before \a v2, false otherwise. + + The returned value is undefined if one of the two parameters is invalid + and the other isn't. However, two invalid timers are equal and thus this + function will return false. +*/ +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW +{ + return v1.t1 < v2.t1; +} + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qelapsedtimer_mac.cpp b/src/corelib/kernel/qelapsedtimer_mac.cpp new file mode 100644 index 0000000000..886e0f41b2 --- /dev/null +++ b/src/corelib/kernel/qelapsedtimer_mac.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// ask for the latest POSIX, just in case +#define _POSIX_C_SOURCE 200809L + +#include "qelapsedtimer.h" +#include +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW +{ + return MachAbsoluteTime; +} + +bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW +{ + return true; +} + +static mach_timebase_info_data_t info = {0,0}; +static qint64 absoluteToNSecs(qint64 cpuTime) +{ + if (info.denom == 0) + mach_timebase_info(&info); +#ifdef __LP64__ + __uint128_t nsecs = static_cast<__uint128_t>(cpuTime) * info.numer / info.denom; + return static_cast(nsecs); +#else + qint64 nsecs = cpuTime * info.numer / info.denom; + return nsecs; +#endif +} + +static qint64 absoluteToMSecs(qint64 cpuTime) +{ + return absoluteToNSecs(cpuTime) / 1000000; +} + +timespec qt_gettime() Q_DECL_NOTHROW +{ + timespec tv; + + uint64_t cpu_time = mach_absolute_time(); + uint64_t nsecs = absoluteToNSecs(cpu_time); + tv.tv_sec = nsecs / 1000000000ull; + tv.tv_nsec = nsecs - (tv.tv_sec * 1000000000ull); + return tv; +} + +void qt_nanosleep(timespec amount) +{ + // Mac doesn't have clock_nanosleep, but it does have nanosleep. + // nanosleep is POSIX.1-1993 + + int r; + EINTR_LOOP(r, nanosleep(&amount, &amount)); +} + +void QElapsedTimer::start() Q_DECL_NOTHROW +{ + t1 = mach_absolute_time(); + t2 = 0; +} + +qint64 QElapsedTimer::restart() Q_DECL_NOTHROW +{ + qint64 old = t1; + t1 = mach_absolute_time(); + t2 = 0; + + return absoluteToMSecs(t1 - old); +} + +qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW +{ + uint64_t cpu_time = mach_absolute_time(); + return absoluteToNSecs(cpu_time - t1); +} + +qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW +{ + uint64_t cpu_time = mach_absolute_time(); + return absoluteToMSecs(cpu_time - t1); +} + +qint64 QElapsedTimer::msecsSinceReference() const Q_DECL_NOTHROW +{ + return absoluteToMSecs(t1); +} + +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + return absoluteToMSecs(other.t1 - t1); +} + +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + return msecsTo(other) / 1000; +} + +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW +{ + return v1.t1 < v2.t1; +} + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qelapsedtimer_unix.cpp b/src/corelib/kernel/qelapsedtimer_unix.cpp new file mode 100644 index 0000000000..e2c3ae6280 --- /dev/null +++ b/src/corelib/kernel/qelapsedtimer_unix.cpp @@ -0,0 +1,251 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Intel Corporation. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" +#if defined(Q_OS_VXWORKS) +#include "qfunctions_vxworks.h" +#else +#include +#include +#endif +#include + +#include +#include "private/qcore_unix_p.h" + +#if defined(QT_NO_CLOCK_MONOTONIC) || defined(QT_BOOTSTRAPPED) +// turn off the monotonic clock +# ifdef _POSIX_MONOTONIC_CLOCK +# undef _POSIX_MONOTONIC_CLOCK +# endif +# define _POSIX_MONOTONIC_CLOCK -1 +#endif + +QT_BEGIN_NAMESPACE + +/* + * Design: + * + * POSIX offers a facility to select the system's monotonic clock when getting + * the current timestamp. Whereas the functions are mandatory in POSIX.1-2008, + * the presence of a monotonic clock is a POSIX Option (see the document + * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html#tag_02_01_06 ) + * + * The macro _POSIX_MONOTONIC_CLOCK can therefore assume the following values: + * -1 monotonic clock is never supported on this system + * 0 monotonic clock might be supported, runtime check is needed + * >1 (such as 200809L) monotonic clock is always supported + * + * The unixCheckClockType() function will return the clock to use: either + * CLOCK_MONOTONIC or CLOCK_REALTIME. In the case the POSIX option has a value + * of zero, then this function stores a static that contains the clock to be + * used. + * + * There's one extra case, which is when CLOCK_REALTIME isn't defined. When + * that's the case, we'll emulate the clock_gettime function with gettimeofday. + * + * Conforming to: + * POSIX.1b-1993 section "Clocks and Timers" + * included in UNIX98 (Single Unix Specification v2) + * included in POSIX.1-2001 + * see http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html + */ + +#if !defined(CLOCK_REALTIME) +# define CLOCK_REALTIME 0 +static inline void qt_clock_gettime(int, struct timespec *ts) +{ + // support clock_gettime with gettimeofday + struct timeval tv; + gettimeofday(&tv, 0); + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000; +} + +# ifdef _POSIX_MONOTONIC_CLOCK +# undef _POSIX_MONOTONIC_CLOCK +# define _POSIX_MONOTONIC_CLOCK -1 +# endif +#else +static inline void qt_clock_gettime(clockid_t clock, struct timespec *ts) +{ + clock_gettime(clock, ts); +} +#endif + +static int unixCheckClockType() +{ +#ifdef Q_OS_LINUX + // Despite glibc claiming that we should check at runtime, the Linux kernel + // always supports the monotonic clock + return CLOCK_MONOTONIC; +#elif (_POSIX_MONOTONIC_CLOCK-0 == 0) && defined(_SC_MONOTONIC_CLOCK) + // we need a value we can store in a clockid_t that isn't a valid clock + // check if the valid ones are both non-negative or both non-positive +# if CLOCK_MONOTONIC >= 0 && CLOCK_REALTIME >= 0 +# define IS_VALID_CLOCK(clock) (clock >= 0) +# define INVALID_CLOCK -1 +# elif CLOCK_MONOTONIC <= 0 && CLOCK_REALTIME <= 0 +# define IS_VALID_CLOCK(clock) (clock <= 0) +# define INVALID_CLOCK 1 +# else +# error "Sorry, your system has weird values for CLOCK_MONOTONIC and CLOCK_REALTIME" +# endif + + static QBasicAtomicInt clockToUse = Q_BASIC_ATOMIC_INITIALIZER(INVALID_CLOCK); + int clock = clockToUse.loadAcquire(); + if (Q_LIKELY(IS_VALID_CLOCK(clock))) + return clock; + + // detect if the system supports monotonic timers + clock = sysconf(_SC_MONOTONIC_CLOCK) > 0 ? CLOCK_MONOTONIC : CLOCK_REALTIME; + clockToUse.storeRelease(clock); + return clock; + +# undef INVALID_CLOCK +# undef IS_VALID_CLOCK +#elif (_POSIX_MONOTONIC_CLOCK-0) > 0 + return CLOCK_MONOTONIC; +#else + return CLOCK_REALTIME; +#endif +} + +bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW +{ + return clockType() == MonotonicClock; +} + +QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW +{ + return unixCheckClockType() == CLOCK_REALTIME ? SystemTime : MonotonicClock; +} + +static inline void do_gettime(qint64 *sec, qint64 *frac) +{ + timespec ts; + qt_clock_gettime(unixCheckClockType(), &ts); + *sec = ts.tv_sec; + *frac = ts.tv_nsec; +} + +// used in qcore_unix.cpp and qeventdispatcher_unix.cpp +struct timespec qt_gettime() Q_DECL_NOTHROW +{ + qint64 sec, frac; + do_gettime(&sec, &frac); + + timespec tv; + tv.tv_sec = sec; + tv.tv_nsec = frac; + + return tv; +} + +void qt_nanosleep(timespec amount) +{ + // We'd like to use clock_nanosleep. + // + // But clock_nanosleep is from POSIX.1-2001 and both are *not* + // affected by clock changes when using relative sleeps, even for + // CLOCK_REALTIME. + // + // nanosleep is POSIX.1-1993 + + int r; + EINTR_LOOP(r, nanosleep(&amount, &amount)); +} + +static qint64 elapsedAndRestart(qint64 sec, qint64 frac, + qint64 *nowsec, qint64 *nowfrac) +{ + do_gettime(nowsec, nowfrac); + sec = *nowsec - sec; + frac = *nowfrac - frac; + return (sec * Q_INT64_C(1000000000) + frac) / Q_INT64_C(1000000); +} + +void QElapsedTimer::start() Q_DECL_NOTHROW +{ + do_gettime(&t1, &t2); +} + +qint64 QElapsedTimer::restart() Q_DECL_NOTHROW +{ + return elapsedAndRestart(t1, t2, &t1, &t2); +} + +qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW +{ + qint64 sec, frac; + do_gettime(&sec, &frac); + sec = sec - t1; + frac = frac - t2; + return sec * Q_INT64_C(1000000000) + frac; +} + +qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW +{ + return nsecsElapsed() / Q_INT64_C(1000000); +} + +qint64 QElapsedTimer::msecsSinceReference() const Q_DECL_NOTHROW +{ + return t1 * Q_INT64_C(1000) + t2 / Q_INT64_C(1000000); +} + +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + qint64 secs = other.t1 - t1; + qint64 fraction = other.t2 - t2; + return (secs * Q_INT64_C(1000000000) + fraction) / Q_INT64_C(1000000); +} + +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + return other.t1 - t1; +} + +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW +{ + return v1.t1 < v2.t1 || (v1.t1 == v2.t1 && v1.t2 < v2.t2); +} + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qelapsedtimer_win.cpp b/src/corelib/kernel/qelapsedtimer_win.cpp new file mode 100644 index 0000000000..520126d262 --- /dev/null +++ b/src/corelib/kernel/qelapsedtimer_win.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" +#include + +QT_BEGIN_NAMESPACE + +// Result of QueryPerformanceFrequency, 0 indicates that the high resolution timer is unavailable +static quint64 counterFrequency = 0; + +static void resolveCounterFrequency() +{ + static bool done = false; + if (done) + return; + + // Retrieve the number of high-resolution performance counter ticks per second + LARGE_INTEGER frequency; + if (!QueryPerformanceFrequency(&frequency)) { + qFatal("QueryPerformanceFrequency failed, even though Microsoft documentation promises it wouldn't."); + counterFrequency = 0; + } else { + counterFrequency = frequency.QuadPart; + } + + done = true; +} + +static inline qint64 ticksToNanoseconds(qint64 ticks) +{ + if (counterFrequency > 0) { + // QueryPerformanceCounter uses an arbitrary frequency + qint64 seconds = ticks / counterFrequency; + qint64 nanoSeconds = (ticks - seconds * counterFrequency) * 1000000000 / counterFrequency; + return seconds * 1000000000 + nanoSeconds; + } else { + // GetTickCount(64) return milliseconds + return ticks * 1000000; + } +} + +static quint64 getTickCount() +{ + resolveCounterFrequency(); + + // This avoids a division by zero and disables the high performance counter if it's not available + if (counterFrequency > 0) { + LARGE_INTEGER counter; + + bool ok = QueryPerformanceCounter(&counter); + Q_ASSERT_X(ok, "QElapsedTimer::start()", + "QueryPerformanceCounter failed, although QueryPerformanceFrequency succeeded."); + Q_UNUSED(ok); + return counter.QuadPart; + } + + return GetTickCount64(); +} + +quint64 qt_msectime() +{ + return ticksToNanoseconds(getTickCount()) / 1000000; +} + +QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW +{ + resolveCounterFrequency(); + + if (counterFrequency > 0) + return PerformanceCounter; + else + return TickCounter; +} + +bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW +{ + return true; +} + +void QElapsedTimer::start() Q_DECL_NOTHROW +{ + t1 = getTickCount(); + t2 = 0; +} + +qint64 QElapsedTimer::restart() Q_DECL_NOTHROW +{ + qint64 oldt1 = t1; + t1 = getTickCount(); + t2 = 0; + return ticksToNanoseconds(t1 - oldt1) / 1000000; +} + +qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW +{ + qint64 elapsed = getTickCount() - t1; + return ticksToNanoseconds(elapsed); +} + +qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW +{ + qint64 elapsed = getTickCount() - t1; + return ticksToNanoseconds(elapsed) / 1000000; +} + +qint64 QElapsedTimer::msecsSinceReference() const Q_DECL_NOTHROW +{ + return ticksToNanoseconds(t1) / 1000000; +} + +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + qint64 difference = other.t1 - t1; + return ticksToNanoseconds(difference) / 1000000; +} + +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + return msecsTo(other) / 1000; +} + +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW +{ + return (v1.t1 - v2.t1) < 0; +} + +QT_END_NAMESPACE diff --git a/src/corelib/tools/qelapsedtimer.cpp b/src/corelib/tools/qelapsedtimer.cpp deleted file mode 100644 index 2eabb4c3a3..0000000000 --- a/src/corelib/tools/qelapsedtimer.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qelapsedtimer.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QElapsedTimer - \inmodule QtCore - \brief The QElapsedTimer class provides a fast way to calculate elapsed times. - \since 4.7 - - \reentrant - \ingroup tools - - The QElapsedTimer class is usually used to quickly calculate how much - time has elapsed between two events. Its API is similar to that of QTime, - so code that was using that can be ported quickly to the new class. - - However, unlike QTime, QElapsedTimer tries to use monotonic clocks if - possible. This means it's not possible to convert QElapsedTimer objects - to a human-readable time. - - The typical use-case for the class is to determine how much time was - spent in a slow operation. The simplest example of such a case is for - debugging purposes, as in the following example: - - \snippet qelapsedtimer/main.cpp 0 - - In this example, the timer is started by a call to start() and the - elapsed timer is calculated by the elapsed() function. - - The time elapsed can also be used to recalculate the time available for - another operation, after the first one is complete. This is useful when - the execution must complete within a certain time period, but several - steps are needed. The \tt{waitFor}-type functions in QIODevice and its - subclasses are good examples of such need. In that case, the code could - be as follows: - - \snippet qelapsedtimer/main.cpp 1 - - Another use-case is to execute a certain operation for a specific - timeslice. For this, QElapsedTimer provides the hasExpired() convenience - function, which can be used to determine if a certain number of - milliseconds has already elapsed: - - \snippet qelapsedtimer/main.cpp 2 - - \section1 Reference Clocks - - QElapsedTimer will use the platform's monotonic reference clock in all - platforms that support it (see QElapsedTimer::isMonotonic()). This has - the added benefit that QElapsedTimer is immune to time adjustments, such - as the user correcting the time. Also unlike QTime, QElapsedTimer is - immune to changes in the timezone settings, such as daylight-saving - periods. - - On the other hand, this means QElapsedTimer values can only be compared - with other values that use the same reference. This is especially true if - the time since the reference is extracted from the QElapsedTimer object - (QElapsedTimer::msecsSinceReference()) and serialised. These values - should never be exchanged across the network or saved to disk, since - there's no telling whether the computer node receiving the data is the - same as the one originating it or if it has rebooted since. - - It is, however, possible to exchange the value with other processes - running on the same machine, provided that they also use the same - reference clock. QElapsedTimer will always use the same clock, so it's - safe to compare with the value coming from another process in the same - machine. If comparing to values produced by other APIs, you should check - that the clock used is the same as QElapsedTimer (see - QElapsedTimer::clockType()). - - \section2 32-bit overflows - - Some of the clocks used by QElapsedTimer have a limited range and may - overflow after hitting the upper limit (usually 32-bit). QElapsedTimer - deals with this overflow issue and presents a consistent timing. However, - when extracting the time since reference from QElapsedTimer, two - different processes in the same machine may have different understanding - of how much time has actually elapsed. - - The information on which clocks types may overflow and how to remedy that - issue is documented along with the clock types. - - \sa QTime, QTimer -*/ - -/*! - \enum QElapsedTimer::ClockType - - This enum contains the different clock types that QElapsedTimer may use. - - QElapsedTimer will always use the same clock type in a particular - machine, so this value will not change during the lifetime of a program. - It is provided so that QElapsedTimer can be used with other non-Qt - 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 systems. This clock may overflow. - \value MachAbsoluteTime The Mach kernel's absolute time (OS X and iOS). 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 - - The system time clock is purely the real time, expressed in milliseconds - since Jan 1, 1970 at 0:00 UTC. It's equivalent to the value returned by - the C and POSIX \tt{time} function, with the milliseconds added. This - clock type is currently only used on Unix systems that do not support - monotonic clocks (see below). - - This is the only non-monotonic clock that QElapsedTimer may use. - - \section2 MonotonicClock - - This is the system's monotonic clock, expressed in milliseconds since an - arbitrary point in the past. This clock type is used on Unix systems - which support POSIX monotonic clocks (\tt{_POSIX_MONOTONIC_CLOCK}). - - This clock does not overflow. - - \section2 TickCounter - - 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 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 - counter, which allows avoiding the overflow. - - On Windows systems, the clock overflows after 2^32 milliseconds, which - corresponds to roughly 49.7 days. This means two processes' reckoning of - the time since the reference may be different by multiples of 2^32 - milliseconds. When comparing such values, it's recommended that the high - 32 bits of the millisecond count be masked off. - - \section2 MachAbsoluteTime - - This clock type is based on the absolute time presented by Mach kernels, - such as that found on OS X. This clock type is presented separately - from MonotonicClock since OS X and iOS are also Unix systems and may support - a POSIX monotonic clock with values differing from the Mach absolute - time. - - 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() -*/ - -/*! - \fn QElapsedTimer::QElapsedTimer() - \since 5.4 - - Constructs an invalid QElapsedTimer. A timer becomes valid once it has been - started. - - \sa isValid(), start() -*/ - - -/*! - \fn bool QElapsedTimer::operator ==(const QElapsedTimer &other) const - - Returns \c true if this object and \a other contain the same time. -*/ - -/*! - \fn bool QElapsedTimer::operator !=(const QElapsedTimer &other) const - - Returns \c true if this object and \a other contain different times. -*/ - -static const qint64 invalidData = Q_INT64_C(0x8000000000000000); - -/*! - Marks this QElapsedTimer object as invalid. - - An invalid object can be checked with isValid(). Calculations of timer - elapsed since invalid data are undefined and will likely produce bizarre - results. - - \sa isValid(), start(), restart() -*/ -void QElapsedTimer::invalidate() Q_DECL_NOTHROW -{ - t1 = t2 = invalidData; -} - -/*! - Returns \c false if the timer has never been started or invalidated by a - call to invalidate(). - - \sa invalidate(), start(), restart() -*/ -bool QElapsedTimer::isValid() const Q_DECL_NOTHROW -{ - return t1 != invalidData && t2 != invalidData; -} - -/*! - Returns \c true if this QElapsedTimer has already expired by \a timeout - milliseconds (that is, more than \a timeout milliseconds have elapsed). - The value of \a timeout can be -1 to indicate that this timer does not - expire, in which case this function will always return false. - - \sa elapsed() -*/ -bool QElapsedTimer::hasExpired(qint64 timeout) const Q_DECL_NOTHROW -{ - // if timeout is -1, quint64(timeout) is LLINT_MAX, so this will be - // considered as never expired - return quint64(elapsed()) > quint64(timeout); -} - -QT_END_NAMESPACE diff --git a/src/corelib/tools/qelapsedtimer.h b/src/corelib/tools/qelapsedtimer.h deleted file mode 100644 index 7954b41bf4..0000000000 --- a/src/corelib/tools/qelapsedtimer.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QELAPSEDTIMER_H -#define QELAPSEDTIMER_H - -#include - -QT_BEGIN_NAMESPACE - - -class Q_CORE_EXPORT QElapsedTimer -{ -public: - enum ClockType { - SystemTime, - MonotonicClock, - TickCounter, - MachAbsoluteTime, - PerformanceCounter - }; - - Q_DECL_CONSTEXPR QElapsedTimer() - : t1(Q_INT64_C(0x8000000000000000)), - t2(Q_INT64_C(0x8000000000000000)) - { - } - - static ClockType clockType() Q_DECL_NOTHROW; - static bool isMonotonic() Q_DECL_NOTHROW; - - void start() Q_DECL_NOTHROW; - qint64 restart() Q_DECL_NOTHROW; - void invalidate() Q_DECL_NOTHROW; - bool isValid() const Q_DECL_NOTHROW; - - qint64 nsecsElapsed() const Q_DECL_NOTHROW; - qint64 elapsed() const Q_DECL_NOTHROW; - bool hasExpired(qint64 timeout) const Q_DECL_NOTHROW; - - qint64 msecsSinceReference() const Q_DECL_NOTHROW; - qint64 msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW; - qint64 secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW; - - bool operator==(const QElapsedTimer &other) const Q_DECL_NOTHROW - { return t1 == other.t1 && t2 == other.t2; } - bool operator!=(const QElapsedTimer &other) const Q_DECL_NOTHROW - { return !(*this == other); } - - friend bool Q_CORE_EXPORT operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW; - -private: - qint64 t1; - qint64 t2; -}; - -QT_END_NAMESPACE - -#endif // QELAPSEDTIMER_H diff --git a/src/corelib/tools/qelapsedtimer_generic.cpp b/src/corelib/tools/qelapsedtimer_generic.cpp deleted file mode 100644 index 8c724247be..0000000000 --- a/src/corelib/tools/qelapsedtimer_generic.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qelapsedtimer.h" -#include "qdatetime.h" - -QT_BEGIN_NAMESPACE - -/*! - Returns the clock type that this QElapsedTimer implementation uses. - - \sa isMonotonic() -*/ -QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW -{ - return SystemTime; -} - -/*! - Returns \c true if this is a monotonic clock, false otherwise. See the - information on the different clock types to understand which ones are - monotonic. - - \sa clockType(), QElapsedTimer::ClockType -*/ -bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW -{ - return false; -} - -/*! - Starts this timer. Once started, a timer value can be checked with elapsed() or msecsSinceReference(). - - Normally, a timer is started just before a lengthy operation, such as: - \snippet qelapsedtimer/main.cpp 0 - - Also, starting a timer makes it valid again. - - \sa restart(), invalidate(), elapsed() -*/ -void QElapsedTimer::start() Q_DECL_NOTHROW -{ - restart(); -} - -/*! - Restarts the timer and returns the time elapsed since the previous start. - This function is equivalent to obtaining the elapsed time with elapsed() - and then starting the timer again with start(), but it does so in one - single operation, avoiding the need to obtain the clock value twice. - - Calling this function on a QElapsedTimer that is invalid - results in undefined behavior. - - The following example illustrates how to use this function to calibrate a - parameter to a slow operation (for example, an iteration count) so that - this operation takes at least 250 milliseconds: - - \snippet qelapsedtimer/main.cpp 3 - - \sa start(), invalidate(), elapsed(), isValid() -*/ -qint64 QElapsedTimer::restart() Q_DECL_NOTHROW -{ - qint64 old = t1; - t1 = QDateTime::currentMSecsSinceEpoch(); - t2 = 0; - return t1 - old; -} - -/*! \since 4.8 - - Returns the number of nanoseconds since this QElapsedTimer was last - started. - - Calling this function on a QElapsedTimer that is invalid - results in undefined behavior. - - On platforms that do not provide nanosecond resolution, the value returned - will be the best estimate available. - - \sa start(), restart(), hasExpired(), invalidate() -*/ -qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW -{ - return elapsed() * 1000000; -} - -/*! - Returns the number of milliseconds since this QElapsedTimer was last - started. - - Calling this function on a QElapsedTimer that is invalid - results in undefined behavior. - - \sa start(), restart(), hasExpired(), isValid(), invalidate() -*/ -qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW -{ - return QDateTime::currentMSecsSinceEpoch() - t1; -} - -/*! - Returns the number of milliseconds between last time this QElapsedTimer - object was started and its reference clock's start. - - This number is usually arbitrary for all clocks except the - QElapsedTimer::SystemTime clock. For that clock type, this number is the - number of milliseconds since January 1st, 1970 at 0:00 UTC (that is, it - is the Unix time expressed in milliseconds). - - On Linux, Windows and OS X/iOS systems, this value is usually the time - since the system boot, though it usually does not include the time the - system has spent in sleep states. - - \sa clockType(), elapsed() -*/ -qint64 QElapsedTimer::msecsSinceReference() const Q_DECL_NOTHROW -{ - return t1; -} - -/*! - Returns the number of milliseconds between this QElapsedTimer and \a - other. If \a other was started before this object, the returned value - will be negative. If it was started later, the returned value will be - positive. - - The return value is undefined if this object or \a other were invalidated. - - \sa secsTo(), elapsed() -*/ -qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW -{ - qint64 diff = other.t1 - t1; - return diff; -} - -/*! - Returns the number of seconds between this QElapsedTimer and \a other. If - \a other was started before this object, the returned value will be - negative. If it was started later, the returned value will be positive. - - Calling this function on or with a QElapsedTimer that is invalid - results in undefined behavior. - - \sa msecsTo(), elapsed() -*/ -qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW -{ - return msecsTo(other) / 1000; -} - -/*! - \relates QElapsedTimer - - Returns \c true if \a v1 was started before \a v2, false otherwise. - - The returned value is undefined if one of the two parameters is invalid - and the other isn't. However, two invalid timers are equal and thus this - function will return false. -*/ -bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW -{ - return v1.t1 < v2.t1; -} - -QT_END_NAMESPACE diff --git a/src/corelib/tools/qelapsedtimer_mac.cpp b/src/corelib/tools/qelapsedtimer_mac.cpp deleted file mode 100644 index 886e0f41b2..0000000000 --- a/src/corelib/tools/qelapsedtimer_mac.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// ask for the latest POSIX, just in case -#define _POSIX_C_SOURCE 200809L - -#include "qelapsedtimer.h" -#include -#include -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW -{ - return MachAbsoluteTime; -} - -bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW -{ - return true; -} - -static mach_timebase_info_data_t info = {0,0}; -static qint64 absoluteToNSecs(qint64 cpuTime) -{ - if (info.denom == 0) - mach_timebase_info(&info); -#ifdef __LP64__ - __uint128_t nsecs = static_cast<__uint128_t>(cpuTime) * info.numer / info.denom; - return static_cast(nsecs); -#else - qint64 nsecs = cpuTime * info.numer / info.denom; - return nsecs; -#endif -} - -static qint64 absoluteToMSecs(qint64 cpuTime) -{ - return absoluteToNSecs(cpuTime) / 1000000; -} - -timespec qt_gettime() Q_DECL_NOTHROW -{ - timespec tv; - - uint64_t cpu_time = mach_absolute_time(); - uint64_t nsecs = absoluteToNSecs(cpu_time); - tv.tv_sec = nsecs / 1000000000ull; - tv.tv_nsec = nsecs - (tv.tv_sec * 1000000000ull); - return tv; -} - -void qt_nanosleep(timespec amount) -{ - // Mac doesn't have clock_nanosleep, but it does have nanosleep. - // nanosleep is POSIX.1-1993 - - int r; - EINTR_LOOP(r, nanosleep(&amount, &amount)); -} - -void QElapsedTimer::start() Q_DECL_NOTHROW -{ - t1 = mach_absolute_time(); - t2 = 0; -} - -qint64 QElapsedTimer::restart() Q_DECL_NOTHROW -{ - qint64 old = t1; - t1 = mach_absolute_time(); - t2 = 0; - - return absoluteToMSecs(t1 - old); -} - -qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW -{ - uint64_t cpu_time = mach_absolute_time(); - return absoluteToNSecs(cpu_time - t1); -} - -qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW -{ - uint64_t cpu_time = mach_absolute_time(); - return absoluteToMSecs(cpu_time - t1); -} - -qint64 QElapsedTimer::msecsSinceReference() const Q_DECL_NOTHROW -{ - return absoluteToMSecs(t1); -} - -qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW -{ - return absoluteToMSecs(other.t1 - t1); -} - -qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW -{ - return msecsTo(other) / 1000; -} - -bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW -{ - return v1.t1 < v2.t1; -} - -QT_END_NAMESPACE diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp deleted file mode 100644 index e2c3ae6280..0000000000 --- a/src/corelib/tools/qelapsedtimer_unix.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qelapsedtimer.h" -#if defined(Q_OS_VXWORKS) -#include "qfunctions_vxworks.h" -#else -#include -#include -#endif -#include - -#include -#include "private/qcore_unix_p.h" - -#if defined(QT_NO_CLOCK_MONOTONIC) || defined(QT_BOOTSTRAPPED) -// turn off the monotonic clock -# ifdef _POSIX_MONOTONIC_CLOCK -# undef _POSIX_MONOTONIC_CLOCK -# endif -# define _POSIX_MONOTONIC_CLOCK -1 -#endif - -QT_BEGIN_NAMESPACE - -/* - * Design: - * - * POSIX offers a facility to select the system's monotonic clock when getting - * the current timestamp. Whereas the functions are mandatory in POSIX.1-2008, - * the presence of a monotonic clock is a POSIX Option (see the document - * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html#tag_02_01_06 ) - * - * The macro _POSIX_MONOTONIC_CLOCK can therefore assume the following values: - * -1 monotonic clock is never supported on this system - * 0 monotonic clock might be supported, runtime check is needed - * >1 (such as 200809L) monotonic clock is always supported - * - * The unixCheckClockType() function will return the clock to use: either - * CLOCK_MONOTONIC or CLOCK_REALTIME. In the case the POSIX option has a value - * of zero, then this function stores a static that contains the clock to be - * used. - * - * There's one extra case, which is when CLOCK_REALTIME isn't defined. When - * that's the case, we'll emulate the clock_gettime function with gettimeofday. - * - * Conforming to: - * POSIX.1b-1993 section "Clocks and Timers" - * included in UNIX98 (Single Unix Specification v2) - * included in POSIX.1-2001 - * see http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html - */ - -#if !defined(CLOCK_REALTIME) -# define CLOCK_REALTIME 0 -static inline void qt_clock_gettime(int, struct timespec *ts) -{ - // support clock_gettime with gettimeofday - struct timeval tv; - gettimeofday(&tv, 0); - ts->tv_sec = tv.tv_sec; - ts->tv_nsec = tv.tv_usec * 1000; -} - -# ifdef _POSIX_MONOTONIC_CLOCK -# undef _POSIX_MONOTONIC_CLOCK -# define _POSIX_MONOTONIC_CLOCK -1 -# endif -#else -static inline void qt_clock_gettime(clockid_t clock, struct timespec *ts) -{ - clock_gettime(clock, ts); -} -#endif - -static int unixCheckClockType() -{ -#ifdef Q_OS_LINUX - // Despite glibc claiming that we should check at runtime, the Linux kernel - // always supports the monotonic clock - return CLOCK_MONOTONIC; -#elif (_POSIX_MONOTONIC_CLOCK-0 == 0) && defined(_SC_MONOTONIC_CLOCK) - // we need a value we can store in a clockid_t that isn't a valid clock - // check if the valid ones are both non-negative or both non-positive -# if CLOCK_MONOTONIC >= 0 && CLOCK_REALTIME >= 0 -# define IS_VALID_CLOCK(clock) (clock >= 0) -# define INVALID_CLOCK -1 -# elif CLOCK_MONOTONIC <= 0 && CLOCK_REALTIME <= 0 -# define IS_VALID_CLOCK(clock) (clock <= 0) -# define INVALID_CLOCK 1 -# else -# error "Sorry, your system has weird values for CLOCK_MONOTONIC and CLOCK_REALTIME" -# endif - - static QBasicAtomicInt clockToUse = Q_BASIC_ATOMIC_INITIALIZER(INVALID_CLOCK); - int clock = clockToUse.loadAcquire(); - if (Q_LIKELY(IS_VALID_CLOCK(clock))) - return clock; - - // detect if the system supports monotonic timers - clock = sysconf(_SC_MONOTONIC_CLOCK) > 0 ? CLOCK_MONOTONIC : CLOCK_REALTIME; - clockToUse.storeRelease(clock); - return clock; - -# undef INVALID_CLOCK -# undef IS_VALID_CLOCK -#elif (_POSIX_MONOTONIC_CLOCK-0) > 0 - return CLOCK_MONOTONIC; -#else - return CLOCK_REALTIME; -#endif -} - -bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW -{ - return clockType() == MonotonicClock; -} - -QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW -{ - return unixCheckClockType() == CLOCK_REALTIME ? SystemTime : MonotonicClock; -} - -static inline void do_gettime(qint64 *sec, qint64 *frac) -{ - timespec ts; - qt_clock_gettime(unixCheckClockType(), &ts); - *sec = ts.tv_sec; - *frac = ts.tv_nsec; -} - -// used in qcore_unix.cpp and qeventdispatcher_unix.cpp -struct timespec qt_gettime() Q_DECL_NOTHROW -{ - qint64 sec, frac; - do_gettime(&sec, &frac); - - timespec tv; - tv.tv_sec = sec; - tv.tv_nsec = frac; - - return tv; -} - -void qt_nanosleep(timespec amount) -{ - // We'd like to use clock_nanosleep. - // - // But clock_nanosleep is from POSIX.1-2001 and both are *not* - // affected by clock changes when using relative sleeps, even for - // CLOCK_REALTIME. - // - // nanosleep is POSIX.1-1993 - - int r; - EINTR_LOOP(r, nanosleep(&amount, &amount)); -} - -static qint64 elapsedAndRestart(qint64 sec, qint64 frac, - qint64 *nowsec, qint64 *nowfrac) -{ - do_gettime(nowsec, nowfrac); - sec = *nowsec - sec; - frac = *nowfrac - frac; - return (sec * Q_INT64_C(1000000000) + frac) / Q_INT64_C(1000000); -} - -void QElapsedTimer::start() Q_DECL_NOTHROW -{ - do_gettime(&t1, &t2); -} - -qint64 QElapsedTimer::restart() Q_DECL_NOTHROW -{ - return elapsedAndRestart(t1, t2, &t1, &t2); -} - -qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW -{ - qint64 sec, frac; - do_gettime(&sec, &frac); - sec = sec - t1; - frac = frac - t2; - return sec * Q_INT64_C(1000000000) + frac; -} - -qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW -{ - return nsecsElapsed() / Q_INT64_C(1000000); -} - -qint64 QElapsedTimer::msecsSinceReference() const Q_DECL_NOTHROW -{ - return t1 * Q_INT64_C(1000) + t2 / Q_INT64_C(1000000); -} - -qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW -{ - qint64 secs = other.t1 - t1; - qint64 fraction = other.t2 - t2; - return (secs * Q_INT64_C(1000000000) + fraction) / Q_INT64_C(1000000); -} - -qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW -{ - return other.t1 - t1; -} - -bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW -{ - return v1.t1 < v2.t1 || (v1.t1 == v2.t1 && v1.t2 < v2.t2); -} - -QT_END_NAMESPACE diff --git a/src/corelib/tools/qelapsedtimer_win.cpp b/src/corelib/tools/qelapsedtimer_win.cpp deleted file mode 100644 index 520126d262..0000000000 --- a/src/corelib/tools/qelapsedtimer_win.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qelapsedtimer.h" -#include - -QT_BEGIN_NAMESPACE - -// Result of QueryPerformanceFrequency, 0 indicates that the high resolution timer is unavailable -static quint64 counterFrequency = 0; - -static void resolveCounterFrequency() -{ - static bool done = false; - if (done) - return; - - // Retrieve the number of high-resolution performance counter ticks per second - LARGE_INTEGER frequency; - if (!QueryPerformanceFrequency(&frequency)) { - qFatal("QueryPerformanceFrequency failed, even though Microsoft documentation promises it wouldn't."); - counterFrequency = 0; - } else { - counterFrequency = frequency.QuadPart; - } - - done = true; -} - -static inline qint64 ticksToNanoseconds(qint64 ticks) -{ - if (counterFrequency > 0) { - // QueryPerformanceCounter uses an arbitrary frequency - qint64 seconds = ticks / counterFrequency; - qint64 nanoSeconds = (ticks - seconds * counterFrequency) * 1000000000 / counterFrequency; - return seconds * 1000000000 + nanoSeconds; - } else { - // GetTickCount(64) return milliseconds - return ticks * 1000000; - } -} - -static quint64 getTickCount() -{ - resolveCounterFrequency(); - - // This avoids a division by zero and disables the high performance counter if it's not available - if (counterFrequency > 0) { - LARGE_INTEGER counter; - - bool ok = QueryPerformanceCounter(&counter); - Q_ASSERT_X(ok, "QElapsedTimer::start()", - "QueryPerformanceCounter failed, although QueryPerformanceFrequency succeeded."); - Q_UNUSED(ok); - return counter.QuadPart; - } - - return GetTickCount64(); -} - -quint64 qt_msectime() -{ - return ticksToNanoseconds(getTickCount()) / 1000000; -} - -QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW -{ - resolveCounterFrequency(); - - if (counterFrequency > 0) - return PerformanceCounter; - else - return TickCounter; -} - -bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW -{ - return true; -} - -void QElapsedTimer::start() Q_DECL_NOTHROW -{ - t1 = getTickCount(); - t2 = 0; -} - -qint64 QElapsedTimer::restart() Q_DECL_NOTHROW -{ - qint64 oldt1 = t1; - t1 = getTickCount(); - t2 = 0; - return ticksToNanoseconds(t1 - oldt1) / 1000000; -} - -qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW -{ - qint64 elapsed = getTickCount() - t1; - return ticksToNanoseconds(elapsed); -} - -qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW -{ - qint64 elapsed = getTickCount() - t1; - return ticksToNanoseconds(elapsed) / 1000000; -} - -qint64 QElapsedTimer::msecsSinceReference() const Q_DECL_NOTHROW -{ - return ticksToNanoseconds(t1) / 1000000; -} - -qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW -{ - qint64 difference = other.t1 - t1; - return ticksToNanoseconds(difference) / 1000000; -} - -qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW -{ - return msecsTo(other) / 1000; -} - -bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW -{ - return (v1.t1 - v2.t1) < 0; -} - -QT_END_NAMESPACE diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 4d77f4e43f..853827e032 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -71,7 +71,6 @@ HEADERS += \ tools/qtimezoneprivate_p.h \ tools/qtimezoneprivate_data_p.h \ tools/qtools_p.h \ - tools/qelapsedtimer.h \ tools/qunicodetables_p.h \ tools/qunicodetools_p.h \ tools/qvarlengtharray.h \ @@ -92,7 +91,6 @@ SOURCES += \ tools/qdatetime.cpp \ tools/qdatetimeparser.cpp \ tools/qeasingcurve.cpp \ - tools/qelapsedtimer.cpp \ tools/qfreelist.cpp \ tools/qhash.cpp \ tools/qline.cpp \ @@ -130,24 +128,23 @@ msvc: NO_PCH_SOURCES += tools/qvector_msvc.cpp false: SOURCES += $$NO_PCH_SOURCES # Hack for QtCreator !nacl:mac: { - SOURCES += tools/qelapsedtimer_mac.cpp OBJECTIVE_SOURCES += tools/qlocale_mac.mm \ tools/qtimezoneprivate_mac.mm \ } else:android { - SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp tools/qtimezoneprivate_android.cpp + SOURCES += tools/qlocale_unix.cpp tools/qtimezoneprivate_android.cpp } else:unix { - SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp tools/qtimezoneprivate_tz.cpp + SOURCES += tools/qlocale_unix.cpp tools/qtimezoneprivate_tz.cpp } else:win32 { - SOURCES += tools/qelapsedtimer_win.cpp \ - tools/qlocale_win.cpp \ + SOURCES += tools/qlocale_win.cpp \ tools/qtimezoneprivate_win.cpp winphone: LIBS_PRIVATE += -lWindowsPhoneGlobalizationUtil winrt-*-msvc2013: LIBS += advapi32.lib -} else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp -else:SOURCES += tools/qelapsedtimer_generic.cpp +} else:integrity { + SOURCES += tools/qlocale_unix.cpp +} contains(QT_CONFIG, system-zlib) { include($$PWD/../../3rdparty/zlib_dependency.pri) -- cgit v1.2.3