summaryrefslogtreecommitdiff
path: root/simpleperf/record.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2021-11-10 15:57:29 -0800
committerYabin Cui <yabinc@google.com>2021-11-10 15:59:38 -0800
commit5dfca1bf880f3c5e0bc434d280490c7eb1b5d7e6 (patch)
tree31a62ebe0a94bbf5e9d49f8588f4a63581c3f540 /simpleperf/record.cpp
parentaed7fb69f3cf91824282cd6bebcce35c54876b33 (diff)
downloadextras-5dfca1bf880f3c5e0bc434d280490c7eb1b5d7e6.tar.gz
simpleperf: record switch records when --trace-offcpu is used.
It can be used to build pure offcpu graph. Bug: 38383695 Test: run simpleperf_unit_test Change-Id: Ic872a3b37b9a9fa1f8195042218076a1368d796d
Diffstat (limited to 'simpleperf/record.cpp')
-rw-r--r--simpleperf/record.cpp42
1 files changed, 34 insertions, 8 deletions
diff --git a/simpleperf/record.cpp b/simpleperf/record.cpp
index 218147b1..2c904d83 100644
--- a/simpleperf/record.cpp
+++ b/simpleperf/record.cpp
@@ -45,6 +45,8 @@ static std::string RecordTypeToString(int record_type) {
{PERF_RECORD_BUILD_ID, "build_id"},
{PERF_RECORD_MMAP2, "mmap2"},
{PERF_RECORD_AUX, "aux"},
+ {PERF_RECORD_SWITCH, "switch"},
+ {PERF_RECORD_SWITCH_CPU_WIDE, "switch_cpu_wide"},
{PERF_RECORD_TRACING_DATA, "tracing_data"},
{PERF_RECORD_AUXTRACE_INFO, "auxtrace_info"},
{PERF_RECORD_AUXTRACE, "auxtrace"},
@@ -186,7 +188,7 @@ Record::Record(Record&& other) noexcept {
}
void Record::Dump(size_t indent) const {
- PrintIndented(indent, "record %s: type %u, misc %u, size %u\n",
+ PrintIndented(indent, "record %s: type %u, misc 0x%x, size %u\n",
RecordTypeToString(type()).c_str(), type(), misc(), size());
DumpData(indent + 1);
sample_id.Dump(indent + 1);
@@ -884,6 +886,27 @@ void AuxRecord::DumpData(size_t indent) const {
PrintIndented(indent, "flags 0x%" PRIx64 "\n", data->flags);
}
+SwitchRecord::SwitchRecord(const perf_event_attr& attr, char* p) : Record(p) {
+ const char* end = p + size();
+ p += header_size();
+ sample_id.ReadFromBinaryFormat(attr, p, end);
+}
+
+SwitchCpuWideRecord::SwitchCpuWideRecord(const perf_event_attr& attr, char* p) : Record(p) {
+ const char* end = p + size();
+ p += header_size();
+ MoveFromBinaryFormat(tid_data, p);
+ sample_id.ReadFromBinaryFormat(attr, p, end);
+}
+
+void SwitchCpuWideRecord::DumpData(size_t indent) const {
+ if (header.misc & PERF_RECORD_MISC_SWITCH_OUT) {
+ PrintIndented(indent, "next_pid %u, next_tid %u\n", tid_data.pid, tid_data.tid);
+ } else {
+ PrintIndented(indent, "prev_pid %u, prev_tid %u\n", tid_data.pid, tid_data.tid);
+ }
+}
+
BuildIdRecord::BuildIdRecord(char* p) : Record(p) {
const char* end = p + size();
p += header_size();
@@ -938,8 +961,7 @@ AuxTraceInfoRecord::AuxTraceInfoRecord(char* p) : Record(p) {
CHECK_EQ(p, end);
}
-AuxTraceInfoRecord::AuxTraceInfoRecord(const DataType& data,
- const std::vector<ETEInfo>& ete_info) {
+AuxTraceInfoRecord::AuxTraceInfoRecord(const DataType& data, const std::vector<ETEInfo>& ete_info) {
SetTypeAndMisc(PERF_RECORD_AUXTRACE_INFO, 0);
uint32_t size = header_size() + sizeof(DataType);
@@ -972,11 +994,11 @@ void AuxTraceInfoRecord::DumpData(size_t indent) const {
PrintIndented(indent, "pmu_type %u\n", data->pmu_type);
PrintIndented(indent, "snapshot %" PRIu64 "\n", data->snapshot);
indent++;
- uint64_t *info = data->info;
+ uint64_t* info = data->info;
for (int i = 0; i < data->nr_cpu; i++) {
if (info[0] == MAGIC_ETM4) {
- ETM4Info &e = *reinterpret_cast<ETM4Info *>(info);
+ ETM4Info& e = *reinterpret_cast<ETM4Info*>(info);
PrintIndented(indent, "magic 0x%" PRIx64 "\n", e.magic);
PrintIndented(indent, "cpu %" PRIu64 "\n", e.cpu);
PrintIndented(indent, "nrtrcparams %" PRIu64 "\n", e.nrtrcparams);
@@ -987,10 +1009,10 @@ void AuxTraceInfoRecord::DumpData(size_t indent) const {
PrintIndented(indent, "trcidr2 0x%" PRIx64 "\n", e.trcidr2);
PrintIndented(indent, "trcidr8 0x%" PRIx64 "\n", e.trcidr8);
PrintIndented(indent, "trcauthstatus 0x%" PRIx64 "\n", e.trcauthstatus);
- info = reinterpret_cast<uint64_t *>(&e + 1);
+ info = reinterpret_cast<uint64_t*>(&e + 1);
} else {
CHECK_EQ(info[0], MAGIC_ETE);
- ETEInfo &e = *reinterpret_cast<ETEInfo *>(info);
+ ETEInfo& e = *reinterpret_cast<ETEInfo*>(info);
PrintIndented(indent, "magic 0x%" PRIx64 "\n", e.magic);
PrintIndented(indent, "cpu %" PRIu64 "\n", e.cpu);
PrintIndented(indent, "nrtrcparams %" PRIu64 "\n", e.nrtrcparams);
@@ -1002,7 +1024,7 @@ void AuxTraceInfoRecord::DumpData(size_t indent) const {
PrintIndented(indent, "trcidr8 0x%" PRIx64 "\n", e.trcidr8);
PrintIndented(indent, "trcauthstatus 0x%" PRIx64 "\n", e.trcauthstatus);
PrintIndented(indent, "trcdevarch 0x%" PRIx64 "\n", e.trcdevarch);
- info = reinterpret_cast<uint64_t *>(&e + 1);
+ info = reinterpret_cast<uint64_t*>(&e + 1);
}
}
}
@@ -1410,6 +1432,10 @@ std::unique_ptr<Record> ReadRecordFromBuffer(const perf_event_attr& attr, uint32
return std::unique_ptr<Record>(new SampleRecord(attr, p));
case PERF_RECORD_AUX:
return std::unique_ptr<Record>(new AuxRecord(attr, p));
+ case PERF_RECORD_SWITCH:
+ return std::unique_ptr<Record>(new SwitchRecord(attr, p));
+ case PERF_RECORD_SWITCH_CPU_WIDE:
+ return std::unique_ptr<Record>(new SwitchCpuWideRecord(attr, p));
case PERF_RECORD_TRACING_DATA:
return std::unique_ptr<Record>(new TracingDataRecord(p));
case PERF_RECORD_AUXTRACE_INFO: