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>
This commit is contained in:
parent
407d076124
commit
47cf674477
@ -105,7 +105,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
Q_DECLARE_TYPEINFO(pollfd, Q_PRIMITIVE_TYPE);
|
Q_DECLARE_TYPEINFO(pollfd, Q_PRIMITIVE_TYPE);
|
||||||
|
|
||||||
// Internal operator functions for timespecs
|
// Internal operator functions for timespecs
|
||||||
inline timespec &normalizedTimespec(timespec &t)
|
constexpr inline timespec &normalizedTimespec(timespec &t)
|
||||||
{
|
{
|
||||||
while (t.tv_nsec >= 1000000000) {
|
while (t.tv_nsec >= 1000000000) {
|
||||||
++t.tv_sec;
|
++t.tv_sec;
|
||||||
@ -117,35 +117,35 @@ inline timespec &normalizedTimespec(timespec &t)
|
|||||||
}
|
}
|
||||||
return 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); }
|
{ 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; }
|
{ 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); }
|
{ 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_sec += t2.tv_sec;
|
||||||
t1.tv_nsec += t2.tv_nsec;
|
t1.tv_nsec += t2.tv_nsec;
|
||||||
return normalizedTimespec(t1);
|
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_sec = t1.tv_sec + t2.tv_sec;
|
||||||
tmp.tv_nsec = t1.tv_nsec + t2.tv_nsec;
|
tmp.tv_nsec = t1.tv_nsec + t2.tv_nsec;
|
||||||
return normalizedTimespec(tmp);
|
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_sec = t1.tv_sec - (t2.tv_sec - 1);
|
||||||
tmp.tv_nsec = t1.tv_nsec - (t2.tv_nsec + 1000000000);
|
tmp.tv_nsec = t1.tv_nsec - (t2.tv_nsec + 1000000000);
|
||||||
return normalizedTimespec(tmp);
|
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_sec = t1.tv_sec * mul;
|
||||||
tmp.tv_nsec = t1.tv_nsec * mul;
|
tmp.tv_nsec = t1.tv_nsec * mul;
|
||||||
return normalizedTimespec(tmp);
|
return normalizedTimespec(tmp);
|
||||||
|
@ -197,15 +197,22 @@ inline timespec operator+(const timespec &t1, int ms)
|
|||||||
return t2 += ms;
|
return t2 += ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
static timespec roundToMillisecond(timespec val)
|
static constexpr timespec roundToMillisecond(timespec val)
|
||||||
{
|
{
|
||||||
// always round up
|
// always round up
|
||||||
// worst case scenario is that the first trigger of a 1-ms timer is 0.999 ms late
|
// 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);
|
int ns = val.tv_nsec % (1000 * 1000);
|
||||||
val.tv_nsec += 1000 * 1000 - ns;
|
if (ns)
|
||||||
|
val.tv_nsec += 1000 * 1000 - ns;
|
||||||
return normalizedTimespec(val);
|
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
|
#ifdef QTIMERINFO_DEBUG
|
||||||
QDebug operator<<(QDebug s, timeval tv)
|
QDebug operator<<(QDebug s, timeval tv)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user