src/corelib/tools/qelapsedtimer.cpp
changeset 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtCore module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qelapsedtimer.h"
       
    43 
       
    44 QT_BEGIN_NAMESPACE
       
    45 
       
    46 /*!
       
    47     \class QElapsedTimer
       
    48     \brief The QElapsedTimer class provides a fast way to calculate elapsed times.
       
    49     \since 4.7
       
    50 
       
    51     \reentrant
       
    52     \ingroup tools
       
    53     \inmodule QtCore
       
    54 
       
    55     The QElapsedTimer class is usually used to quickly calculate how much
       
    56     time has elapsed between two events. Its API is similar to that of QTime,
       
    57     so code that was using that can be ported quickly to the new class.
       
    58 
       
    59     However, unlike QTime, QElapsedTimer tries to use monotonic clocks if
       
    60     possible. This means it's not possible to convert QElapsedTimer objects
       
    61     to a human-readable time.
       
    62 
       
    63     The typical use-case for the class is to determine how much time was
       
    64     spent in a slow operation. The simplest example of such a case is for
       
    65     debugging purposes, as in the following example:
       
    66 
       
    67     \snippet doc/src/snippets/qelapsedtimer/main.cpp 0
       
    68 
       
    69     In this example, the timer is started by a call to start() and the
       
    70     elapsed timer is calculated by the elapsed() function.
       
    71 
       
    72     The time elapsed can also be used to recalculate the time available for
       
    73     another operation, after the first one is complete. This is useful when
       
    74     the execution must complete within a certain time period, but several
       
    75     steps are needed. The \tt{waitFor}-type functions in QIODevice and its
       
    76     subclasses are good examples of such need. In that case, the code could
       
    77     be as follows:
       
    78 
       
    79     \snippet doc/src/snippets/qelapsedtimer/main.cpp 1
       
    80 
       
    81     Another use-case is to execute a certain operation for a specific
       
    82     timeslice. For this, QElapsedTimer provides the hasExpired() convenience
       
    83     function, which can be used to determine if a certain number of
       
    84     milliseconds has already elapsed:
       
    85 
       
    86     \snippet doc/src/snippets/qelapsedtimer/main.cpp 1
       
    87 
       
    88     \section1 Reference clocks
       
    89 
       
    90     QElapsedTimer will use the platform's monotonic reference clock in all
       
    91     platforms that support it (see QElapsedTimer::isMonotonic()). This has
       
    92     the added benefit that QElapsedTimer is immune to time adjustments, such
       
    93     as the user correcting the time. Also unlike QTime, QElapsedTimer is
       
    94     immune to changes in the timezone settings, such as daylight savings
       
    95     periods.
       
    96 
       
    97     On the other hand, this means QElapsedTimer values can only be compared
       
    98     with other values that use the same reference. This is especially true if
       
    99     the time since the reference is extracted from the QElapsedTimer object
       
   100     (QElapsedTimer::msecsSinceReference()) and serialised. These values
       
   101     should never be exchanged across the network or saved to disk, since
       
   102     there's no telling whether the computer node receiving the data is the
       
   103     same as the one originating it or if it has rebooted since.
       
   104 
       
   105     It is, however, possible to exchange the value with other processes
       
   106     running on the same machine, provided that they also use the same
       
   107     reference clock. QElapsedTimer will always use the same clock, so it's
       
   108     safe to compare with the value coming from another process in the same
       
   109     machine. If comparing to values produced by other APIs, you should check
       
   110     that the clock used is the same as QElapsedTimer (see
       
   111     QElapsedTimer::clockType()).
       
   112 
       
   113     \section2 32-bit overflows
       
   114 
       
   115     Some of the clocks that QElapsedTimer have a limited range and may
       
   116     overflow after hitting the upper limit (usually 32-bit). QElapsedTimer
       
   117     deals with this overflow issue and presents a consistent timing. However,
       
   118     when extracting the time since reference from QElapsedTimer, two
       
   119     different processes in the same machine may have different understanding
       
   120     of how much time has actually elapsed.
       
   121 
       
   122     The information on which clocks types may overflow and how to remedy that
       
   123     issue is documented along with the clock types.
       
   124 
       
   125     \sa QTime, QTimer
       
   126 */
       
   127 
       
   128 /*!
       
   129     \enum QElapsedTimer::ClockType
       
   130 
       
   131     This enum contains the different clock types that QElapsedTimer may use.
       
   132 
       
   133     QElapsedTimer will always use the same clock type in a particular
       
   134     machine, so this value will not change during the lifetime of a program.
       
   135     It is provided so that QElapsedTimer can be used with other non-Qt
       
   136     implementations, to guarantee that the same reference clock is being
       
   137     used.
       
   138 
       
   139     \value SystemTime       The human-readable system time. This clock is not monotonic.
       
   140     \value MonotonicClock   The system's monotonic clock, usually found in Unix systems. This clock is not monotonic and does not overflow.
       
   141     \value TickCounter      The system's tick counter, used on Windows and Symbian systems. This clock may overflow.
       
   142     \value MachAbsoluteTime The Mach kernel's absolute time (Mac OS X). This clock is monotonic and does not overflow.
       
   143 
       
   144     \section2 SystemTime
       
   145 
       
   146     The system time clock is purely the real time, expressed in milliseconds
       
   147     since Jan 1, 1970 at 0:00 UTC. It's equivalent to the value returned by
       
   148     the C and POSIX \tt{time} function, with the milliseconds added. This
       
   149     clock type is currently only used on Unix systems that do not support
       
   150     monotonic clocks (see below).
       
   151 
       
   152     This is the only non-monotonic clock that QElapsedTimer may use.
       
   153 
       
   154     \section2 MonotonicClock
       
   155 
       
   156     This is the system's monotonic clock, expressed in milliseconds since an
       
   157     arbitrary point in the past. This clock type is used on Unix systems
       
   158     which support POSIX monotonic clocks (\tt{_POSIX_MONOTONIC_CLOCK}).
       
   159 
       
   160     This clock does not overflow.
       
   161 
       
   162     \section2 TickCounter
       
   163 
       
   164     The tick counter clock type is based on the system's or the processor's
       
   165     tick counter, multiplied by the duration of a tick. This clock type is
       
   166     used on Windows and Symbian platforms.
       
   167 
       
   168     The TickCounter clock type is the only clock type that may overflow.
       
   169     Windows Vista and Windows Server 2008 support the extended 64-bit tick
       
   170     counter, which allows avoiding the overflow.
       
   171 
       
   172     On Windows systems, the clock overflows after 2^32 milliseconds, which
       
   173     corresponds to roughly 49.7 days. This means two processes's reckoning of
       
   174     the time since the reference may be different by multiples of 2^32
       
   175     milliseconds. When comparing such values, it's recommended that the high
       
   176     32 bits of the millisecond count be masked off.
       
   177 
       
   178     On Symbian systems, the overflow happens after 2^32 ticks, the duration
       
   179     of which can be obtained from the platform HAL using the constant
       
   180     HAL::ENanoTickPeriod. When comparing values between processes, it's
       
   181     necessary to divide the value by the tick duration and mask off the high
       
   182     32 bits.
       
   183 
       
   184     \section2 MachAbsoluteTime
       
   185 
       
   186     This clock type is based on the absolute time presented by Mach kernels,
       
   187     such as that found on Mac OS X. This clock type is presented separately
       
   188     from MonotonicClock since Mac OS X is also a Unix system and may support
       
   189     a POSIX monotonic clock with values differing from the Mach absolute
       
   190     time.
       
   191 
       
   192     This clock is monotonic and does not overflow.
       
   193 
       
   194     \sa clockType(), isMonotonic()
       
   195 */
       
   196 
       
   197 /*!
       
   198     \fn bool QElapsedTimer::operator ==(const QElapsedTimer &other) const
       
   199 
       
   200     Returns true if this object and \a other contain the same time.
       
   201 */
       
   202 
       
   203 /*!
       
   204     \fn bool QElapsedTimer::operator !=(const QElapsedTimer &other) const
       
   205 
       
   206     Returns true if this object and \a other contain different times.
       
   207 */
       
   208 
       
   209 static const qint64 invalidData = Q_INT64_C(0x8000000000000000);
       
   210 
       
   211 /*!
       
   212     Marks this QElapsedTimer object as invalid.
       
   213 
       
   214     An invalid object can be checked with isValid(). Calculations of timer
       
   215     elapsed since invalid data are undefined and will likely produce bizarre
       
   216     results.
       
   217 
       
   218     \sa isValid(), start(), restart()
       
   219 */
       
   220 void QElapsedTimer::invalidate()
       
   221 {
       
   222      t1 = t2 = invalidData;
       
   223 }
       
   224 
       
   225 /*!
       
   226     Returns true if this object was invalidated by a call to invalidate() and
       
   227     has not been restarted since.
       
   228 
       
   229     \sa invalidate(), start(), restart()
       
   230 */
       
   231 bool QElapsedTimer::isValid() const
       
   232 {
       
   233     return t1 != invalidData && t2 != invalidData;
       
   234 }
       
   235 
       
   236 /*!
       
   237     Returns true if this QElapsedTimer has already expired by \a timeout
       
   238     milliseconds (that is, more than \a timeout milliseconds have elapsed).
       
   239     The value of \a timeout can be -1 to indicate that this timer does not
       
   240     expire, in which case this function will always return false.
       
   241 
       
   242     \sa elapsed()
       
   243 */
       
   244 bool QElapsedTimer::hasExpired(qint64 timeout) const
       
   245 {
       
   246     // if timeout is -1, quint64(timeout) is LLINT_MAX, so this will be
       
   247     // considered as never expired
       
   248     return quint64(elapsed()) > quint64(timeout);
       
   249 }
       
   250 
       
   251 QT_END_NAMESPACE