forked from qt-creator/qt-creator
ScopedTimer: Make it possible to provide optional message string
When optional message argument is provided, both macros print the message instead of __FILE__ and __LINE__ info. It helps to ease the identification of the exact place in code when many macros are added - custom message may be more informative that the file and line location. Change-Id: I7a3ccbdaca2858b44dcbd51a8f9330160dab73e9 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include "scopedtimer.h"
|
#include "scopedtimer.h"
|
||||||
|
|
||||||
#include <QByteArray>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
@@ -15,25 +14,31 @@ static QString currentTime() { return QTime::currentTime().toString(Qt::ISODateW
|
|||||||
|
|
||||||
using namespace std::chrono;
|
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_scoped[] = "SCOPED TIMER";
|
||||||
static const char s_scopedCumulative[] = "STATIC SCOPED TIMER";
|
static const char s_scopedCumulative[] = "STATIC SCOPED TIMER";
|
||||||
|
|
||||||
ScopedTimer::ScopedTimer(const char *fileName, int line, std::atomic<int64_t> *cumulative)
|
class ScopedTimerPrivate
|
||||||
: d(new ScopedTimerPrivate{fileName, line, cumulative})
|
|
||||||
{
|
{
|
||||||
if (d->m_cumulative)
|
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;
|
return;
|
||||||
qDebug().noquote().nospace() << s_scoped << " [" << currentTime() << "] in " << d->m_fileName
|
qDebug().noquote().nospace() << d->header() << "started";
|
||||||
<< ':' << d->m_line << " started";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t toMs(int64_t ns) { return ns / 1000000; }
|
static int64_t toMs(int64_t ns) { return ns / 1000000; }
|
||||||
@@ -42,8 +47,8 @@ ScopedTimer::~ScopedTimer()
|
|||||||
{
|
{
|
||||||
const auto elapsed = duration_cast<nanoseconds>(system_clock::now() - d->m_start);
|
const auto elapsed = duration_cast<nanoseconds>(system_clock::now() - d->m_start);
|
||||||
QString suffix;
|
QString suffix;
|
||||||
if (d->m_cumulative) {
|
if (d->m_data.m_cumulative) {
|
||||||
const int64_t nsOld = d->m_cumulative->fetch_add(elapsed.count());
|
const int64_t nsOld = d->m_data.m_cumulative->fetch_add(elapsed.count());
|
||||||
const int64_t msOld = toMs(nsOld);
|
const int64_t msOld = toMs(nsOld);
|
||||||
const int64_t nsNew = nsOld + elapsed.count();
|
const int64_t nsNew = nsOld + elapsed.count();
|
||||||
const int64_t msNew = toMs(nsNew);
|
const int64_t msNew = toMs(nsNew);
|
||||||
@@ -52,13 +57,11 @@ ScopedTimer::~ScopedTimer()
|
|||||||
if (nsOld != 0 && msOld / 10 == msNew / 10)
|
if (nsOld != 0 && msOld / 10 == msNew / 10)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
suffix = " cumulative timeout: " + QString::number(msNew) + "ms";
|
suffix = "cumulative timeout: " + QString::number(msNew) + "ms";
|
||||||
} else {
|
} else {
|
||||||
suffix = " stopped with timeout: " + QString::number(toMs(elapsed.count())) + "ms";
|
suffix = "stopped with timeout: " + QString::number(toMs(elapsed.count())) + "ms";
|
||||||
}
|
}
|
||||||
const char *header = d->m_cumulative ? s_scopedCumulative : s_scoped;
|
qDebug().noquote().nospace() << d->header() << suffix;
|
||||||
qDebug().noquote().nospace() << header << " [" << currentTime() << "] in " << d->m_fileName
|
|
||||||
<< ':' << d->m_line << suffix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "utils_global.h"
|
#include "utils_global.h"
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -12,10 +14,19 @@ namespace Utils {
|
|||||||
|
|
||||||
class ScopedTimerPrivate;
|
class ScopedTimerPrivate;
|
||||||
|
|
||||||
|
class QTCREATOR_UTILS_EXPORT ScopedTimerData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString m_message;
|
||||||
|
const char *m_fileName = nullptr;
|
||||||
|
int m_line = 0;
|
||||||
|
std::atomic<int64_t> *m_cumulative = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
class QTCREATOR_UTILS_EXPORT ScopedTimer
|
class QTCREATOR_UTILS_EXPORT ScopedTimer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScopedTimer(const char *fileName, int line, std::atomic<int64_t> *cumulative = nullptr);
|
ScopedTimer(const ScopedTimerData &data);
|
||||||
~ScopedTimer();
|
~ScopedTimer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -24,15 +35,18 @@ private:
|
|||||||
|
|
||||||
} // Utils
|
} // Utils
|
||||||
|
|
||||||
|
// The "message" argument of QTC_SCOPED_TIMER() and QTC_STATIC_SCOPED_TIMER() macros is optional.
|
||||||
|
// When provided, it should evaluate to QString.
|
||||||
|
|
||||||
#define QTC_CONCAT_HELPER(x, y) x ## y
|
#define QTC_CONCAT_HELPER(x, y) x ## y
|
||||||
#define QTC_CONCAT(x, y) QTC_CONCAT_HELPER(x, y)
|
#define QTC_CONCAT(x, y) QTC_CONCAT_HELPER(x, y)
|
||||||
#define QTC_SCOPED_TIMER() ::Utils::ScopedTimer QTC_CONCAT(_qtc_scoped_timer_, __LINE__)\
|
#define QTC_SCOPED_TIMER(message) ::Utils::ScopedTimer QTC_CONCAT(_qtc_scoped_timer_, __LINE__)\
|
||||||
(__FILE__, __LINE__)
|
({{message}, __FILE__, __LINE__})
|
||||||
|
|
||||||
// The macro below expands as follows (in one line):
|
// The macro below expands as follows (in one line):
|
||||||
// static std::atomic<int64_t> _qtc_static_scoped_timer___LINE__ = 0;
|
// static std::atomic<int64_t> _qtc_static_scoped_timer___LINE__ = 0;
|
||||||
// ScopedTimer _qtc_scoped_timer___LINE__(__FILE__, __LINE__, &_qtc_static_scoped_timer___LINE__)
|
// ScopedTimer _qtc_scoped_timer___LINE__(__FILE__, __LINE__, &_qtc_static_scoped_timer___LINE__)
|
||||||
#define QTC_STATIC_SCOPED_TIMER() static std::atomic<int64_t> \
|
#define QTC_STATIC_SCOPED_TIMER(message) static std::atomic<int64_t> \
|
||||||
QTC_CONCAT(_qtc_static_scoped_timer_, __LINE__) = 0; \
|
QTC_CONCAT(_qtc_static_scoped_timer_, __LINE__) = 0; \
|
||||||
::Utils::ScopedTimer QTC_CONCAT(_qtc_scoped_timer_, __LINE__)\
|
::Utils::ScopedTimer QTC_CONCAT(_qtc_scoped_timer_, __LINE__)\
|
||||||
(__FILE__, __LINE__, &QTC_CONCAT(_qtc_static_scoped_timer_, __LINE__))
|
({{message}, __FILE__, __LINE__, &QTC_CONCAT(_qtc_static_scoped_timer_, __LINE__)})
|
||||||
|
Reference in New Issue
Block a user