CtfVisualizer: Allow strings for process and thread id

While the format document only uses numbers for these in its examples,
the data type is not really specified there and chrome://tracing itself
handles strings for them without complaint. On trace-generating side
std:🧵:id can't easily be serialized as a number, and strings can
easily be supported in the viewer.

Change-Id: I36c8497049d4933058b9f72a28f24e1d1cf0d5bb
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Eike Ziller
2023-09-08 10:17:29 +02:00
parent 67aab38873
commit c83047abb9
5 changed files with 48 additions and 32 deletions

View File

@@ -23,15 +23,17 @@ using json = nlohmann::json;
using namespace Constants; using namespace Constants;
CtfTimelineModel::CtfTimelineModel(Timeline::TimelineModelAggregator *parent, CtfTimelineModel::CtfTimelineModel(Timeline::TimelineModelAggregator *parent,
CtfTraceManager *traceManager, int tid, int pid) CtfTraceManager *traceManager,
: Timeline::TimelineModel (parent) const QString &tid,
const QString &pid)
: Timeline::TimelineModel(parent)
, m_traceManager(traceManager) , m_traceManager(traceManager)
, m_threadId(tid) , m_threadId(tid)
, m_processId(pid) , m_processId(pid)
{ {
updateName(); updateName();
setCollapsedRowCount(1); setCollapsedRowCount(1);
setCategoryColor(colorByHue(pid * 25)); setCategoryColor(colorByHue(qHash(pid)));
setHasMixedTypesInExpandedState(true); setHasMixedTypesInExpandedState(true);
} }
@@ -199,7 +201,7 @@ void CtfTimelineModel::finalize(double traceBegin, double traceEnd, const QStrin
emit contentChanged(); emit contentChanged();
} }
int CtfTimelineModel::tid() const QString CtfTimelineModel::tid() const
{ {
return m_threadId; return m_threadId;
} }
@@ -218,13 +220,13 @@ void CtfTimelineModel::updateName()
if (m_threadName.isEmpty()) { if (m_threadName.isEmpty()) {
setDisplayName(Tr::tr("Thread %1").arg(m_threadId)); setDisplayName(Tr::tr("Thread %1").arg(m_threadId));
} else { } else {
setDisplayName(QString("%1 (%2)").arg(m_threadName).arg(m_threadId)); setDisplayName(QString("%1 (%2)").arg(m_threadName, m_threadId));
} }
QString process = m_processName.isEmpty() ? QString::number(m_processId) : QString process = m_processName.isEmpty() ? m_processId
QString("%1 (%2)").arg(m_processName).arg(m_processId); : QString("%1 (%2)").arg(m_processName, m_processId);
QString thread = m_threadName.isEmpty() ? QString::number(m_threadId) : QString thread = m_threadName.isEmpty() ? m_threadId
QString("%1 (%2)").arg(m_threadName).arg(m_threadId); : QString("%1 (%2)").arg(m_threadName, m_threadId);
setTooltip(QString("Process: %1\nThread: %2").arg(process).arg(thread)); setTooltip(QString("Process: %1\nThread: %2").arg(process, thread));
} }
qint64 CtfTimelineModel::newStackEvent(const json &event, qint64 normalizedTime, qint64 CtfTimelineModel::newStackEvent(const json &event, qint64 normalizedTime,

View File

@@ -28,7 +28,9 @@ class CtfTimelineModel : public Timeline::TimelineModel
public: public:
explicit CtfTimelineModel(Timeline::TimelineModelAggregator *parent, explicit CtfTimelineModel(Timeline::TimelineModelAggregator *parent,
CtfTraceManager *traceManager, int tid, int pid); CtfTraceManager *traceManager,
const QString &tid,
const QString &pid);
QRgb color(int index) const override; QRgb color(int index) const override;
QVariantList labels() const override; QVariantList labels() const override;
@@ -44,7 +46,7 @@ public:
void finalize(double traceBegin, double traceEnd, const QString &processName, const QString &threadName); void finalize(double traceBegin, double traceEnd, const QString &processName, const QString &threadName);
int tid() const; QString tid() const;
QString eventTitle(int index) const; QString eventTitle(int index) const;
signals: signals:
@@ -65,9 +67,9 @@ private:
protected: protected:
CtfTraceManager *const m_traceManager; CtfTraceManager *const m_traceManager;
int m_threadId; QString m_threadId;
QString m_threadName; QString m_threadName;
int m_processId; QString m_processId;
QString m_processName; QString m_processName;
int m_maxStackSize = 0; int m_maxStackSize = 0;

View File

@@ -105,8 +105,19 @@ void CtfTraceManager::addEvent(const json &event)
m_timeOffset = timestamp; m_timeOffset = timestamp;
} }
const int processId = event.value(CtfProcessIdKey, 0); static const auto getStringValue = [](const json &event, const char *key, const QString &def) {
const int threadId = event.contains(CtfThreadIdKey) ? int(event[CtfThreadIdKey]) : processId; if (!event.contains(key))
return def;
const json val = event[key];
if (val.is_string())
return QString::fromStdString(val);
if (val.is_number()) {
return QString::number(int(val));
}
return def;
};
const QString processId = getStringValue(event, CtfProcessIdKey, "0");
const QString threadId = getStringValue(event, CtfThreadIdKey, processId);
if (!m_threadModels.contains(threadId)) { if (!m_threadModels.contains(threadId)) {
addModelForThread(threadId, processId); addModelForThread(threadId, processId);
} }
@@ -202,14 +213,16 @@ int CtfTraceManager::getSelectionId(const std::string &name)
QList<CtfTimelineModel *> CtfTraceManager::getSortedThreads() const QList<CtfTimelineModel *> CtfTraceManager::getSortedThreads() const
{ {
QList<CtfTimelineModel *> models = m_threadModels.values(); QList<CtfTimelineModel *> models = m_threadModels.values();
std::sort(models.begin(), models.end(), [](const CtfTimelineModel *a, const CtfTimelineModel *b) -> bool { std::sort(models.begin(),
return (a->m_processId != b->m_processId) ? (a->m_processId < b->m_processId) models.end(),
: (std::abs(a->m_threadId) < std::abs(b->m_threadId)); [](const CtfTimelineModel *a, const CtfTimelineModel *b) -> bool {
}); return (a->m_processId != b->m_processId) ? (a->m_processId < b->m_processId)
: (a->m_threadId < b->m_threadId);
});
return models; return models;
} }
void CtfTraceManager::setThreadRestriction(int tid, bool restrictToThisThread) void CtfTraceManager::setThreadRestriction(const QString &tid, bool restrictToThisThread)
{ {
if (m_threadRestrictions.value(tid) == restrictToThisThread) if (m_threadRestrictions.value(tid) == restrictToThisThread)
return; return;
@@ -218,12 +231,12 @@ void CtfTraceManager::setThreadRestriction(int tid, bool restrictToThisThread)
addModelsToAggregator(); addModelsToAggregator();
} }
bool CtfTraceManager::isRestrictedTo(int tid) const bool CtfTraceManager::isRestrictedTo(const QString &tid) const
{ {
return m_threadRestrictions.value(tid); return m_threadRestrictions.value(tid);
} }
void CtfTraceManager::addModelForThread(int threadId, int processId) void CtfTraceManager::addModelForThread(const QString &threadId, const QString &processId)
{ {
CtfTimelineModel *model = new CtfTimelineModel(m_modelAggregator, this, threadId, processId); CtfTimelineModel *model = new CtfTimelineModel(m_modelAggregator, this, threadId, processId);
m_threadModels.insert(threadId, model); m_threadModels.insert(threadId, model);

View File

@@ -43,15 +43,14 @@ public:
QList<CtfTimelineModel *> getSortedThreads() const; QList<CtfTimelineModel *> getSortedThreads() const;
void setThreadRestriction(int tid, bool restrictToThisThread); void setThreadRestriction(const QString &tid, bool restrictToThisThread);
bool isRestrictedTo(int tid) const; bool isRestrictedTo(const QString &tid) const;
signals: signals:
void detailsRequested(const QString &title); void detailsRequested(const QString &title);
protected: protected:
void addModelForThread(const QString &threadId, const QString &processId);
void addModelForThread(int threadId, int processId);
void addModelsToAggregator(); void addModelsToAggregator();
void updateStatistics(); void updateStatistics();
@@ -61,11 +60,11 @@ protected:
Timeline::TimelineModelAggregator *const m_modelAggregator; Timeline::TimelineModelAggregator *const m_modelAggregator;
CtfStatisticsModel *const m_statisticsModel; CtfStatisticsModel *const m_statisticsModel;
QHash<qint64, CtfTimelineModel *> m_threadModels; QHash<QString, CtfTimelineModel *> m_threadModels;
QHash<qint64, QString> m_processNames; QHash<QString, QString> m_processNames;
QHash<qint64, QString> m_threadNames; QHash<QString, QString> m_threadNames;
QMap<std::string, int> m_name2selectionId; QMap<std::string, int> m_name2selectionId;
QHash<qint64, bool> m_threadRestrictions; QHash<QString, bool> m_threadRestrictions;
double m_traceBegin = std::numeric_limits<double>::max(); double m_traceBegin = std::numeric_limits<double>::max();
double m_traceEnd = std::numeric_limits<double>::min(); double m_traceEnd = std::numeric_limits<double>::min();

View File

@@ -123,7 +123,7 @@ void CtfVisualizerTool::setAvailableThreads(const QList<CtfTimelineModel *> &thr
void CtfVisualizerTool::toggleThreadRestriction(QAction *action) void CtfVisualizerTool::toggleThreadRestriction(QAction *action)
{ {
const int tid = action->data().toInt(); const QString tid = action->data().toString();
m_traceManager->setThreadRestriction(tid, action->isChecked()); m_traceManager->setThreadRestriction(tid, action->isChecked());
} }