summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libs/utils/CMakeLists.txt1
-rw-r--r--src/libs/utils/qtcassert.cpp28
-rw-r--r--src/libs/utils/qtcassert.h20
-rw-r--r--src/libs/utils/scopedtimer.cpp64
-rw-r--r--src/libs/utils/scopedtimer.h38
-rw-r--r--src/libs/utils/utils.qbs2
6 files changed, 105 insertions, 48 deletions
diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt
index e3bbfcf7a9..f05398094a 100644
--- a/src/libs/utils/CMakeLists.txt
+++ b/src/libs/utils/CMakeLists.txt
@@ -147,6 +147,7 @@ add_qtc_library(Utils
runextensions.cpp runextensions.h
savefile.cpp savefile.h
scopedswap.h
+ scopedtimer.cpp scopedtimer.h
searchresultitem.cpp searchresultitem.h
set_algorithm.h
settingsaccessor.cpp settingsaccessor.h
diff --git a/src/libs/utils/qtcassert.cpp b/src/libs/utils/qtcassert.cpp
index 019c223ef7..78baa41a4a 100644
--- a/src/libs/utils/qtcassert.cpp
+++ b/src/libs/utils/qtcassert.cpp
@@ -8,8 +8,6 @@
#include <QMutex>
#include <QTime>
-#include <chrono>
-
#if defined(Q_OS_UNIX)
#include <stdio.h>
#include <signal.h>
@@ -132,30 +130,4 @@ void writeAssertLocation(const char *msg)
dumpBacktrace(maxdepth);
}
-using namespace std::chrono;
-
-class ScopedTimerPrivate
-{
-public:
- const char *m_fileName = nullptr;
- const int m_line = 0;
- const time_point<system_clock, nanoseconds> m_start = system_clock::now();
-};
-
-ScopedTimer::ScopedTimer(const char *fileName, int line)
- : d(new ScopedTimerPrivate{fileName, line})
-{
- const QByteArray time = QTime::currentTime().toString(Qt::ISODateWithMs).toLatin1();
- qDebug("SCOPED TIMER [%s] in %s:%d started", time.data(), d->m_fileName, d->m_line);
-}
-
-ScopedTimer::~ScopedTimer()
-{
- const auto end = system_clock::now();
- const auto elapsed = duration_cast<milliseconds>(end - d->m_start);
- const QByteArray time = QTime::currentTime().toString(Qt::ISODateWithMs).toLatin1();
- qDebug("SCOPED TIMER [%s] in %s:%d stopped with timeout: %ldms",
- time.data(), d->m_fileName, d->m_line, elapsed.count());
-}
-
} // namespace Utils
diff --git a/src/libs/utils/qtcassert.h b/src/libs/utils/qtcassert.h
index aab7ab93d0..8f6b2ec5b8 100644
--- a/src/libs/utils/qtcassert.h
+++ b/src/libs/utils/qtcassert.h
@@ -5,25 +5,9 @@
#include "utils_global.h"
-#include <memory>
-
namespace Utils {
-
QTCREATOR_UTILS_EXPORT void writeAssertLocation(const char *msg);
QTCREATOR_UTILS_EXPORT void dumpBacktrace(int maxdepth);
-
-class ScopedTimerPrivate;
-
-class QTCREATOR_UTILS_EXPORT ScopedTimer
-{
-public:
- ScopedTimer(const char *fileName, int line);
- ~ScopedTimer();
-
-private:
- std::unique_ptr<ScopedTimerPrivate> d;
-};
-
} // Utils
#define QTC_ASSERT_STRINGIFY_HELPER(x) #x
@@ -37,7 +21,3 @@ private:
#define QTC_ASSERT(cond, action) if (Q_LIKELY(cond)) {} else { QTC_ASSERT_STRING(#cond); action; } do {} while (0)
#define QTC_CHECK(cond) if (Q_LIKELY(cond)) {} else { QTC_ASSERT_STRING(#cond); } do {} while (0)
#define QTC_GUARD(cond) ((Q_LIKELY(cond)) ? true : (QTC_ASSERT_STRING(#cond), false))
-
-#define QTC_CONCAT_HELPER(x, y) x ## y
-#define QTC_CONCAT(x, y) QTC_CONCAT_HELPER(x, y)
-#define QTC_SCOPED_TIMER() ::Utils::ScopedTimer QTC_CONCAT(_qtc_scoped_timer_, __LINE__)(__FILE__, __LINE__)
diff --git a/src/libs/utils/scopedtimer.cpp b/src/libs/utils/scopedtimer.cpp
new file mode 100644
index 0000000000..97b8beffda
--- /dev/null
+++ b/src/libs/utils/scopedtimer.cpp
@@ -0,0 +1,64 @@
+// 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 <QByteArray>
+#include <QDebug>
+#include <QTime>
+
+#include <chrono>
+
+namespace Utils {
+
+static QString currentTime() { return QTime::currentTime().toString(Qt::ISODateWithMs); }
+
+using namespace std::chrono;
+
+class ScopedTimerPrivate
+{
+public:
+ const char *m_fileName = nullptr;
+ const int m_line = 0;
+ std::atomic<int64_t> *m_cumulative = nullptr;
+ const time_point<system_clock, nanoseconds> m_start = system_clock::now();
+};
+
+static const char s_scoped[] = "SCOPED TIMER";
+static const char s_scopedCumulative[] = "STATIC SCOPED TIMER";
+
+ScopedTimer::ScopedTimer(const char *fileName, int line, std::atomic<int64_t> *cumulative)
+ : d(new ScopedTimerPrivate{fileName, line, cumulative})
+{
+ if (d->m_cumulative)
+ return;
+ qDebug().noquote().nospace() << s_scoped << " [" << currentTime() << "] in " << d->m_fileName
+ << ':' << d->m_line << " 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_cumulative) {
+ const int64_t nsOld = d->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";
+ }
+ const char *header = d->m_cumulative ? s_scopedCumulative : s_scoped;
+ qDebug().noquote().nospace() << header << " [" << currentTime() << "] in " << d->m_fileName
+ << ':' << d->m_line << suffix;
+}
+
+} // namespace Utils
diff --git a/src/libs/utils/scopedtimer.h b/src/libs/utils/scopedtimer.h
new file mode 100644
index 0000000000..e6ec42e6f4
--- /dev/null
+++ b/src/libs/utils/scopedtimer.h
@@ -0,0 +1,38 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "utils_global.h"
+
+#include <atomic>
+#include <memory>
+
+namespace Utils {
+
+class ScopedTimerPrivate;
+
+class QTCREATOR_UTILS_EXPORT ScopedTimer
+{
+public:
+ ScopedTimer(const char *fileName, int line, std::atomic<int64_t> *cumulative = nullptr);
+ ~ScopedTimer();
+
+private:
+ std::unique_ptr<ScopedTimerPrivate> d;
+};
+
+} // Utils
+
+#define QTC_CONCAT_HELPER(x, y) x ## y
+#define QTC_CONCAT(x, y) QTC_CONCAT_HELPER(x, y)
+#define QTC_SCOPED_TIMER() ::Utils::ScopedTimer QTC_CONCAT(_qtc_scoped_timer_, __LINE__)\
+(__FILE__, __LINE__)
+
+// The macro below expands as follows (in one line):
+// static std::atomic<int64_t> _qtc_static_scoped_timer___LINE__ = 0;
+// ScopedTimer _qtc_scoped_timer___LINE__(__FILE__, __LINE__, &_qtc_static_scoped_timer___LINE__)
+#define QTC_STATIC_SCOPED_TIMER() static std::atomic<int64_t> \
+QTC_CONCAT(_qtc_static_scoped_timer_, __LINE__) = 0; \
+::Utils::ScopedTimer QTC_CONCAT(_qtc_scoped_timer_, __LINE__)\
+(__FILE__, __LINE__, &QTC_CONCAT(_qtc_static_scoped_timer_, __LINE__))
diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs
index fa766b8bc4..f1940a053d 100644
--- a/src/libs/utils/utils.qbs
+++ b/src/libs/utils/utils.qbs
@@ -275,6 +275,8 @@ Project {
"savefile.cpp",
"savefile.h",
"scopedswap.h",
+ "scopedtimer.cpp",
+ "scopedtimer.h",
"searchresultitem.cpp",
"searchresultitem.h",
"set_algorithm.h",