PerfProfiler: Support context switch events

Change-Id: I328b518cc3674ee26975edf26d40057ceb2c21a2
Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
This commit is contained in:
Ulf Hermann
2019-05-02 16:40:56 +02:00
parent 3830619cc8
commit e5ee202f85
5 changed files with 32 additions and 2 deletions

View File

@@ -50,7 +50,8 @@ public:
ThreadStartTypeId = -2, ThreadStartTypeId = -2,
ThreadEndTypeId = -3, ThreadEndTypeId = -3,
LostTypeId = -4, LostTypeId = -4,
LastSpecialTypeId = -5 ContextSwitchTypeId = -5,
LastSpecialTypeId = -256
}; };
const QVector<qint32> &origFrames() const { return m_origFrames; } const QVector<qint32> &origFrames() const { return m_origFrames; }
@@ -72,6 +73,9 @@ public:
quint8 feature() const { return m_feature; } quint8 feature() const { return m_feature; }
quint8 extra() const { return m_extra; }
void setExtra(quint8 extra) { m_extra = extra; }
private: private:
friend QDataStream &operator>>(QDataStream &stream, PerfEvent &event); friend QDataStream &operator>>(QDataStream &stream, PerfEvent &event);
friend QDataStream &operator<<(QDataStream &stream, const PerfEvent &event); friend QDataStream &operator<<(QDataStream &stream, const PerfEvent &event);
@@ -86,6 +90,7 @@ private:
quint8 m_origNumGuessedFrames = 0; quint8 m_origNumGuessedFrames = 0;
quint8 m_numGuessedFrames = 0; quint8 m_numGuessedFrames = 0;
quint8 m_feature = PerfEventType::InvalidFeature; quint8 m_feature = PerfEventType::InvalidFeature;
quint8 m_extra = 0;
}; };
inline QDataStream &operator>>(QDataStream &stream, PerfEvent &event) inline QDataStream &operator>>(QDataStream &stream, PerfEvent &event)
@@ -109,6 +114,7 @@ inline QDataStream &operator>>(QDataStream &stream, PerfEvent &event)
case PerfEventType::Sample43: case PerfEventType::Sample43:
case PerfEventType::Sample: case PerfEventType::Sample:
case PerfEventType::TracePointSample: case PerfEventType::TracePointSample:
case PerfEventType::ContextSwitchDefinition:
break; break;
case PerfEventType::InvalidFeature: case PerfEventType::InvalidFeature:
QTC_ASSERT(false, return stream); QTC_ASSERT(false, return stream);
@@ -130,6 +136,12 @@ inline QDataStream &operator>>(QDataStream &stream, PerfEvent &event)
case PerfEventType::LostDefinition: case PerfEventType::LostDefinition:
event.setTypeIndex(PerfEvent::LostTypeId); event.setTypeIndex(PerfEvent::LostTypeId);
break; break;
case PerfEventType::ContextSwitchDefinition:
event.setTypeIndex(PerfEvent::ContextSwitchTypeId);
bool isSwitchOut;
stream >> isSwitchOut;
event.setExtra(isSwitchOut);
break;
default: { default: {
qint32 typeIndex; qint32 typeIndex;
stream >> event.m_origFrames >> event.m_origNumGuessedFrames >> typeIndex; stream >> event.m_origFrames >> event.m_origNumGuessedFrames >> typeIndex;
@@ -155,6 +167,9 @@ inline QDataStream &operator<<(QDataStream &stream, const PerfEvent &event)
case PerfEventType::ThreadEnd: case PerfEventType::ThreadEnd:
case PerfEventType::LostDefinition: case PerfEventType::LostDefinition:
break; break;
case PerfEventType::ContextSwitchDefinition:
stream << bool(event.extra());
break;
case PerfEventType::Sample43: case PerfEventType::Sample43:
case PerfEventType::Sample: case PerfEventType::Sample:
case PerfEventType::TracePointSample: case PerfEventType::TracePointSample:

View File

@@ -55,6 +55,7 @@ public:
TracePointFormat, TracePointFormat,
TracePointSample, TracePointSample,
AttributesDefinition, AttributesDefinition,
ContextSwitchDefinition,
InvalidFeature InvalidFeature
}; };
@@ -66,7 +67,8 @@ public:
static quint64 metaFeatures() static quint64 metaFeatures()
{ {
return (1ull << ThreadStart) | (1ull << ThreadEnd) | (1ull << LostDefinition); return (1ull << ThreadStart) | (1ull << ThreadEnd) | (1ull << LostDefinition)
| (1ull << ContextSwitchDefinition);
} }
static quint64 locationFeatures() static quint64 locationFeatures()
@@ -143,6 +145,7 @@ public:
case ThreadStart: case ThreadStart:
case ThreadEnd: case ThreadEnd:
case LostDefinition: case LostDefinition:
case ContextSwitchDefinition:
return true; return true;
default: default:
return false; return false;

