diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2022-02-10 20:06:07 -0800 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2022-02-11 13:02:35 -0800 |
commit | 47cf674477473a05390df4a218fd6b3867c6e923 (patch) | |
tree | b751a30bf7ce841af16711a0e9291f1c80c699a2 /src/corelib/kernel | |
parent | 407d076124d42a1f4911e139ffb2d77a117ef277 (diff) |
QTimerInfo/Unix: Fix roundToMillisecond when it's already rounded
Don't add 1 ms when it's rounded to 1 ms.
Found when running unit tests on QNX, where the clock did not update
between two subsequent calls to clock_gettime().
All of this ought to be refactored to use std::chrono::nanoseconds.
Fixes: QTBUG-100438
Pick-to: 6.2 6.3
Change-Id: I47dc6426c33d3a66dec946ae3589694745ed1835
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qcore_unix_p.h | 22 | ||||
-rw-r--r-- | src/corelib/kernel/qtimerinfo_unix.cpp | 11 |
2 files changed, 20 insertions, 13 deletions
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index abe9bb3738..23c20b1749 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -105,7 +105,7 @@ QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(pollfd, Q_PRIMITIVE_TYPE); // Internal operator functions for timespecs -inline timespec &normalizedTimespec(timespec &t) +constexpr inline timespec &normalizedTimespec(timespec &t) { while (t.tv_nsec >= 1000000000) { ++t.tv_sec; @@ -117,35 +117,35 @@ inline timespec &normalizedTimespec(timespec &t) } return t; } -inline bool operator<(const timespec &t1, const timespec &t2) +constexpr inline bool operator<(const timespec &t1, const timespec &t2) { return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_nsec < t2.tv_nsec); } -inline bool operator==(const timespec &t1, const timespec &t2) +constexpr inline bool operator==(const timespec &t1, const timespec &t2) { return t1.tv_sec == t2.tv_sec && t1.tv_nsec == t2.tv_nsec; } -inline bool operator!=(const timespec &t1, const timespec &t2) +constexpr inline bool operator!=(const timespec &t1, const timespec &t2) { return !(t1 == t2); } -inline timespec &operator+=(timespec &t1, const timespec &t2) +constexpr inline timespec &operator+=(timespec &t1, const timespec &t2) { t1.tv_sec += t2.tv_sec; t1.tv_nsec += t2.tv_nsec; return normalizedTimespec(t1); } -inline timespec operator+(const timespec &t1, const timespec &t2) +constexpr inline timespec operator+(const timespec &t1, const timespec &t2) { - timespec tmp; + timespec tmp = {}; tmp.tv_sec = t1.tv_sec + t2.tv_sec; tmp.tv_nsec = t1.tv_nsec + t2.tv_nsec; return normalizedTimespec(tmp); } -inline timespec operator-(const timespec &t1, const timespec &t2) +constexpr inline timespec operator-(const timespec &t1, const timespec &t2) { - timespec tmp; + timespec tmp = {}; tmp.tv_sec = t1.tv_sec - (t2.tv_sec - 1); tmp.tv_nsec = t1.tv_nsec - (t2.tv_nsec + 1000000000); return normalizedTimespec(tmp); } -inline timespec operator*(const timespec &t1, int mul) +constexpr inline timespec operator*(const timespec &t1, int mul) { - timespec tmp; + timespec tmp = {}; tmp.tv_sec = t1.tv_sec * mul; tmp.tv_nsec = t1.tv_nsec * mul; return normalizedTimespec(tmp); diff --git a/src/corelib/kernel/qtimerinfo_unix.cpp b/src/corelib/kernel/qtimerinfo_unix.cpp index db4d4b1188..3b1696647b 100644 --- a/src/corelib/kernel/qtimerinfo_unix.cpp +++ b/src/corelib/kernel/qtimerinfo_unix.cpp @@ -197,15 +197,22 @@ inline timespec operator+(const timespec &t1, int ms) return t2 += ms; } -static timespec roundToMillisecond(timespec val) +static constexpr timespec roundToMillisecond(timespec val) { // always round up // worst case scenario is that the first trigger of a 1-ms timer is 0.999 ms late int ns = val.tv_nsec % (1000 * 1000); - val.tv_nsec += 1000 * 1000 - ns; + if (ns) + val.tv_nsec += 1000 * 1000 - ns; return normalizedTimespec(val); } +static_assert(roundToMillisecond({0, 0}) == timespec{0, 0}); +static_assert(roundToMillisecond({0, 1}) == timespec{0, 1'000'000}); +static_assert(roundToMillisecond({0, 999'999}) == timespec{0, 1'000'000}); +static_assert(roundToMillisecond({0, 1'000'000}) == timespec{0, 1'000'000}); +static_assert(roundToMillisecond({0, 999'999'999}) == timespec{1, 0}); +static_assert(roundToMillisecond({1, 0}) == timespec{1, 0}); #ifdef QTIMERINFO_DEBUG QDebug operator<<(QDebug s, timeval tv) |