summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2022-08-29 22:07:26 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-08-29 22:07:26 +0000
commit035545f4caa78e23deae5367487298e21316ec16 (patch)
tree33d3820a92b002325edc4be2783d062bd465379a
parentb6a2b1de22d4691e4372aed5a9a1bc78a7003f4d (diff)
parent7fe23bfc69b5dc53a1328ab3afb43fe83eeb3bd3 (diff)
downloadextras-035545f4caa78e23deae5367487298e21316ec16.tar.gz
Merge "simpleperf: update --print-hw-counter to check each cpu." into android13-tests-dev
-rw-r--r--simpleperf/cmd_stat.cpp27
-rw-r--r--simpleperf/workload.cpp13
-rw-r--r--simpleperf/workload.h1
3 files changed, 33 insertions, 8 deletions
diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp
index 325cb045..56249907 100644
--- a/simpleperf/cmd_stat.cpp
+++ b/simpleperf/cmd_stat.cpp
@@ -739,23 +739,23 @@ bool StatCommand::ParseOptions(const std::vector<std::string>& args,
return true;
}
-bool StatCommand::PrintHardwareCounters() {
+std::optional<size_t> GetHardwareCountersOnCpu(int cpu) {
size_t available_counters = 0;
const EventType* event = FindEventTypeByName("cpu-cycles", true);
if (event == nullptr) {
- return false;
+ return std::nullopt;
}
perf_event_attr attr = CreateDefaultPerfEventAttr(*event);
while (true) {
auto workload = Workload::CreateWorkload({"sleep", "0.1"});
- if (!workload) {
- return false;
+ if (!workload || !workload->SetCpuAffinity(cpu)) {
+ return std::nullopt;
}
std::vector<std::unique_ptr<EventFd>> event_fds;
for (size_t i = 0; i <= available_counters; i++) {
EventFd* group_event_fd = event_fds.empty() ? nullptr : event_fds[0].get();
- auto event_fd =
- EventFd::OpenEventFile(attr, workload->GetPid(), -1, group_event_fd, "cpu-cycles", false);
+ auto event_fd = EventFd::OpenEventFile(attr, workload->GetPid(), cpu, group_event_fd,
+ "cpu-cycles", false);
if (!event_fd) {
break;
}
@@ -771,7 +771,7 @@ bool StatCommand::PrintHardwareCounters() {
for (auto& event_fd : event_fds) {
PerfCounter counter;
if (!event_fd->ReadCounter(&counter)) {
- return false;
+ return std::nullopt;
}
if (counter.time_enabled == 0 || counter.time_enabled > counter.time_running) {
always_running = false;
@@ -783,7 +783,18 @@ bool StatCommand::PrintHardwareCounters() {
}
available_counters++;
}
- printf("There are %zu CPU PMU hardware counters available on this device.\n", available_counters);
+ return available_counters;
+}
+
+bool StatCommand::PrintHardwareCounters() {
+ for (int cpu : GetOnlineCpus()) {
+ std::optional<size_t> counters = GetHardwareCountersOnCpu(cpu);
+ if (!counters) {
+ LOG(ERROR) << "failed to get CPU PMU hardware counters on cpu " << cpu;
+ return false;
+ }
+ printf("There are %zu CPU PMU hardware counters available on cpu %d.\n", counters.value(), cpu);
+ }
return true;
}
diff --git a/simpleperf/workload.cpp b/simpleperf/workload.cpp
index 4bb7c540..142ed713 100644
--- a/simpleperf/workload.cpp
+++ b/simpleperf/workload.cpp
@@ -18,6 +18,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <sched.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <unistd.h>
@@ -160,6 +161,18 @@ void Workload::ChildProcessFn(int start_signal_fd, int exec_child_fd) {
}
}
+bool Workload::SetCpuAffinity(int cpu) {
+ CHECK_EQ(work_state_, NotYetStartNewProcess);
+ cpu_set_t mask;
+ CPU_ZERO(&mask);
+ CPU_SET(cpu, &mask);
+ if (sched_setaffinity(GetPid(), sizeof(mask), &mask) != 0) {
+ PLOG(ERROR) << "sched_setaffinity failed";
+ return false;
+ }
+ return true;
+}
+
bool Workload::Start() {
CHECK_EQ(work_state_, NotYetStartNewProcess);
char start_signal = 1;
diff --git a/simpleperf/workload.h b/simpleperf/workload.h
index 2400ac8f..86b28924 100644
--- a/simpleperf/workload.h
+++ b/simpleperf/workload.h
@@ -43,6 +43,7 @@ class Workload {
~Workload();
+ bool SetCpuAffinity(int cpu);
bool Start();
bool IsStarted() { return work_state_ == Started; }
pid_t GetPid() { return work_pid_; }