View File

@@ -237,6 +237,7 @@ void PerfProfilerTraceFile::readMessages(const QByteArray &buffer)
case PerfEventType::ThreadStart: case PerfEventType::ThreadStart:
case PerfEventType::ThreadEnd: case PerfEventType::ThreadEnd:
case PerfEventType::LostDefinition: case PerfEventType::LostDefinition:
case PerfEventType::ContextSwitchDefinition:
if (acceptsSamples()) if (acceptsSamples())
traceManager->appendEvent(std::move(event)); traceManager->appendEvent(std::move(event));
break; break;

View File

@@ -217,6 +217,8 @@ void PerfProfilerTraceManager::resetAttributes()
tr("Thread ended"))); tr("Thread ended")));
setEventType(PerfEvent::LostTypeId, PerfEventType(PerfEventType::LostDefinition, setEventType(PerfEvent::LostTypeId, PerfEventType(PerfEventType::LostDefinition,
tr("Samples lost"))); tr("Samples lost")));
setEventType(PerfEvent::ContextSwitchTypeId,
PerfEventType(PerfEventType::ContextSwitchDefinition, tr("Context switch")));
} }
void PerfProfilerTraceManager::finalize() void PerfProfilerTraceManager::finalize()

View File

@@ -198,6 +198,10 @@ QVariantMap PerfTimelineModel::details(int index) const
result.insert(tr("Details"), tr("lost sample")); result.insert(tr("Details"), tr("lost sample"));
result.insert(tr("Timestamp"), Timeline::formatTime(startTime(index), result.insert(tr("Timestamp"), Timeline::formatTime(startTime(index),
manager->traceDuration())); manager->traceDuration()));
} else if (typeId == PerfEvent::ContextSwitchTypeId) {
result.insert(tr("Details"), tr("context switch"));
result.insert(tr("Timestamp"), Timeline::formatTime(startTime(index),
manager->traceDuration()));
} else { } else {
const PerfProfilerTraceManager::Symbol &symbol const PerfProfilerTraceManager::Symbol &symbol
= manager->symbol(manager->aggregateAddresses() = manager->symbol(manager->aggregateAddresses()
@@ -438,6 +442,11 @@ void PerfTimelineModel::loadEvent(const PerfEvent &event, int numConcurrentThrea
addSample(guessed, 0, 0); addSample(guessed, 0, 0);
break; break;
} }
case PerfEvent::ContextSwitchTypeId: {
const int id = TimelineModel::insert(event.timestamp(), 1, PerfEvent::ContextSwitchTypeId);
m_data.insert(id, StackFrame::sampleFrame());
break;
}
case PerfEvent::ThreadStartTypeId: { case PerfEvent::ThreadStartTypeId: {
if (m_threadStartTimestamp < 0 || event.timestamp() <= m_threadStartTimestamp) if (m_threadStartTimestamp < 0 || event.timestamp() <= m_threadStartTimestamp)
m_threadStartTimestamp = event.timestamp() - 1; m_threadStartTimestamp = event.timestamp() - 1;