Skip to content

Commit 84d7904

Browse files
committed
always show all costs
since we now have one line per cost there is no need to hide some costs
1 parent 2a10dc2 commit 84d7904

File tree

6 files changed

+84
-32
lines changed

6 files changed

+84
-32
lines changed

src/models/data.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,3 +398,15 @@ const Data::ThreadEvents* Data::EventResults::findThread(qint32 pid, qint32 tid)
398398
{
399399
return const_cast<Data::EventResults*>(this)->findThread(pid, tid);
400400
}
401+
402+
const Data::ThreadEvents* Data::EventResults::findThread(qint32 pid, qint32 tid, qint32 costId) const
403+
{
404+
for (int i = threads.size() - 1; i >= 0; --i) {
405+
auto& thread = threads[i];
406+
if (thread.pid == pid && thread.tid == tid && thread.events[0].type == costId) {
407+
return &thread;
408+
}
409+
}
410+
411+
return nullptr;
412+
}

src/models/data.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,7 @@ struct EventResults
855855

856856
ThreadEvents* findThread(qint32 pid, qint32 tid);
857857
const ThreadEvents* findThread(qint32 pid, qint32 tid) const;
858+
const ThreadEvents* findThread(qint32 pid, qint32 tid, qint32 costId) const;
858859

859860
bool operator==(const EventResults& rhs) const
860861
{

src/models/eventmodel.cpp

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,15 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
210210
quint64 maxRuntime = 0;
211211
quint64 offCpuTime = 0;
212212
quint64 numEvents = 0;
213-
for (const auto tid : process.threads) {
214-
const auto thread = m_data.findThread(process.pid, tid);
215-
Q_ASSERT(thread);
216-
runtime += thread->time.delta();
217-
maxRuntime = std::max(thread->time.delta(), maxRuntime);
218-
offCpuTime += thread->offCpuTime;
219-
numEvents += thread->events.size();
213+
for (const auto tidCostId : process.threads) {
214+
for (const auto& thread : m_data.threads) {
215+
if (thread.tid == tidCostId.tid) {
216+
runtime += thread.time.delta();
217+
maxRuntime = std::max(thread.time.delta(), maxRuntime);
218+
offCpuTime += thread.offCpuTime;
219+
numEvents += thread.events.size();
220+
}
221+
}
220222
}
221223

222224
const auto totalRuntime = m_time.delta();
@@ -249,8 +251,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
249251
cpu = &m_data.cpus[index.row()];
250252
} else if (tag == Tag::Threads) {
251253
const auto process = m_processes.value(tagData(index.internalId()));
252-
const auto tid = process.threads.value(index.row());
253-
thread = m_data.findThread(process.pid, tid);
254+
const auto tid = process.threads[index.row()].tid;
255+
const auto costId = process.threads[index.row()].costId;
256+
thread = m_data.findThread(process.pid, tid, costId);
254257
Q_ASSERT(thread);
255258
} else if (tag == Tag::Tracepoints) {
256259
tracepoint = &m_data.tracepoints[index.row()];
@@ -521,36 +524,68 @@ void EventModel::setData(const Data::EventResults& data)
521524
if (data.threads.isEmpty()) {
522525
m_time = {};
523526
} else {
527+
const auto numCostTypes = m_data.totalCosts.size();
524528
m_time = data.threads.first().time;
529+
m_data.threads.clear();
525530
for (const auto& thread : data.threads) {
526531
m_time.start = std::min(thread.time.start, m_time.start);
527532
m_time.end = std::max(thread.time.end, m_time.end);
528533
m_totalOffCpuTime += thread.offCpuTime;
529534
m_totalOnCpuTime += thread.time.delta() - thread.offCpuTime;
530535
m_totalEvents += thread.events.size();
531536
auto it = std::lower_bound(m_processes.begin(), m_processes.end(), thread.pid, orderProcessByPid);
532-
if (it == m_processes.end() || it->pid != thread.pid) {
533-
m_processes.insert(it, {thread.pid, {thread.tid}, thread.name});
534-
} else {
535-
it->threads.append(thread.tid);
536-
// prefer process name, if we encountered a thread first
537-
if (thread.pid == thread.tid)
538-
it->name = thread.name;
539-
}
540537

541-
for (const auto& event : thread.events) {
542-
if (event.type != 0) {
543-
// TODO: support multiple cost types somehow
544-
continue;
538+
for (int eventType = 0; eventType < numCostTypes; eventType++) {
539+
Data::ThreadEvents event {
540+
thread.pid, thread.tid, thread.time, {}, thread.name, thread.lastSwitchTime,
541+
thread.offCpuTime, thread.state};
542+
543+
std::copy_if(thread.events.cbegin(), thread.events.cend(), std::back_inserter(event.events),
544+
[eventType](const Data::Event& event) { return eventType == event.type; });
545+
546+
if (!event.events.isEmpty()) {
547+
m_data.threads.push_back(event);
548+
if (it == m_processes.end() || it->pid != thread.pid) {
549+
it = m_processes.insert(it, {thread.pid, {{thread.tid, eventType}}, thread.name});
550+
} else {
551+
it->threads.append({thread.tid, eventType});
552+
// prefer process name, if we encountered a thread first
553+
if (thread.pid == thread.tid)
554+
it->name = thread.name;
555+
}
545556
}
546-
m_maxCost = std::max(event.cost, m_maxCost);
557+
}
558+
559+
// TODO: support multiple cost types somehow
560+
if (!thread.events.isEmpty() && thread.events[0].type == 0) {
561+
auto maxElement = std::max_element(thread.events.cbegin(), thread.events.cend(),
562+
[](const auto& a, const auto& b) { return a.cost < b.cost; });
563+
m_maxCost = std::max(maxElement->cost, m_maxCost);
547564
}
548565
}
549566

550567
// don't show timeline for CPU cores that did not receive any events
551568
auto it = std::remove_if(m_data.cpus.begin(), m_data.cpus.end(),
552569
[](const Data::CpuEvents& cpuEvents) { return cpuEvents.events.isEmpty(); });
553570
m_data.cpus.erase(it, m_data.cpus.end());
571+
572+
// split events to that each CpuEvents entry contains only one event type
573+
QVector<Data::CpuEvents> cpuEventsExpanded;
574+
575+
for (const auto& cpu : std::as_const(m_data.cpus)) {
576+
for (int eventType = 0; eventType < numCostTypes; eventType++) {
577+
Data::CpuEvents event;
578+
event.cpuId = cpu.cpuId;
579+
std::copy_if(cpu.events.cbegin(), cpu.events.cend(), std::back_inserter(event.events),
580+
[eventType](const Data::Event& event) { return eventType == event.type; });
581+
582+
if (!event.events.isEmpty()) {
583+
cpuEventsExpanded.append(event);
584+
}
585+
}
586+
}
587+
// Keep the data somehow so that we can show all events if no source is selected
588+
m_data.cpus = cpuEventsExpanded;
554589
}
555590

556591
endResetModel();

src/models/eventmodel.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,20 @@ class EventModel : public QAbstractItemModel
6262

6363
struct Process
6464
{
65-
Process(qint32 pid = Data::INVALID_PID, const QVector<qint32>& threads = {}, const QString& name = {})
65+
struct ThreadIdCostId
66+
{
67+
qint32 tid;
68+
qint32 costId;
69+
};
70+
71+
Process(qint32 pid = Data::INVALID_PID, const QVector<ThreadIdCostId>& threads = {}, const QString& name = {})
6672
: pid(pid)
6773
, threads(threads)
6874
, name(name)
6975
{
7076
}
7177
qint32 pid;
72-
QVector<qint32> threads;
78+
QVector<ThreadIdCostId> threads;
7379
QString name;
7480
};
7581

src/models/timelinedelegate.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ void TimeLineDelegate::paint(QPainter* painter, const QStyleOptionViewItem& opti
161161
const auto results = index.data(EventModel::EventResultsRole).value<Data::EventResults>();
162162
const auto offCpuCostId = results.offCpuTimeCostId;
163163
const auto lostEventCostId = results.lostEventCostId;
164-
const auto tracepointEventCostId = results.tracepointEventCostId;
165164
const bool is_alternate = option.features & QStyleOptionViewItem::Alternate;
166165
const auto& palette = option.palette;
167166

@@ -231,10 +230,6 @@ void TimeLineDelegate::paint(QPainter* painter, const QStyleOptionViewItem& opti
231230
// see also: https://www.spinics.net/lists/linux-perf-users/msg03486.html
232231
for (const auto& event : data.events) {
233232
const auto isLostEvent = event.type == lostEventCostId;
234-
const auto isTracepointEvent = event.type == tracepointEventCostId;
235-
if (event.type != m_eventType && !isLostEvent && !isTracepointEvent) {
236-
continue;
237-
}
238233

239234
const auto x = data.mapTimeToX(event.time);
240235
if (x < TimeLineData::padding || x >= data.w) {

tests/modeltests/tst_models.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,8 @@ private slots:
478478
{
479479
const auto events = createEventModelTestData();
480480
const int nonEmptyCpus = 2;
481-
const int processes = 2;
481+
// there are two in the data, but one does not contain any events, so the proxy filters it out
482+
const int processes = 1;
482483

483484
const quint64 endTime = 1000;
484485

@@ -491,6 +492,8 @@ private slots:
491492

492493
auto simplifiedEvents = events;
493494
simplifiedEvents.cpus.remove(1);
495+
simplifiedEvents.threads.remove(2);
496+
simplifiedEvents.threads.remove(2);
494497

495498
auto verifyCommonData = [&](const QModelIndex& idx) {
496499
const auto eventResults = idx.data(EventModel::EventResultsRole).value<Data::EventResults>();
@@ -502,7 +505,7 @@ private slots:
502505
const auto numProcesses = idx.data(EventModel::NumProcessesRole).value<uint>();
503506
QCOMPARE(numProcesses, processes);
504507
const auto numThreads = idx.data(EventModel::NumThreadsRole).value<uint>();
505-
QCOMPARE(numThreads, events.threads.size());
508+
QCOMPARE(numThreads, simplifiedEvents.threads.size());
506509
const auto numCpus = idx.data(EventModel::NumCpusRole).value<uint>();
507510
QCOMPARE(numCpus, nonEmptyCpus);
508511
const auto maxCost = idx.data(EventModel::MaxCostRole).value<quint64>();
@@ -629,7 +632,7 @@ private slots:
629632
// favorites are still on top
630633
QVERIFY(proxy.index(0, 0, proxy.index(0, 0)).data(EventModel::IsFavoriteRole).toBool());
631634
// followed by processes
632-
QCOMPARE(proxy.index(0, 0, proxy.index(1, 0)).data(EventModel::ProcessIdRole).value<quint32>(), 5678);
635+
QCOMPARE(proxy.index(0, 0, proxy.index(1, 0)).data(EventModel::ProcessIdRole).value<quint32>(), 1234);
633636
}
634637

635638
model.removeFromFavorites(model.index(0, 0, favoritesIndex));

0 commit comments

Comments
 (0)