From c000143ee472fc613b91a4f16f321509e4f0ee18 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Jun 2016 00:34:10 -0700 Subject: [PATCH] QDeadlineTimer: optimize when std::chrono::steady_clock is the same Change-Id: Ib57b52598e2f452985e9fffd14583173716343b0 Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- src/corelib/kernel/qdeadlinetimer.h | 28 +++++++++++++++++++ .../qdeadlinetimer/tst_qdeadlinetimer.cpp | 12 ++++++++ 2 files changed, 40 insertions(+) diff --git a/src/corelib/kernel/qdeadlinetimer.h b/src/corelib/kernel/qdeadlinetimer.h index 180d5fe4317..8ec9380916c 100644 --- a/src/corelib/kernel/qdeadlinetimer.h +++ b/src/corelib/kernel/qdeadlinetimer.h @@ -192,6 +192,34 @@ public: QPair _q_data() const { return qMakePair(t1, t2); } }; +#if QT_HAS_INCLUDE() && (defined(Q_OS_DARWIN) || defined(Q_OS_LINUX) || (defined(Q_CC_MSVC) && Q_CC_MSVC >= 1900)) +// We know for these OS/compilers that the std::chrono::steady_clock uses the same +// reference time as QDeadlineTimer + +template <> inline std::chrono::steady_clock::time_point +QDeadlineTimer::deadline() const +{ + return std::chrono::steady_clock::time_point(std::chrono::nanoseconds(deadlineNSecs())); +} + +template <> inline void +QDeadlineTimer::setDeadline(std::chrono::steady_clock::time_point tp, Qt::TimerType type_) +{ + using namespace std::chrono; + if (tp == tp.max()) { + *this = Forever; + type = type_; + } else if (type_ != Qt::PreciseTimer) { + // if we aren't using PreciseTimer, then we need to convert + setPreciseRemainingTime(0, duration_cast(tp - steady_clock::now()).count(), type_); + } else { + setPreciseDeadline(0, + duration_cast(tp.time_since_epoch()).count(), + type_); + } +} +#endif + Q_DECLARE_SHARED(QDeadlineTimer) QT_END_NAMESPACE diff --git a/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp b/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp index e4ab2eb1db4..74ab52ee7ea 100644 --- a/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp +++ b/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp @@ -596,6 +596,18 @@ void tst_QDeadlineTimer::stdchrono() QTRY_VERIFY2_WITH_TIMEOUT(timersExecuted, "Looks like timers didn't fire on time.", 4 * minResolution); +#if defined(Q_OS_DARWIN) || defined(Q_OS_LINUX) || (defined(Q_CC_MSVC) && Q_CC_MSVC >= 1900) + { + // We know for these OS/compilers that the std::chrono::steady_clock uses the same + // reference time as QDeadlineTimer + qint64 before = duration_cast(steady_before.time_since_epoch()).count(); + qint64 after = duration_cast(steady_after.time_since_epoch()).count(); + QVERIFY2(now.deadlineNSecs() > before, QByteArray::number(now.deadlineNSecs()) + + " > " + QByteArray::number(before)); + QVERIFY2(now.deadlineNSecs() < after, QByteArray::number(now.deadlineNSecs()) + + " < " + QByteArray::number(after)); + } +#endif { auto diff = duration_cast(steady_after - steady_deadline); QVERIFY2(diff.count() > minResolution / 2, QByteArray::number(qint64(diff.count())));