diff options
author | Bradley T. Hughes <bradley.hughes@nokia.com> | 2009-07-27 11:23:26 (GMT) |
---|---|---|
committer | Bradley T. Hughes <bradley.hughes@nokia.com> | 2009-07-27 11:32:29 (GMT) |
commit | 1edad2af19ee67c3e3504c8226fc3cfef9fd51a1 (patch) | |
tree | 79e4a017bedf38d9aa7fa9d1b3d3a417d11507a4 /src/corelib/kernel/qcore_unix.cpp | |
parent | f2135cccffbef6d6accb49f404d9b23ade418641 (diff) | |
download | Qt-1edad2af19ee67c3e3504c8226fc3cfef9fd51a1.zip Qt-1edad2af19ee67c3e3504c8226fc3cfef9fd51a1.tar.gz Qt-1edad2af19ee67c3e3504c8226fc3cfef9fd51a1.tar.bz2 |
Refactor monotonic time code to avoid duplication.
Merge the monotonic clock source detection in
qeventdispatcher_unix.cpp with that in qcore_unix.cpp. As discussed
with Thiago, we're also removing older compat code at the same time
(spinning on select() when we think it woke up early).
Reviewed-by: Thiago
Diffstat (limited to 'src/corelib/kernel/qcore_unix.cpp')
-rw-r--r-- | src/corelib/kernel/qcore_unix.cpp | 71 |
1 files changed, 53 insertions, 18 deletions
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index c5b0fc7..6ef56fd 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -55,37 +55,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 * 1e-9; + tv.tv_usec = nsecs * 1e-3 - (t.tv_sec * 1e6); + 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 +135,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 |