diff options
Diffstat (limited to 'src/libs/utils/scopedtimer.cpp')
-rw-r--r-- | src/libs/utils/scopedtimer.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/libs/utils/scopedtimer.cpp b/src/libs/utils/scopedtimer.cpp new file mode 100644 index 0000000000..6a4522e28d --- /dev/null +++ b/src/libs/utils/scopedtimer.cpp @@ -0,0 +1,67 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "scopedtimer.h" + +#include <QDebug> +#include <QTime> + +#include <chrono> + +namespace Utils { + +static QString currentTime() { return QTime::currentTime().toString(Qt::ISODateWithMs); } + +using namespace std::chrono; + +static const char s_scoped[] = "SCOPED TIMER"; +static const char s_scopedCumulative[] = "STATIC SCOPED TIMER"; + +class ScopedTimerPrivate +{ +public: + QString header() const { + const char *scopedTimerType = m_data.m_cumulative ? s_scopedCumulative : s_scoped; + const QString prefix = QLatin1String(scopedTimerType) + " [" + currentTime() + "] "; + const QString infix = m_data.m_message.isEmpty() + ? QLatin1String(m_data.m_fileName) + ':' + QString::number(m_data.m_line) + : m_data.m_message; + return prefix + infix + ' '; + } + + const ScopedTimerData m_data; + const time_point<system_clock, nanoseconds> m_start = system_clock::now(); +}; + +ScopedTimer::ScopedTimer(const ScopedTimerData &data) + : d(new ScopedTimerPrivate{data}) +{ + if (d->m_data.m_cumulative) + return; + qDebug().noquote().nospace() << d->header() << "started"; +} + +static int64_t toMs(int64_t ns) { return ns / 1000000; } + +ScopedTimer::~ScopedTimer() +{ + const auto elapsed = duration_cast<nanoseconds>(system_clock::now() - d->m_start); + QString suffix; + if (d->m_data.m_cumulative) { + const int64_t nsOld = d->m_data.m_cumulative->fetch_add(elapsed.count()); + const int64_t msOld = toMs(nsOld); + const int64_t nsNew = nsOld + elapsed.count(); + const int64_t msNew = toMs(nsNew); + // Always report the first hit, and later, as not to clog the debug output, + // only at 10ms resolution. + if (nsOld != 0 && msOld / 10 == msNew / 10) + return; + + suffix = "cumulative timeout: " + QString::number(msNew) + "ms"; + } else { + suffix = "stopped with timeout: " + QString::number(toMs(elapsed.count())) + "ms"; + } + qDebug().noquote().nospace() << d->header() << suffix; +} + +} // namespace Utils |