summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/animation/qabstractanimation.cpp1
-rw-r--r--src/corelib/animation/qabstractanimation_p.h57
-rw-r--r--src/corelib/io/qprocess.cpp6
-rw-r--r--src/corelib/io/qprocess_unix.cpp8
-rw-r--r--src/corelib/kernel/qcore_unix.cpp65
-rw-r--r--src/corelib/kernel/qcore_unix_p.h4
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp4
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp9
-rw-r--r--src/corelib/plugin/qplugin.h2
-rw-r--r--src/corelib/thread/qthread.cpp4
-rw-r--r--src/corelib/thread/qthread_unix.cpp107
-rw-r--r--src/corelib/tools/qdatetime.cpp353
-rw-r--r--src/corelib/tools/qdatetime.h2
-rw-r--r--src/corelib/tools/qelapsedtimer.cpp251
-rw-r--r--src/corelib/tools/qelapsedtimer.h93
-rw-r--r--src/corelib/tools/qelapsedtimer_generic.cpp178
-rw-r--r--src/corelib/tools/qelapsedtimer_mac.cpp126
-rw-r--r--src/corelib/tools/qelapsedtimer_symbian.cpp131
-rw-r--r--src/corelib/tools/qelapsedtimer_unix.cpp179
-rw-r--r--src/corelib/tools/qelapsedtimer_win.cpp135
-rw-r--r--src/corelib/tools/qlocale.cpp214
-rw-r--r--src/corelib/tools/qlocale.h1
-rw-r--r--src/corelib/tools/qlocale_p.h18
-rw-r--r--src/corelib/tools/qtimeline.cpp4
-rw-r--r--src/corelib/tools/tools.pri8
25 files changed, 1617 insertions, 343 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index f834a80..82b3003 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -170,6 +170,7 @@ QUnifiedTimer::QUnifiedTimer() :
currentAnimationIdx(0), consistentTiming(false), slowMode(false),
isPauseTimerActive(false), runningLeafAnimations(0)
{
+ time.invalidate();
}
QUnifiedTimer *QUnifiedTimer::instance()
diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h
index 8bc3224..2282cdb 100644
--- a/src/corelib/animation/qabstractanimation_p.h
+++ b/src/corelib/animation/qabstractanimation_p.h
@@ -56,6 +56,7 @@
#include <QtCore/qbasictimer.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qtimer.h>
+#include <QtCore/qelapsedtimer.h>
#include <private/qobject_p.h>
#ifdef Q_OS_WIN
@@ -113,61 +114,7 @@ private:
Q_DECLARE_PUBLIC(QAbstractAnimation)
};
-class ElapsedTimer
-{
-public:
- ElapsedTimer() {
- invalidate();
- }
-
- void invalidate() {
- m_started = -1;
- }
-
- bool isValid() const {
- return m_started >= 0;
- }
-
- void start() {
- m_started = getTickCount_sys();
- }
-
- qint64 elapsed() const {
- qint64 current = getTickCount_sys();
- qint64 delta = current - m_started;
- if (delta < 0)
- delta += getPeriod_sys(); //we wrapped around
- return delta;
- }
-
-private:
- enum {
- MSECS_PER_HOUR = 3600000,
- MSECS_PER_MIN = 60000
- };
-
- qint64 m_started;
-
- quint64 getPeriod_sys() const {
-#ifdef Q_OS_WIN
- return Q_UINT64_C(0x100000000);
-#else
- // fallback
- return 86400 * 1000;
-#endif
- }
-
- qint64 getTickCount_sys() const {
-#ifdef Q_OS_WIN
- return ::GetTickCount();
-#else
- // fallback
- const QTime t = QTime::currentTime();
- return MSECS_PER_HOUR * t.hour() + MSECS_PER_MIN * t.minute() + 1000 * t.second() + t.msec();
-#endif
- }
-};
-
+typedef QElapsedTimer ElapsedTimer;
class QUnifiedTimer : public QObject
{
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 12a992a..63c2ab8 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -88,7 +88,7 @@ QT_END_NAMESPACE
#include "qprocess_p.h"
#include <qbytearray.h>
-#include <qdatetime.h>
+#include <qelapsedtimer.h>
#include <qcoreapplication.h>
#include <qsocketnotifier.h>
#include <qtimer.h>
@@ -1639,7 +1639,7 @@ bool QProcess::waitForBytesWritten(int msecs)
if (d->processState == QProcess::NotRunning)
return false;
if (d->processState == QProcess::Starting) {
- QTime stopWatch;
+ QElapsedTimer stopWatch;
stopWatch.start();
bool started = waitForStarted(msecs);
if (!started)
@@ -1676,7 +1676,7 @@ bool QProcess::waitForFinished(int msecs)
if (d->processState == QProcess::NotRunning)
return false;
if (d->processState == QProcess::Starting) {
- QTime stopWatch;
+ QElapsedTimer stopWatch;
stopWatch.start();
bool started = waitForStarted(msecs);
if (!started)
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 5119ec0..216c382 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -92,7 +92,6 @@ QT_END_NAMESPACE
#include <private/qcoreapplication_p.h>
#include <private/qthread_p.h>
-#include <qdatetime.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qlist.h>
@@ -101,6 +100,7 @@ QT_END_NAMESPACE
#include <qsemaphore.h>
#include <qsocketnotifier.h>
#include <qthread.h>
+#include <qelapsedtimer.h>
#include <errno.h>
#include <stdlib.h>
@@ -933,7 +933,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
qDebug("QProcessPrivate::waitForReadyRead(%d)", msecs);
#endif
- QTime stopWatch;
+ QElapsedTimer stopWatch;
stopWatch.start();
forever {
@@ -1005,7 +1005,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
qDebug("QProcessPrivate::waitForBytesWritten(%d)", msecs);
#endif
- QTime stopWatch;
+ QElapsedTimer stopWatch;
stopWatch.start();
while (!writeBuffer.isEmpty()) {
@@ -1072,7 +1072,7 @@ bool QProcessPrivate::waitForFinished(int msecs)
qDebug("QProcessPrivate::waitForFinished(%d)", msecs);
#endif
- QTime stopWatch;
+ QElapsedTimer stopWatch;
stopWatch.start();
forever {
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp
index 0fd965b..e0d92c0 100644
--- a/src/corelib/kernel/qcore_unix.cpp
+++ b/src/corelib/kernel/qcore_unix.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qcore_unix_p.h"
+#include "qelapsedtimer.h"
#ifndef Q_OS_VXWORKS
# if !defined(Q_OS_HPUX) || defined(__ia64)
@@ -56,74 +57,12 @@
#include <mach/mach_time.h>
#endif
-#if !defined(QT_NO_CLOCK_MONOTONIC)
-# if defined(QT_BOOTSTRAPPED)
-# define QT_NO_CLOCK_MONOTONIC
-# endif
-#endif
-
QT_BEGIN_NAMESPACE
-bool qt_gettime_is_monotonic()
-{
-#if (_POSIX_MONOTONIC_CLOCK-0 > 0) || defined(Q_OS_MAC)
- return true;
-#else
- static int returnValue = 0;
-
- if (returnValue == 0) {
-# if (_POSIX_MONOTONIC_CLOCK-0 < 0)
- returnValue = -1;
-# elif (_POSIX_MONOTONIC_CLOCK == 0)
- // detect if the system support monotonic timers
- long x = sysconf(_SC_MONOTONIC_CLOCK);
- returnValue = (x >= 200112L) ? 1 : -1;
-# endif
- }
-
- return returnValue != -1;
-#endif
-}
-
-timeval qt_gettime()
-{
- timeval tv;
-#if defined(Q_OS_MAC)
- static mach_timebase_info_data_t info = {0,0};
- if (info.denom == 0)
- mach_timebase_info(&info);
-
- uint64_t cpu_time = mach_absolute_time();
- uint64_t nsecs = cpu_time * (info.numer / info.denom);
- tv.tv_sec = nsecs / 1000000000ull;
- tv.tv_usec = (nsecs / 1000) - (tv.tv_sec * 1000000);
- return tv;
-#elif (_POSIX_MONOTONIC_CLOCK-0 > 0)
- timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- tv.tv_sec = ts.tv_sec;
- tv.tv_usec = ts.tv_nsec / 1000;
- return tv;
-#else
-# if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED)
- if (qt_gettime_is_monotonic()) {
- timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- tv.tv_sec = ts.tv_sec;
- tv.tv_usec = ts.tv_nsec / 1000;
- return tv;
- }
-# endif
- // use gettimeofday
- ::gettimeofday(&tv, 0);
- return tv;
-#endif
-}
-
static inline bool time_update(struct timeval *tv, const struct timeval &start,
const struct timeval &timeout)
{
- if (!qt_gettime_is_monotonic()) {
+ if (!QElapsedTimer::isMonotonic()) {
// we cannot recalculate the timeout without a monotonic clock as the time may have changed
return false;
}
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index 297b25d..439ca5a 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -314,8 +314,8 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options)
# define _POSIX_MONOTONIC_CLOCK -1
#endif
-bool qt_gettime_is_monotonic();
-timeval qt_gettime();
+timeval qt_gettime(); // in qelapsedtimer_mac.cpp or qtimestamp_unix.cpp
+
Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
const struct timeval *tv);
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 2da5a7d..8fc3fb8 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -47,7 +47,6 @@
#include "qeventloop.h"
#include "qcorecmdlineargs_p.h"
#include <qdatastream.h>
-#include <qdatetime.h>
#include <qdebug.h>
#include <qdir.h>
#include <qfile.h>
@@ -59,6 +58,7 @@
#include <qthreadpool.h>
#include <qthreadstorage.h>
#include <private/qthread_p.h>
+#include <qelapsedtimer.h>
#include <qlibraryinfo.h>
#include <qvarlengtharray.h>
#include <private/qfactoryloader_p.h>
@@ -917,7 +917,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int m
QThreadData *data = QThreadData::current();
if (!data->eventDispatcher)
return;
- QTime start;
+ QElapsedTimer start;
start.start();
if (flags & QEventLoop::DeferredDeletion)
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index a141887..f7d45ac 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -45,6 +45,7 @@
#include "qpair.h"
#include "qsocketnotifier.h"
#include "qthread.h"
+#include "qelapsedtimer.h"
#include "qeventdispatcher_unix_p.h"
#include <private/qthread_p.h>
@@ -311,12 +312,10 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags,
QTimerInfoList::QTimerInfoList()
{
- currentTime = qt_gettime();
-
#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)
- if (!qt_gettime_is_monotonic()) {
+ if (!QElapsedTimer::isMonotonic()) {
// not using monotonic timers, initialize the timeChanged() machinery
- previousTime = currentTime;
+ previousTime = qt_gettime();
tms unused;
previousTicks = times(&unused);
@@ -393,7 +392,7 @@ bool QTimerInfoList::timeChanged(timeval *delta)
void QTimerInfoList::repairTimersIfNeeded()
{
- if (qt_gettime_is_monotonic())
+ if (QElapsedTimer::isMonotonic())
return;
timeval delta;
if (timeChanged(&delta))
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index b798437..7f541f1 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -110,7 +110,7 @@ void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunctio
# define QPLUGIN_DEBUG_STR "true"
# endif
# define Q_PLUGIN_VERIFICATION_DATA \
- static const char *qt_plugin_verification_data = \
+ static const char qt_plugin_verification_data[] = \
"pattern=""QT_PLUGIN_VERIFICATION_DATA""\n" \
"version="QT_VERSION_STR"\n" \
"debug="QPLUGIN_DEBUG_STR"\n" \
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index dd0c257..cb84538 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -617,7 +617,9 @@ QThread::Priority QThread::priority() const
{
Q_D(const QThread);
QMutexLocker locker(&d->mutex);
- return d->priority;
+
+ // mask off the high bits that are used for flags
+ return Priority(d->priority & 0xffff);
}
/*!
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index cda35a4..5a50646 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -92,10 +92,17 @@
# endif
#endif
+#if defined(Q_OS_LINUX) && !defined(SCHED_IDLE)
+// from linux/sched.h
+# define SCHED_IDLE 5
+#endif
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_THREAD
+enum { ThreadPriorityResetFlag = 0x80000000 };
+
static pthread_once_t current_thread_data_once = PTHREAD_ONCE_INIT;
static pthread_key_t current_thread_data_key;
@@ -221,6 +228,11 @@ void *QThreadPrivate::start(void *arg)
QThread *thr = reinterpret_cast<QThread *>(arg);
QThreadData *data = QThreadData::get2(thr);
+ // do we need to reset the thread priority?
+ if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) {
+ thr->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
+ }
+
#ifdef Q_OS_SYMBIAN
// Because Symbian Open C does not provide a way to convert between
// RThread and pthread_t, we must delay initialization of the RThread
@@ -436,6 +448,37 @@ void QThread::usleep(unsigned long usecs)
thread_sleep(&ti);
}
+// Does some magic and calculate the Unix scheduler priorities
+// sched_policy is IN/OUT: it must be set to a valid policy before calling this function
+// sched_priority is OUT only
+static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_priority)
+{
+#ifdef SCHED_IDLE
+ if (priority == QThread::IdlePriority) {
+ *sched_policy = SCHED_IDLE;
+ *sched_priority = 0;
+ return true;
+ }
+ const int lowestPriority = QThread::LowestPriority;
+#else
+ const int lowestPriority = QThread::IdlePriority;
+#endif
+ const int highestPriority = QThread::TimeCriticalPriority;
+
+ int prio_min = sched_get_priority_min(*sched_policy);
+ int prio_max = sched_get_priority_max(*sched_policy);
+ if (prio_min == -1 || prio_max == -1)
+ return false;
+
+ int prio;
+ // crudely scale our priority enum values to the prio_min/prio_max
+ prio = ((priority - lowestPriority) * (prio_max - prio_min) / highestPriority) + prio_min;
+ prio = qMax(prio_min, qMin(prio_max, prio));
+
+ *sched_priority = prio;
+ return true;
+}
+
void QThread::start(Priority priority)
{
Q_D(QThread);
@@ -472,32 +515,14 @@ void QThread::start(Priority priority)
break;
}
- int prio_min = sched_get_priority_min(sched_policy);
- int prio_max = sched_get_priority_max(sched_policy);
- if (prio_min == -1 || prio_max == -1) {
+ int prio;
+ if (!calculateUnixPriority(priority, &sched_policy, &prio)) {
// failed to get the scheduling parameters, don't
// bother setting the priority
qWarning("QThread::start: Cannot determine scheduler priority range");
break;
}
- int prio;
- switch (priority) {
- case IdlePriority:
- prio = prio_min;
- break;
-
- case TimeCriticalPriority:
- prio = prio_max;
- break;
-
- default:
- // crudely scale our priority enum values to the prio_min/prio_max
- prio = (priority * (prio_max - prio_min) / TimeCriticalPriority) + prio_min;
- prio = qMax(prio_min, qMin(prio_max, prio));
- break;
- }
-
sched_param sp;
sp.sched_priority = prio;
@@ -505,7 +530,9 @@ void QThread::start(Priority priority)
|| pthread_attr_setschedpolicy(&attr, sched_policy) != 0
|| pthread_attr_setschedparam(&attr, &sp) != 0) {
// could not set scheduling hints, fallback to inheriting them
+ // we'll try again from inside the thread
pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+ d->priority = Priority(priority | ThreadPriorityResetFlag);
}
break;
}
@@ -672,38 +699,28 @@ void QThread::setPriority(Priority priority)
return;
}
- int prio_min = sched_get_priority_min(sched_policy);
- int prio_max = sched_get_priority_max(sched_policy);
- if (prio_min == -1 || prio_max == -1) {
+ int prio;
+ if (!calculateUnixPriority(priority, &sched_policy, &prio)) {
// failed to get the scheduling parameters, don't
// bother setting the priority
qWarning("QThread::setPriority: Cannot determine scheduler priority range");
return;
}
- int prio;
- switch (priority) {
- case InheritPriority:
- qWarning("QThread::setPriority: Argument cannot be InheritPriority");
- return;
-
- case IdlePriority:
- prio = prio_min;
- break;
-
- case TimeCriticalPriority:
- prio = prio_max;
- break;
-
- default:
- // crudely scale our priority enum values to the prio_min/prio_max
- prio = (priority * (prio_max - prio_min) / TimeCriticalPriority) + prio_min;
- prio = qMax(prio_min, qMin(prio_max, prio));
- break;
- }
-
param.sched_priority = prio;
- pthread_setschedparam(d->thread_id, sched_policy, &param);
+ int status = pthread_setschedparam(d->thread_id, sched_policy, &param);
+
+# ifdef SCHED_IDLE
+ // were we trying to set to idle priority and failed?
+ if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) {
+ // reset to lowest priority possible
+ pthread_getschedparam(d->thread_id, &sched_policy, &param);
+ param.sched_priority = sched_get_priority_min(sched_policy);
+ pthread_setschedparam(d->thread_id, sched_policy, &param);
+ }
+# else
+ Q_UNUSED(status);
+# endif // SCHED_IDLE
#endif
}
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index c1027ed..54a4205 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -98,18 +98,23 @@ static inline QDate fixedDate(int y, int m, int d)
return result;
}
+static inline uint julianDayFromGregorianDate(int year, int month, int day)
+{
+ // Gregorian calendar starting from October 15, 1582
+ // Algorithm from Henry F. Fliegel and Thomas C. Van Flandern
+ return (1461 * (year + 4800 + (month - 14) / 12)) / 4
+ + (367 * (month - 2 - 12 * ((month - 14) / 12))) / 12
+ - (3 * ((year + 4900 + (month - 14) / 12) / 100)) / 4
+ + day - 32075;
+}
+
static uint julianDayFromDate(int year, int month, int day)
{
if (year < 0)
++year;
if (year > 1582 || (year == 1582 && (month > 10 || (month == 10 && day >= 15)))) {
- // Gregorian calendar starting from October 15, 1582
- // Algorithm from Henry F. Fliegel and Thomas C. Van Flandern
- return (1461 * (year + 4800 + (month - 14) / 12)) / 4
- + (367 * (month - 2 - 12 * ((month - 14) / 12))) / 12
- - (3 * ((year + 4900 + (month - 14) / 12) / 100)) / 4
- + day - 32075;
+ return julianDayFromGregorianDate(year, month, day);
} else if (year < 1582 || (year == 1582 && (month < 10 || (month == 10 && day <= 4)))) {
// Julian calendar until October 4, 1582
// Algorithm from Frequently Asked Questions about Calendars by Claus Toendering
@@ -1118,46 +1123,12 @@ int QDate::daysTo(const QDate &d) const
*/
/*!
- \overload
+ \fn QDate::currentDate()
Returns the current date, as reported by the system clock.
\sa QTime::currentTime(), QDateTime::currentDateTime()
*/
-QDate QDate::currentDate()
-{
- QDate d;
-#if defined(Q_OS_WIN)
- SYSTEMTIME st;
- memset(&st, 0, sizeof(SYSTEMTIME));
- GetLocalTime(&st);
- d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
-#elif defined(Q_OS_SYMBIAN)
- TTime localTime;
- localTime.HomeTime();
- TDateTime localDateTime = localTime.DateTime();
- // months and days are zero indexed
- d.jd = julianDayFromDate(localDateTime.Year(), localDateTime.Month() + 1, localDateTime.Day() + 1 );
-#else
- // posix compliant system
- time_t ltime;
- time(&ltime);
- tm *t = 0;
-
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
- // use the reentrant version of localtime() where available
- tzset();
- tm res;
- t = localtime_r(&ltime, &res);
-#else
- t = localtime(&ltime);
-#endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
-
- d.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
-#endif
- return d;
-}
-
#ifndef QT_NO_DATESTRING
/*!
\fn QDate QDate::fromString(const QString &string, Qt::DateFormat format)
@@ -1812,7 +1783,7 @@ int QTime::msecsTo(const QTime &t) const
*/
/*!
- \overload
+ \fn QTime::currentTime()
Returns the current time as reported by the system clock.
@@ -1820,53 +1791,6 @@ int QTime::msecsTo(const QTime &t) const
operating system; not all systems provide 1-millisecond accuracy.
*/
-QTime QTime::currentTime()
-{
- QTime ct;
-
-#if defined(Q_OS_WIN)
- SYSTEMTIME st;
- memset(&st, 0, sizeof(SYSTEMTIME));
- GetLocalTime(&st);
- ct.mds = MSECS_PER_HOUR * st.wHour + MSECS_PER_MIN * st.wMinute + 1000 * st.wSecond
- + st.wMilliseconds;
-#if defined(Q_OS_WINCE)
- ct.startTick = GetTickCount() % MSECS_PER_DAY;
-#endif
-#elif defined(Q_OS_SYMBIAN)
- TTime localTime;
- localTime.HomeTime();
- TDateTime localDateTime = localTime.DateTime();
- ct.mds = MSECS_PER_HOUR * localDateTime.Hour() + MSECS_PER_MIN * localDateTime.Minute()
- + 1000 * localDateTime.Second() + (localDateTime.MicroSecond() / 1000);
-#elif defined(Q_OS_UNIX)
- // posix compliant system
- struct timeval tv;
- gettimeofday(&tv, 0);
- time_t ltime = tv.tv_sec;
- tm *t = 0;
-
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
- // use the reentrant version of localtime() where available
- tzset();
- tm res;
- t = localtime_r(&ltime, &res);
-#else
- t = localtime(&ltime);
-#endif
- Q_CHECK_PTR(t);
-
- ct.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec
- + tv.tv_usec / 1000;
-#else
- time_t ltime; // no millisecond resolution
- ::time(&ltime);
- const tm *const t = localtime(&ltime);
- ct.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec;
-#endif
- return ct;
-}
-
#ifndef QT_NO_DATESTRING
/*!
\fn QTime QTime::fromString(const QString &string, Qt::DateFormat format)
@@ -2872,63 +2796,280 @@ bool QDateTime::operator<(const QDateTime &other) const
*/
/*!
+ \fn QDateTime QDateTime::currentDateTime()
Returns the current datetime, as reported by the system clock, in
the local time zone.
- \sa QDate::currentDate(), QTime::currentTime(), toTimeSpec()
+ \sa currentDateTimeUtc(), QDate::currentDate(), QTime::currentTime(), toTimeSpec()
*/
-QDateTime QDateTime::currentDateTime()
+/*!
+ \fn QDateTime QDateTime::currentDateTimeUtc()
+ \since 4.7
+ Returns the current datetime, as reported by the system clock, in
+ UTC.
+
+ \sa currentDateTime(), QDate::currentDate(), QTime::currentTime(), toTimeSpec()
+*/
+
+/*!
+ \fn qint64 QDateTime::currentMsecsSinceEpoch()
+ \since 4.7
+
+ Returns the number of milliseconds since 1970-01-01T00:00:00 Universal
+ Coordinated Time. This number is like the POSIX time_t variable, but
+ expressed in milliseconds instead.
+
+ \sa currentDateTime(), currentDateTimeUtc(), toTime_t(), toTimeSpec()
+*/
+
+static inline uint msecsFromDecomposed(int hour, int minute, int sec, int msec = 0)
{
+ return MSECS_PER_HOUR * hour + MSECS_PER_MIN * minute + 1000 * sec + msec;
+}
+
#if defined(Q_OS_WIN)
+QDate QDate::currentDate()
+{
+ QDate d;
+ SYSTEMTIME st;
+ memset(&st, 0, sizeof(SYSTEMTIME));
+ GetLocalTime(&st);
+ d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
+ return d;
+}
+
+QTime QTime::currentTime()
+{
+ QTime ct;
+ SYSTEMTIME st;
+ memset(&st, 0, sizeof(SYSTEMTIME));
+ GetLocalTime(&st);
+ ct.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
+#if defined(Q_OS_WINCE)
+ ct.startTick = GetTickCount() % MSECS_PER_DAY;
+#endif
+ return ct;
+}
+
+QDateTime QDateTime::currentDateTime()
+{
QDate d;
QTime t;
SYSTEMTIME st;
memset(&st, 0, sizeof(SYSTEMTIME));
GetLocalTime(&st);
d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
- t.mds = MSECS_PER_HOUR * st.wHour + MSECS_PER_MIN * st.wMinute + 1000 * st.wSecond
- + st.wMilliseconds;
+ t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
return QDateTime(d, t);
+}
+
+QDateTime QDateTime::currentDateTimeUtc()
+{
+ QDate d;
+ QTime t;
+ SYSTEMTIME st;
+ memset(&st, 0, sizeof(SYSTEMTIME));
+ GetSystemTime(&st);
+ d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
+ t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
+ return QDateTime(d, t, Qt::UTC);
+}
+
+qint64 QDateTime::currentMsecsSinceEpoch()
+{
+ QDate d;
+ QTime t;
+ SYSTEMTIME st;
+ memset(&st, 0, sizeof(SYSTEMTIME));
+ GetSystemTime(&st);
+
+ return msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds) +
+ qint64(julianDayFromGregorianDate(st.wYear, st.wMonth, st.wDay)
+ - julianDayFromGregorianDate(1970, 1, 1)) * Q_INT64_C(86400000);
+}
+
#elif defined(Q_OS_SYMBIAN)
- return QDateTime(QDate::currentDate(), QTime::currentTime());
+QDate QDate::currentDate()
+{
+ QDate d;
+ TTime localTime;
+ localTime.HomeTime();
+ TDateTime localDateTime = localTime.DateTime();
+ // months and days are zero indexed
+ d.jd = julianDayFromDate(localDateTime.Year(), localDateTime.Month() + 1, localDateTime.Day() + 1 );
+ return d;
+}
+
+QTime QTime::currentTime()
+{
+ QTime ct;
+ TTime localTime;
+ localTime.HomeTime();
+ TDateTime localDateTime = localTime.DateTime();
+ ct.mds = msecsFromDecomposed(localDateTime.Hour(), localDateTime.Minute(),
+ localDateTime.Second(), localDateTime.MicroSecond() / 1000);
+ return ct;
+}
+
+QDateTime QDateTime::currentDateTime()
+{
+ QDate d;
+ QTime ct;
+ TTime localTime;
+ localTime.HomeTime();
+ TDateTime localDateTime = localTime.DateTime();
+ // months and days are zero indexed
+ d.jd = julianDayFromDate(localDateTime.Year(), localDateTime.Month() + 1, localDateTime.Day() + 1);
+ ct.mds = msecsFromDecomposed(localDateTime.Hour(), localDateTime.Minute(),
+ localDateTime.Second(), localDateTime.MicroSecond() / 1000);
+ return QDateTime(d, ct);
+}
+
+QDateTime QDateTime::currentDateTimeUtc()
+{
+ QDate d;
+ QTime ct;
+ TTime gmTime;
+ gmTime.UniversalTime();
+ TDateTime gmtDateTime = gmTime.DateTime();
+ // months and days are zero indexed
+ d.jd = julianDayFromDate(gmtDateTime.Year(), gmtDateTime.Month() + 1, gmtDateTime.Day() + 1);
+ ct.mds = msecsFromDecomposed(gmtDateTime.Hour(), gmtDateTime.Minute(),
+ gmtDateTime.Second(), gmtDateTime.MicroSecond() / 1000);
+ return QDateTime(d, ct, Qt::UTC);
+}
+
+qint64 QDateTime::currentMsecsSinceEpoch()
+{
+ QDate d;
+ QTime ct;
+ TTime gmTime;
+ gmTime.UniversalTime();
+ TDateTime gmtDateTime = gmTime.DateTime();
+
+ // according to the documentation, the value is:
+ // "a date and time as a number of microseconds since midnight, January 1st, 0 AD nominal Gregorian"
+ qint64 value = gmTime.Int64();
+
+ // whereas 1970-01-01T00:00:00 is (in the same representation):
+ // ((1970 * 365) + (1970 / 4) - (1970 / 100) + (1970 / 400) - 13) * 86400 * 1000000
+ static const qint64 unixEpoch = Q_INT64_C(0xdcddb30f2f8000);
+
+ return (value - unixEpoch) / 1000;
+}
+
+#elif defined(Q_OS_UNIX)
+QDate QDate::currentDate()
+{
+ QDate d;
+ // posix compliant system
+ time_t ltime;
+ time(&ltime);
+ struct tm *t = 0;
+
+#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant version of localtime() where available
+ tzset();
+ struct tm res;
+ t = localtime_r(&ltime, &res);
#else
-#if defined(Q_OS_UNIX)
+ t = localtime(&ltime);
+#endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
+
+ d.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
+ return d;
+}
+
+QTime QTime::currentTime()
+{
+ QTime ct;
+ // posix compliant system
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ time_t ltime = tv.tv_sec;
+ struct tm *t = 0;
+
+#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant version of localtime() where available
+ tzset();
+ struct tm res;
+ t = localtime_r(&ltime, &res);
+#else
+ t = localtime(&ltime);
+#endif
+ Q_CHECK_PTR(t);
+
+ ct.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
+ return ct;
+}
+
+QDateTime QDateTime::currentDateTime()
+{
// posix compliant system
// we have milliseconds
struct timeval tv;
gettimeofday(&tv, 0);
time_t ltime = tv.tv_sec;
- tm *t = 0;
+ struct tm *t = 0;
#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
// use the reentrant version of localtime() where available
tzset();
- tm res;
+ struct tm res;
t = localtime_r(&ltime, &res);
#else
t = localtime(&ltime);
#endif
QDateTime dt;
- dt.d->time.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec
- + tv.tv_usec / 1000;
-#else
- time_t ltime; // no millisecond resolution
- ::time(&ltime);
- tm *t = 0;
- localtime(&ltime);
- dt.d->time.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec;
-#endif // Q_OS_UNIX
+ dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
dt.d->spec = t->tm_isdst > 0 ? QDateTimePrivate::LocalDST :
t->tm_isdst == 0 ? QDateTimePrivate::LocalStandard :
QDateTimePrivate::LocalUnknown;
return dt;
+}
+
+QDateTime QDateTime::currentDateTimeUtc()
+{
+ // posix compliant system
+ // we have milliseconds
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ time_t ltime = tv.tv_sec;
+ struct tm *t = 0;
+
+#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant version of localtime() where available
+ struct tm res;
+ t = gmtime_r(&ltime, &res);
+#else
+ t = gmtime(&ltime);
#endif
+
+ QDateTime dt;
+ dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
+
+ dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
+ dt.d->spec = QDateTimePrivate::UTC;
+ return dt;
}
+qint64 QDateTime::currentMsecsSinceEpoch()
+{
+ // posix compliant system
+ // we have milliseconds
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ return qint64(tv.tv_sec) * Q_INT64_C(1000) + tv.tv_usec / 1000;
+}
+
+#else
+#error "What system is this?"
+#endif
+
/*!
\since 4.2
diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h
index 6fdc855..ef5968e 100644
--- a/src/corelib/tools/qdatetime.h
+++ b/src/corelib/tools/qdatetime.h
@@ -261,11 +261,13 @@ public:
int utcOffset() const;
static QDateTime currentDateTime();
+ static QDateTime currentDateTimeUtc();
#ifndef QT_NO_DATESTRING
static QDateTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
static QDateTime fromString(const QString &s, const QString &format);
#endif
static QDateTime fromTime_t(uint secsSince1Jan1970UTC);
+ static qint64 currentMsecsSinceEpoch();
#ifdef QT3_SUPPORT
inline QT3_SUPPORT void setTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec) {
diff --git a/src/corelib/tools/qelapsedtimer.cpp b/src/corelib/tools/qelapsedtimer.cpp
new file mode 100644
index 0000000..28dfc23
--- /dev/null
+++ b/src/corelib/tools/qelapsedtimer.cpp
@@ -0,0 +1,251 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qelapsedtimer.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QElapsedTimer
+ \brief The QElapsedTimer class provides a fast way to calculate elapsed times.
+ \since 4.7
+
+ \reentrant
+ \ingroup tools
+ \inmodule QtCore
+
+ 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 doc/src/snippets/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 doc/src/snippets/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 doc/src/snippets/qelapsedtimer/main.cpp 1
+
+ \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 savings
+ 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 that 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 not monotonic and does not overflow.
+ \value TickCounter The system's tick counter, used on Windows and Symbian systems. This clock may overflow.
+ \value MachAbsoluteTime The Mach kernel's absolute time (Mac OS X). This clock is monotonic and does not overflow.
+
+ \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 and Symbian platforms.
+
+ 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's 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.
+
+ On Symbian systems, the overflow happens after 2^32 ticks, the duration
+ of which can be obtained from the platform HAL using the constant
+ HAL::ENanoTickPeriod. When comparing values between processes, it's
+ necessary to divide the value by the tick duration and mask off the high
+ 32 bits.
+
+ \section2 MachAbsoluteTime
+
+ This clock type is based on the absolute time presented by Mach kernels,
+ such as that found on Mac OS X. This clock type is presented separately
+ from MonotonicClock since Mac OS X is also a Unix system and may support
+ a POSIX monotonic clock with values differing from the Mach absolute
+ time.
+
+ This clock is monotonic and does not overflow.
+
+ \sa clockType(), isMonotonic()
+*/
+
+/*!
+ \fn bool QElapsedTimer::operator ==(const QElapsedTimer &other) const
+
+ Returns true if this object and \a other contain the same time.
+*/
+
+/*!
+ \fn bool QElapsedTimer::operator !=(const QElapsedTimer &other) const
+
+ Returns 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()
+{
+ t1 = t2 = invalidData;
+}
+
+/*!
+ Returns true if this object was invalidated by a call to invalidate() and
+ has not been restarted since.
+
+ \sa invalidate(), start(), restart()
+*/
+bool QElapsedTimer::isValid() const
+{
+ return t1 != invalidData && t2 != invalidData;
+}
+
+/*!
+ Returns 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
+{
+ // 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
new file mode 100644
index 0000000..0d6f0be
--- /dev/null
+++ b/src/corelib/tools/qelapsedtimer.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTIMESTAMP_H
+#define QTIMESTAMP_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class Q_CORE_EXPORT QElapsedTimer
+{
+public:
+ enum ClockType {
+ SystemTime,
+ MonotonicClock,
+ TickCounter,
+ MachAbsoluteTime
+ };
+ static ClockType clockType();
+ static bool isMonotonic();
+
+ void start();
+ qint64 restart();
+ void invalidate();
+ bool isValid() const;
+
+ qint64 elapsed() const;
+ bool hasExpired(qint64 timeout) const;
+
+ qint64 msecsSinceReference() const;
+ qint64 msecsTo(const QElapsedTimer &other) const;
+ qint64 secsTo(const QElapsedTimer &other) const;
+
+ bool operator==(const QElapsedTimer &other) const
+ { return t1 == other.t1 && t2 == other.t2; }
+ bool operator!=(const QElapsedTimer &other) const
+ { return !(*this == other); }
+
+ friend bool Q_CORE_EXPORT operator<(const QElapsedTimer &v1, const QElapsedTimer &v2);
+
+private:
+ qint64 t1;
+ qint64 t2;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTIMESTAMP_H
diff --git a/src/corelib/tools/qelapsedtimer_generic.cpp b/src/corelib/tools/qelapsedtimer_generic.cpp
new file mode 100644
index 0000000..9b589c1
--- /dev/null
+++ b/src/corelib/tools/qelapsedtimer_generic.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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()
+{
+ return SystemTime;
+}
+
+/*!
+ Returns 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()
+{
+ 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 doc/src/snippets/qelapsedtimer/main.cpp 0
+
+ Also, starting a timer makes it valid again.
+
+ \sa restart(), invalidate(), elapsed()
+*/
+void QElapsedTimer::start()
+{
+ 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 restart(), but it does so in one
+ single operation, avoiding the need to obtain the clock value twice.
+
+ 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 doc/src/snippets/qelapsedtimer/main.cpp 3
+
+ \sa start(), invalidate(), elapsed()
+*/
+qint64 QElapsedTimer::restart()
+{
+ qint64 old = t1;
+ t1 = QDateTime::currentMsecsSinceEpoch();
+ t2 = 0;
+ return t1 - old;
+}
+
+/*!
+ Returns the number of milliseconds since this QElapsedTimer was last
+ started. Calling this function in a QElapsedTimer that was invalidated
+ will result in undefined results.
+
+ \sa start(), restart(), hasExpired(), invalidate()
+*/
+qint64 QElapsedTimer::elapsed() const
+{
+ 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).
+
+ \sa clockType(), elapsed()
+*/
+qint64 QElapsedTimer::msecsSinceReference() const
+{
+ 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 positive. If it was started later, the returned value will be
+ negative.
+
+ The return value is undefined if this object or \a other were invalidated.
+
+ \sa secsTo(), elapsed()
+*/
+qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const
+{
+ 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
+ positive. If it was started later, the returned value will be negative.
+
+ The return value is undefined if this object or \a other were invalidated.
+
+ \sa msecsTo(), elapsed()
+*/
+qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const
+{
+ return msecsTo(other) / 1000;
+}
+
+/*!
+ \relates QElapsedTimer
+
+ Returns 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)
+{
+ return v1.t1 < v2.t1;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qelapsedtimer_mac.cpp b/src/corelib/tools/qelapsedtimer_mac.cpp
new file mode 100644
index 0000000..8fceb49
--- /dev/null
+++ b/src/corelib/tools/qelapsedtimer_mac.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qelapsedtimer.h"
+#include <sys/time.h>
+#include <unistd.h>
+
+#include <mach/mach_time.h>
+
+QT_BEGIN_NAMESPACE
+
+QElapsedTimer::ClockType QElapsedTimer::clockType()
+{
+ return MachAbsoluteTime;
+}
+
+bool QElapsedTimer::isMonotonic()
+{
+ return true;
+}
+
+static mach_timebase_info_data_t info = {0,0};
+static qint64 absoluteToNSecs(qint64 cpuTime)
+{
+ if (info.denom == 0)
+ mach_timebase_info(&info);
+ qint64 nsecs = cpuTime * info.numer / info.denom;
+ return nsecs;
+}
+
+static qint64 absoluteToMSecs(qint64 cpuTime)
+{
+ return absoluteToNSecs(cpuTime) / 1000000;
+}
+
+timeval qt_gettime()
+{
+ timeval tv;
+
+ uint64_t cpu_time = mach_absolute_time();
+ uint64_t nsecs = absoluteToNSecs(cpu_time);
+ tv.tv_sec = nsecs / 1000000000ull;
+ tv.tv_usec = (nsecs / 1000) - (tv.tv_sec * 1000000);
+ return tv;
+}
+
+void QElapsedTimer::start()
+{
+ t1 = mach_absolute_time();
+ t2 = 0;
+}
+
+qint64 QElapsedTimer::restart()
+{
+ qint64 old = t1;
+ t1 = mach_absolute_time();
+ t2 = 0;
+
+ return absoluteToMSecs(t1 - old);
+}
+
+qint64 QElapsedTimer::elapsed() const
+{
+ uint64_t cpu_time = mach_absolute_time();
+ return absoluteToMSecs(cpu_time - t1);
+}
+
+qint64 QElapsedTimer::msecsSinceReference() const
+{
+ return absoluteToMSecs(t1);
+}
+
+qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const
+{
+ return absoluteToMSecs(other.t1 - t1);
+}
+
+qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const
+{
+ return msecsTo(other) / 1000;
+}
+
+bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2)
+{
+ return v1.t1 < v2.t1;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qelapsedtimer_symbian.cpp b/src/corelib/tools/qelapsedtimer_symbian.cpp
new file mode 100644
index 0000000..038b102
--- /dev/null
+++ b/src/corelib/tools/qelapsedtimer_symbian.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qelapsedtimer.h"
+#include "qpair.h"
+#include <e32std.h>
+#include <sys/time.h>
+#include <hal.h>
+
+QT_BEGIN_NAMESPACE
+
+// return quint64 to avoid sign-extension
+static quint64 getMicrosecondFromTick()
+{
+ static TInt nanokernel_tick_period;
+ if (!nanokernel_tick_period)
+ HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
+
+ static quint32 highdword = 0;
+ static quint32 lastval = 0;
+ quint32 val = User::NTickCount();
+ if (val < lastval)
+ ++highdword;
+ lastval = val;
+
+ return nanokernel_tick_period * (val | (quint64(highdword) << 32));
+}
+
+static quint64 getMillisecondFromTick()
+{
+ return getMicrosecondFromTick() / 1000;
+}
+
+timeval qt_gettime()
+{
+ timeval tv;
+ quint64 now = getMicrosecondFromTick();
+ tv.tv_sec = now / 1000000;
+ tv.tv_usec = now % 1000000;
+
+ return tv;
+}
+
+QElapsedTimer::ClockType QElapsedTimer::clockType()
+{
+ return TickCounter;
+}
+
+bool QElapsedTimer::isMonotonic()
+{
+ return true;
+}
+
+void QElapsedTimer::start()
+{
+ t1 = getMillisecondFromTick();
+ t2 = 0;
+}
+
+qint64 QElapsedTimer::restart()
+{
+ qint64 oldt1 = t1;
+ t1 = getMillisecondFromTick();
+ t2 = 0;
+ return t1 - oldt1;
+}
+
+qint64 QElapsedTimer::elapsed() const
+{
+ return getMillisecondFromTick() - t1;
+}
+
+qint64 QElapsedTimer::msecsSinceReference() const
+{
+ return t1;
+}
+
+qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const
+{
+ return other.t1 - t1;
+}
+
+qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const
+{
+ return msecsTo(other) / 1000;
+}
+
+bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2)
+{
+ return (v1.t1 - v2.t1) < 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp
new file mode 100644
index 0000000..85d7fa8
--- /dev/null
+++ b/src/corelib/tools/qelapsedtimer_unix.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qelapsedtimer.h"
+#include "qpair.h"
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+
+#if !defined(QT_NO_CLOCK_MONOTONIC)
+# if defined(QT_BOOTSTRAPPED)
+# define QT_NO_CLOCK_MONOTONIC
+# endif
+#endif
+
+QT_BEGIN_NAMESPACE
+
+static qint64 fractionAdjustment()
+{
+ if (QElapsedTimer::isMonotonic()) {
+ // the monotonic timer is measured in nanoseconds
+ // 1 ms = 1000000 ns
+ return 1000*1000ull;
+ } else {
+ // gettimeofday is measured in microseconds
+ // 1 ms = 1000 us
+ return 1000;
+ }
+}
+
+bool QElapsedTimer::isMonotonic()
+{
+#if (_POSIX_MONOTONIC_CLOCK-0 > 0)
+ return true;
+#else
+ static int returnValue = 0;
+
+ if (returnValue == 0) {
+# if (_POSIX_MONOTONIC_CLOCK-0 < 0)
+ returnValue = -1;
+# elif (_POSIX_MONOTONIC_CLOCK == 0)
+ // detect if the system support monotonic timers
+ long x = sysconf(_SC_MONOTONIC_CLOCK);
+ returnValue = (x >= 200112L) ? 1 : -1;
+# endif
+ }
+
+ return returnValue != -1;
+#endif
+}
+
+QElapsedTimer::ClockType QElapsedTimer::clockType()
+{
+ return isMonotonic() ? MonotonicClock : SystemTime;
+}
+
+static inline QPair<long, long> do_gettime()
+{
+#if (_POSIX_MONOTONIC_CLOCK-0 > 0)
+ timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return qMakePair(ts.tv_sec, ts.tv_nsec);
+#else
+# if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED)
+ if (QElapsedTimer::isMonotonic()) {
+ timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return qMakePair(ts.tv_sec, ts.tv_nsec);
+ }
+# endif
+ // use gettimeofday
+ timeval tv;
+ ::gettimeofday(&tv, 0);
+ return qMakePair(tv.tv_sec, tv.tv_usec);
+#endif
+}
+
+// used in qcore_unix.cpp and qeventdispatcher_unix.cpp
+timeval qt_gettime()
+{
+ QPair<long, long> r = do_gettime();
+
+ timeval tv;
+ tv.tv_sec = r.first;
+ tv.tv_usec = r.second;
+ if (QElapsedTimer::isMonotonic())
+ tv.tv_usec /= 1000;
+
+ return tv;
+}
+
+void QElapsedTimer::start()
+{
+ QPair<long, long> r = do_gettime();
+ t1 = r.first;
+ t2 = r.second;
+}
+
+qint64 QElapsedTimer::restart()
+{
+ QPair<long, long> r = do_gettime();
+ qint64 oldt1 = t1;
+ qint64 oldt2 = t2;
+ t1 = r.first;
+ t2 = r.second;
+
+ r.first -= oldt1;
+ r.second -= oldt2;
+ return r.first * Q_INT64_C(1000) + r.second / fractionAdjustment();
+}
+
+qint64 QElapsedTimer::elapsed() const
+{
+ QElapsedTimer now;
+ now.start();
+ return msecsTo(now);
+}
+
+qint64 QElapsedTimer::msecsSinceReference() const
+{
+ return t1 * Q_INT64_C(1000) + t2 / fractionAdjustment();
+}
+
+qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const
+{
+ qint64 secs = other.t1 - t1;
+ qint64 fraction = other.t2 - t2;
+ return secs * Q_INT64_C(1000) + fraction / fractionAdjustment();
+}
+
+qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const
+{
+ return other.t1 - t1;
+}
+
+bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2)
+{
+ 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
new file mode 100644
index 0000000..135196a
--- /dev/null
+++ b/src/corelib/tools/qelapsedtimer_win.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qelapsedtimer.h"
+#include <windows.h>
+
+typedef ULONGLONG (WINAPI *PtrGetTickCount64)(void);
+static PtrGetTickCount64 ptrGetTickCount64 = 0;
+
+QT_BEGIN_NAMESPACE
+
+static void resolveLibs()
+{
+ static bool done = false;
+ if (done)
+ return;
+
+ // try to get GetTickCount64 from the system
+ HMODULE kernel32 = GetModuleHandleW(L"kernel32");
+ if (!kernel32)
+ return;
+
+#if defined(Q_OS_WINCE)
+ // does this function exist on WinCE, or will ever exist?
+ ptrGetTickCount64 = (PtrGetTickCount64)GetProcAddress(kernel32, L"GetTickCount64");
+#else
+ ptrGetTickCount64 = (PtrGetTickCount64)GetProcAddress(kernel32, "GetTickCount64");
+#endif
+
+ done = true;
+}
+
+static quint64 getTickCount()
+{
+ resolveLibs();
+ if (ptrGetTickCount64)
+ return ptrGetTickCount64();
+
+ static quint32 highdword = 0;
+ static quint32 lastval = 0;
+ quint32 val = GetTickCount();
+ if (val < lastval)
+ ++highdword;
+ lastval = val;
+ return val | (quint64(highdword) << 32);
+}
+
+QElapsedTimer::ClockType QElapsedTimer::clockType()
+{
+ return TickCounter;
+}
+
+bool QElapsedTimer::isMonotonic()
+{
+ return true;
+}
+
+void QElapsedTimer::start()
+{
+ t1 = getTickCount();
+ t2 = 0;
+}
+
+qint64 QElapsedTimer::restart()
+{
+ qint64 oldt1 = t1;
+ t1 = getTickCount();
+ t2 = 0;
+ return t1 - oldt1;
+}
+
+qint64 QElapsedTimer::elapsed() const
+{
+ return getTickCount() - t1;
+}
+
+qint64 QElapsedTimer::msecsSinceReference() const
+{
+ return t1;
+}
+
+qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const
+{
+ return other.t1 - t1;
+}
+
+qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const
+{
+ return msecsTo(other) / 1000;
+}
+
+bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2)
+{
+ return (v1.t1 - v2.t1) < 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 1966a79..e36497c 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -1274,11 +1274,25 @@ QLocale QSystemLocale::fallbackLocale() const
*/
QVariant QSystemLocale::query(QueryType type, QVariant /* in */) const
{
- if (type == MeasurementSystem) {
+ switch (type) {
+ case MeasurementSystem:
return QVariant(unixGetSystemMeasurementSystem());
- } else {
- return QVariant();
+ case LanguageId:
+ case CountryId: {
+ QString locale = QLatin1String(envVarLocale());
+ QLocale::Language lang;
+ QLocale::Country cntry;
+ getLangAndCountry(locale, lang, cntry);
+ if (type == LanguageId)
+ return lang;
+ if (cntry == QLocale::AnyCountry)
+ return fallbackLocale().country();
+ return cntry;
+ }
+ default:
+ break;
}
+ return QVariant();
}
#elif !defined(Q_OS_SYMBIAN)
@@ -1310,12 +1324,10 @@ QVariant QSystemLocale::query(QueryType /* type */, QVariant /* in */) const
#endif
-#ifndef QT_NO_SYSTEMLOCALE
static QSystemLocale *_systemLocale = 0;
Q_GLOBAL_STATIC_WITH_ARGS(QSystemLocale, QSystemLocale_globalSystemLocale, (true))
static QLocalePrivate *system_lp = 0;
Q_GLOBAL_STATIC(QLocalePrivate, globalLocalePrivate)
-#endif
/******************************************************************************
** Default system locale behavior
@@ -1388,7 +1400,8 @@ QSystemLocale::QSystemLocale()
/*! \internal */
QSystemLocale::QSystemLocale(bool)
-{ }
+{
+}
/*!
Deletes the object.
@@ -1410,16 +1423,42 @@ static const QSystemLocale *systemLocale()
return QSystemLocale_globalSystemLocale();
}
+static const QLocalePrivate *maybeSystemPrivate();
+bool QLocalePrivate::isUninitializedSystemLocale() const
+{
+ return this == maybeSystemPrivate() && m_language_id == 0;
+}
+
+QVariant QLocalePrivate::querySystemLocale(int type, const QVariant &in) const
+{
+ QVariant res = systemLocale()->query(QSystemLocale::QueryType(type), in);
+ if (res.isNull() && isUninitializedSystemLocale()) {
+ // if we were not able to get data from the system, initialize the
+ // system locale private data (which is essentially equals to this)
+ // with a fallback locale.
+ QLocalePrivate *system_private = globalLocalePrivate();
+ *system_private = *systemLocale()->fallbackLocale().d();
+ // internal cache is not initialized with values from the system, mark
+ // it as not fully initialized system locale.
+ system_private->m_language_id = 0;
+ }
+ return res;
+}
+
+// retrieves data from the system locale and caches them locally.
void QLocalePrivate::updateSystemPrivate()
{
const QSystemLocale *sys_locale = systemLocale();
if (!system_lp)
- system_lp = globalLocalePrivate();
+ return;
+
+ // copy over the information from the fallback locale and modify
*system_lp = *sys_locale->fallbackLocale().d();
QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant());
if (!res.isNull())
system_lp->m_language_id = res.toInt();
+
res = sys_locale->query(QSystemLocale::CountryId, QVariant());
if (!res.isNull())
system_lp->m_country_id = res.toInt();
@@ -1446,19 +1485,29 @@ void QLocalePrivate::updateSystemPrivate()
}
#endif
+// returns the private data for the system locale. Cached data will not be
+// initialized until the updateSystemPrivate is called.
static const QLocalePrivate *systemPrivate()
{
#ifndef QT_NO_SYSTEMLOCALE
- // copy over the information from the fallback locale and modify
- if (!system_lp || system_lp->m_language_id == 0)
- QLocalePrivate::updateSystemPrivate();
-
+ if (!system_lp) {
+ system_lp = globalLocalePrivate();
+ // mark the locale as uninitialized system locale
+ system_lp->m_language_id = 0;
+ }
return system_lp;
#else
return locale_data;
#endif
}
+#ifndef QT_NO_SYSTEMLOCALE
+static const QLocalePrivate *maybeSystemPrivate()
+{
+ return system_lp;
+}
+#endif
+
static const QLocalePrivate *defaultPrivate()
{
if (!default_lp)
@@ -2283,7 +2332,12 @@ void QLocale::setDefault(const QLocale &locale)
*/
QLocale::Language QLocale::language() const
{
- return Language(d()->languageId());
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return Language(dd->languageId());
}
/*!
@@ -2293,7 +2347,12 @@ QLocale::Language QLocale::language() const
*/
QLocale::Country QLocale::country() const
{
- return Country(d()->countryId());
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return Country(dd->countryId());
}
/*!
@@ -2631,8 +2690,8 @@ QString QLocale::toString(const QDate &date, FormatType format) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(format == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(format == LongFormat
? QSystemLocale::DateToStringLong : QSystemLocale::DateToStringShort,
date);
if (!res.isNull())
@@ -2726,8 +2785,8 @@ QString QLocale::toString(const QDateTime &dateTime, FormatType format) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(format == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(format == LongFormat
? QSystemLocale::DateTimeToStringLong
: QSystemLocale::DateTimeToStringShort,
dateTime);
@@ -2752,8 +2811,8 @@ QString QLocale::toString(const QTime &time, FormatType format) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(format == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(format == LongFormat
? QSystemLocale::TimeToStringLong : QSystemLocale::TimeToStringShort,
time);
if (!res.isNull())
@@ -2779,8 +2838,8 @@ QString QLocale::toString(const QTime &time, FormatType format) const
QString QLocale::dateFormat(FormatType format) const
{
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(format == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(format == LongFormat
? QSystemLocale::DateFormatLong : QSystemLocale::DateFormatShort,
QVariant());
if (!res.isNull())
@@ -2816,8 +2875,8 @@ QString QLocale::dateFormat(FormatType format) const
QString QLocale::timeFormat(FormatType format) const
{
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(format == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(format == LongFormat
? QSystemLocale::TimeFormatLong : QSystemLocale::TimeFormatShort,
QVariant());
if (!res.isNull())
@@ -2853,8 +2912,8 @@ QString QLocale::timeFormat(FormatType format) const
QString QLocale::dateTimeFormat(FormatType format) const
{
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(format == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(format == LongFormat
? QSystemLocale::DateTimeFormatLong
: QSystemLocale::DateTimeFormatShort,
QVariant());
@@ -3021,7 +3080,12 @@ QDateTime QLocale::toDateTime(const QString &string, const QString &format) cons
*/
QChar QLocale::decimalPoint() const
{
- return d()->decimal();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->decimal();
}
/*!
@@ -3031,7 +3095,12 @@ QChar QLocale::decimalPoint() const
*/
QChar QLocale::groupSeparator() const
{
- return d()->group();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->group();
}
/*!
@@ -3041,7 +3110,12 @@ QChar QLocale::groupSeparator() const
*/
QChar QLocale::percent() const
{
- return d()->percent();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->percent();
}
/*!
@@ -3051,7 +3125,12 @@ QChar QLocale::percent() const
*/
QChar QLocale::zeroDigit() const
{
- return d()->zero();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->zero();
}
/*!
@@ -3061,7 +3140,12 @@ QChar QLocale::zeroDigit() const
*/
QChar QLocale::negativeSign() const
{
- return d()->minus();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->minus();
}
/*!
@@ -3071,7 +3155,12 @@ QChar QLocale::negativeSign() const
*/
QChar QLocale::positiveSign() const
{
- return d()->plus();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->plus();
}
/*!
@@ -3081,7 +3170,12 @@ QChar QLocale::positiveSign() const
*/
QChar QLocale::exponential() const
{
- return d()->exponential();
+ const QLocalePrivate *dd = d();
+#ifndef QT_NO_SYSTEMLOCALE
+ if (dd->isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
+ return dd->exponential();
}
static bool qIsUpper(char c)
@@ -3200,8 +3294,8 @@ QString QLocale::monthName(int month, FormatType type) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(type == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(type == LongFormat
? QSystemLocale::MonthNameLong : QSystemLocale::MonthNameShort,
month);
if (!res.isNull())
@@ -3246,8 +3340,8 @@ QString QLocale::standaloneMonthName(int month, FormatType type) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(type == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(type == LongFormat
? QSystemLocale::MonthNameLong : QSystemLocale::MonthNameShort,
month);
if (!res.isNull())
@@ -3293,8 +3387,8 @@ QString QLocale::dayName(int day, FormatType type) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(type == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(type == LongFormat
? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort,
day);
if (!res.isNull())
@@ -3342,8 +3436,8 @@ QString QLocale::standaloneDayName(int day, FormatType type) const
return QString();
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(type == LongFormat
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(type == LongFormat
? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort,
day);
if (!res.isNull())
@@ -3387,8 +3481,8 @@ QLocale::MeasurementSystem QLocale::measurementSystem() const
bool found = false;
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(QSystemLocale::MeasurementSystem, QVariant());
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(QSystemLocale::MeasurementSystem, QVariant());
if (!res.isNull()) {
meas = MeasurementSystem(res.toInt());
found = true;
@@ -3415,8 +3509,8 @@ QLocale::MeasurementSystem QLocale::measurementSystem() const
QString QLocale::amText() const
{
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(QSystemLocale::AMText, QVariant());
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(QSystemLocale::AMText, QVariant());
if (!res.isNull())
return res.toString();
}
@@ -3435,8 +3529,8 @@ QString QLocale::amText() const
QString QLocale::pmText() const
{
#ifndef QT_NO_SYSTEMLOCALE
- if (d() == systemPrivate()) {
- QVariant res = systemLocale()->query(QSystemLocale::PMText, QVariant());
+ if (d() == maybeSystemPrivate()) {
+ QVariant res = d()->querySystemLocale(QSystemLocale::PMText, QVariant());
if (!res.isNull())
return res.toString();
}
@@ -3851,6 +3945,10 @@ QString QLocalePrivate::doubleToString(double d,
int width,
unsigned flags) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
if (precision == -1)
precision = 6;
if (width == -1)
@@ -4001,6 +4099,10 @@ QString QLocalePrivate::longLongToString(qlonglong l, int precision,
int base, int width,
unsigned flags) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
bool precision_not_specified = false;
if (precision == -1) {
precision_not_specified = true;
@@ -4086,6 +4188,10 @@ QString QLocalePrivate::unsLongLongToString(qulonglong l, int precision,
int base, int width,
unsigned flags) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
bool precision_not_specified = false;
if (precision == -1) {
precision_not_specified = true;
@@ -4288,6 +4394,10 @@ bool QLocalePrivate::numberToCLocale(const QString &num,
bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByteArray *buff,
int decDigits) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
buff->clear();
buff->reserve(str.length());
@@ -4381,6 +4491,10 @@ bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByte
double QLocalePrivate::stringToDouble(const QString &number, bool *ok,
GroupSeparatorMode group_sep_mode) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
CharBuff buff;
if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
group_sep_mode, &buff)) {
@@ -4394,6 +4508,10 @@ double QLocalePrivate::stringToDouble(const QString &number, bool *ok,
qlonglong QLocalePrivate::stringToLongLong(const QString &number, int base,
bool *ok, GroupSeparatorMode group_sep_mode) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
CharBuff buff;
if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
group_sep_mode, &buff)) {
@@ -4408,6 +4526,10 @@ qlonglong QLocalePrivate::stringToLongLong(const QString &number, int base,
qulonglong QLocalePrivate::stringToUnsLongLong(const QString &number, int base,
bool *ok, GroupSeparatorMode group_sep_mode) const
{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (isUninitializedSystemLocale())
+ QLocalePrivate::updateSystemPrivate();
+#endif
CharBuff buff;
if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
group_sep_mode, &buff)) {
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index e854c84..9b7b214 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -638,6 +638,7 @@ public:
;
private:
friend struct QLocalePrivate;
+
// ### We now use this field to pack an index into locale_data and NumberOptions.
// ### Qt 5: change to a QLocaleData *d; uint numberOptions.
union {
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index ecf79e9..003ae8c 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -63,14 +63,14 @@ QT_BEGIN_NAMESPACE
struct Q_CORE_EXPORT QLocalePrivate
{
public:
- QChar decimal() const { return QChar(m_decimal); }
- QChar group() const { return QChar(m_group); }
- QChar list() const { return QChar(m_list); }
- QChar percent() const { return QChar(m_percent); }
- QChar zero() const { return QChar(m_zero); }
- QChar plus() const { return QChar(m_plus); }
- QChar minus() const { return QChar(m_minus); }
- QChar exponential() const { return QChar(m_exponential); }
+ QChar decimal() const { Q_ASSERT(m_decimal); return QChar(m_decimal); }
+ QChar group() const { Q_ASSERT(m_group); return QChar(m_group); }
+ QChar list() const { Q_ASSERT(m_list); return QChar(m_list); }
+ QChar percent() const { Q_ASSERT(m_percent); return QChar(m_percent); }
+ QChar zero() const { Q_ASSERT(m_zero); return QChar(m_zero); }
+ QChar plus() const { Q_ASSERT(m_plus); return QChar(m_plus); }
+ QChar minus() const { Q_ASSERT(m_minus); return QChar(m_minus); }
+ QChar exponential() const { Q_ASSERT(m_exponential); return QChar(m_exponential); }
quint32 languageId() const { return m_language_id; }
quint32 countryId() const { return m_country_id; }
@@ -132,6 +132,8 @@ public:
CharBuff *result) const;
inline char digitToCLocale(const QChar &c) const;
+ inline bool isUninitializedSystemLocale() const;
+ QVariant querySystemLocale(int type, const QVariant &in) const;
static void updateSystemPrivate();
enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode };
diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp
index 877a77a..f413223 100644
--- a/src/corelib/tools/qtimeline.cpp
+++ b/src/corelib/tools/qtimeline.cpp
@@ -42,9 +42,9 @@
#include "qtimeline.h"
#include <private/qobject_p.h>
-#include <QtCore/qdatetime.h>
#include <QtCore/qcoreevent.h>
#include <QtCore/qmath.h>
+#include <QtCore/qelapsedtimer.h>
QT_BEGIN_NAMESPACE
@@ -70,7 +70,7 @@ public:
int currentTime;
int timerId;
- QTime timer;
+ QElapsedTimer timer;
QTimeLine::Direction direction;
QEasingCurve easingCurve;
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 6d64915..4e0ebbc 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -42,6 +42,7 @@ HEADERS += \
tools/qstringmatcher.h \
tools/qtextboundaryfinder.h \
tools/qtimeline.h \
+ tools/qelapsedtimer.h \
tools/qunicodetables_p.h \
tools/qvarlengtharray.h \
tools/qvector.h \
@@ -56,6 +57,7 @@ SOURCES += \
tools/qcryptographichash.cpp \
tools/qdatetime.cpp \
tools/qeasingcurve.cpp \
+ tools/qelapsedtimer.cpp \
tools/qhash.cpp \
tools/qline.cpp \
tools/qlinkedlist.cpp \
@@ -81,6 +83,12 @@ SOURCES += \
symbian:SOURCES+=tools/qlocale_symbian.cpp
+mac:SOURCES += tools/qelapsedtimer_mac.cpp
+else:symbian:SOURCES += tools/qelapsedtimer_symbian.cpp
+else:unix:SOURCES += tools/qelapsedtimer_unix.cpp
+else:win32:SOURCES += tools/qelapsedtimer_win.cpp
+else:SOURCES += tools/qelapsedtimer_generic.cpp
+
#zlib support
contains(QT_CONFIG, zlib) {
wince*: DEFINES += NO_ERRNO_H