summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorJason Barron <jbarron@trolltech.com>2009-07-29 06:45:10 (GMT)
committerJason Barron <jbarron@trolltech.com>2009-07-29 06:45:10 (GMT)
commit77bd318b2892ad2a6beefee84c8e1436f4f7f386 (patch)
tree0de55e09200679501da73babed5cce1d4b558781 /src/corelib/kernel
parent7eba68adc4a7862d9474179592e5c8393a7acdbb (diff)
parentd22d08f3f8a70edfc66c0f6c2fd952688b64fcc2 (diff)
downloadQt-77bd318b2892ad2a6beefee84c8e1436f4f7f386.zip
Qt-77bd318b2892ad2a6beefee84c8e1436f4f7f386.tar.gz
Qt-77bd318b2892ad2a6beefee84c8e1436f4f7f386.tar.bz2
Merge commit 'qt/master-stable'
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qcore_unix.cpp75
-rw-r--r--src/corelib/kernel/qcore_unix_p.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp101
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix_p.h4
4 files changed, 64 insertions, 118 deletions
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp
index c5b0fc7..28c1d9c 100644
--- a/src/corelib/kernel/qcore_unix.cpp
+++ b/src/corelib/kernel/qcore_unix.cpp
@@ -47,6 +47,10 @@
#include "qeventdispatcher_unix_p.h" // for the timeval operators
+#ifdef Q_OS_MAC
+#include <mach/mach_time.h>
+#endif
+
#if !defined(QT_NO_CLOCK_MONOTONIC)
# if defined(QT_BOOTSTRAPPED)
# define QT_NO_CLOCK_MONOTONIC
@@ -55,37 +59,72 @@
QT_BEGIN_NAMESPACE
-static inline timeval gettime()
+bool qt_gettime_is_monotonic()
{
- timeval tv;
-#ifndef QT_NO_CLOCK_MONOTONIC
- // use the monotonic clock
- static volatile bool monotonicClockDisabled = false;
- struct timespec ts;
- if (!monotonicClockDisabled) {
- if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
- monotonicClockDisabled = true;
- } else {
- tv.tv_sec = ts.tv_sec;
- tv.tv_usec = ts.tv_nsec / 1000;
- return tv;
- }
+#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)
{
- struct timeval now = gettime();
- if (now < start) {
- // clock reset, give up
+ if (!qt_gettime_is_monotonic()) {
+ // we cannot recalculate the timeout without a monotonic clock as the time may have changed
return false;
}
+ // clock source is monotonic, so we can recalculate how much timeout is left
+ struct timeval now = qt_gettime();
*tv = timeout + start - now;
return true;
}
@@ -100,7 +139,7 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
return ret;
}
- timeval start = gettime();
+ timeval start = qt_gettime();
timeval timeout = *orig_timeout;
// loop and recalculate the timeout as needed
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index 565c895..28bc34a 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -270,6 +270,8 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options)
return ret;
}
+bool qt_gettime_is_monotonic();
+timeval qt_gettime();
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/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index 288b381..c3979e8 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -59,33 +59,10 @@
# include <sys/times.h>
#endif
-#ifdef Q_OS_MAC
-#include <mach/mach_time.h>
-#endif
-
QT_BEGIN_NAMESPACE
Q_CORE_EXPORT bool qt_disable_lowpriority_timers=false;
-// check for _POSIX_MONOTONIC_CLOCK support
-static bool supportsMonotonicClock()
-{
- bool returnValue;
-
-#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)
- returnValue = false;
-# if (_POSIX_MONOTONIC_CLOCK == 0)
- // detect if the system support monotonic timers
- long x = sysconf(_SC_MONOTONIC_CLOCK);
- returnValue = x >= 200112L;
-# endif
-#else
- returnValue = true;
-#endif
-
- return returnValue;
-}
-
/*****************************************************************************
UNIX signal handling
*****************************************************************************/
@@ -281,12 +258,11 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags,
*/
QTimerInfoList::QTimerInfoList()
- : useMonotonicTimers(supportsMonotonicClock())
{
- getTime(currentTime);
+ currentTime = qt_gettime();
#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)
- if (!useMonotonicTimers) {
+ if (!qt_gettime_is_monotonic()) {
// not using monotonic timers, initialize the timeChanged() machinery
previousTime = currentTime;
@@ -309,8 +285,7 @@ QTimerInfoList::QTimerInfoList()
timeval QTimerInfoList::updateCurrentTime()
{
- getTime(currentTime);
- return currentTime;
+ return (currentTime = qt_gettime());
}
#if ((_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)) || defined(QT_BOOTSTRAPPED)
@@ -364,38 +339,9 @@ bool QTimerInfoList::timeChanged(timeval *delta)
return elapsedTimeTicks < ((qAbs(*delta) - tickGranularity) * 10);
}
-void QTimerInfoList::getTime(timeval &t)
-{
-#if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED)
- if (useMonotonicTimers) {
- timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- t.tv_sec = ts.tv_sec;
- t.tv_usec = ts.tv_nsec / 1000;
- return;
- }
-#endif
-
- gettimeofday(&t, 0);
- // NTP-related fix
- while (t.tv_usec >= 1000000l) {
- t.tv_usec -= 1000000l;
- ++t.tv_sec;
- }
- while (t.tv_usec < 0l) {
- if (t.tv_sec > 0l) {
- t.tv_usec += 1000000l;
- --t.tv_sec;
- } else {
- t.tv_usec = 0l;
- break;
- }
- }
-}
-
void QTimerInfoList::repairTimersIfNeeded()
{
- if (useMonotonicTimers)
+ if (qt_gettime_is_monotonic())
return;
timeval delta;
if (timeChanged(&delta))
@@ -404,25 +350,6 @@ void QTimerInfoList::repairTimersIfNeeded()
#else // !(_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(QT_BOOTSTRAPPED)
-void QTimerInfoList::getTime(timeval &t)
-{
-#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);
- t.tv_sec = nsecs * 1e-9;
- t.tv_usec = nsecs * 1e-3 - (t.tv_sec * 1e6);
-#else
- timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- t.tv_sec = ts.tv_sec;
- t.tv_usec = ts.tv_nsec / 1000;
-#endif
-}
-
void QTimerInfoList::repairTimersIfNeeded()
{
}
@@ -651,25 +578,7 @@ QEventDispatcherUNIX::~QEventDispatcherUNIX()
int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
timeval *timeout)
{
- Q_D(QEventDispatcherUNIX);
- if (timeout && d->timerList.useMonotonicTimers) {
- // handle the case where select returns with a timeout, too
- // soon.
- timeval tvStart = d->timerList.currentTime;
- timeval tvCurrent = tvStart;
- timeval originalTimeout = *timeout;
-
- int nsel;
- do {
- timeval tvRest = originalTimeout + tvStart - tvCurrent;
- nsel = ::select(nfds, readfds, writefds, exceptfds, &tvRest);
- d->timerList.getTime(tvCurrent);
- } while (nsel == 0 && (tvCurrent - tvStart) < originalTimeout);
-
- return nsel;
- }
-
- return ::select(nfds, readfds, writefds, exceptfds, timeout);
+ return ::qt_safe_select(nfds, readfds, writefds, exceptfds, timeout);
}
/*!
diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h
index 88d645e..fedbccf 100644
--- a/src/corelib/kernel/qeventdispatcher_unix_p.h
+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h
@@ -142,10 +142,6 @@ class QTimerInfoList : public QList<QTimerInfo*>
public:
QTimerInfoList();
- const bool useMonotonicTimers;
-
- void getTime(timeval &t);
-
timeval currentTime;
timeval updateCurrentTime();