diff options
author | Jason Barron <jbarron@trolltech.com> | 2009-07-29 06:45:10 (GMT) |
---|---|---|
committer | Jason Barron <jbarron@trolltech.com> | 2009-07-29 06:45:10 (GMT) |
commit | 77bd318b2892ad2a6beefee84c8e1436f4f7f386 (patch) | |
tree | 0de55e09200679501da73babed5cce1d4b558781 /src/corelib/kernel | |
parent | 7eba68adc4a7862d9474179592e5c8393a7acdbb (diff) | |
parent | d22d08f3f8a70edfc66c0f6c2fd952688b64fcc2 (diff) | |
download | Qt-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.cpp | 75 | ||||
-rw-r--r-- | src/corelib/kernel/qcore_unix_p.h | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_unix.cpp | 101 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_unix_p.h | 4 |
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(); |