OSDN Git Service

simpleperf: check perf event limit.
[android-x86/system-extras.git] / simpleperf / cmd_stat.cpp
index 245a996..488e731 100644 (file)
@@ -25,8 +25,8 @@
 #include <string>
 #include <vector>
 
-#include <base/logging.h>
-#include <base/strings.h>
+#include <android-base/logging.h>
+#include <android-base/strings.h>
 
 #include "command.h"
 #include "environment.h"
@@ -34,6 +34,7 @@
 #include "event_fd.h"
 #include "event_selection_set.h"
 #include "event_type.h"
+#include "scoped_signal_handler.h"
 #include "utils.h"
 #include "workload.h"
 
@@ -55,6 +56,9 @@ class StatCommand : public Command {
                 "Usage: simpleperf stat [options] [command [command-args]]\n"
                 "    Gather performance counter information of running [command].\n"
                 "    -a           Collect system-wide information.\n"
+                "    --cpu cpu_item1,cpu_item2,...\n"
+                "                 Collect information only on the selected cpus. cpu_item can\n"
+                "                 be a cpu number like 1, or a cpu range like 0-3.\n"
                 "    -e event1[:modifier1],event2[:modifier2],...\n"
                 "                 Select the event list to count. Use `simpleperf list` to find\n"
                 "                 all possible event names. Modifiers can be added to define\n"
@@ -72,8 +76,8 @@ class StatCommand : public Command {
         system_wide_collection_(false),
         child_inherit_(true) {
     signaled = false;
-    signal_handler_register_.reset(
-        new SignalHandlerRegister({SIGCHLD, SIGINT, SIGTERM}, signal_handler));
+    scoped_signal_handler_.reset(
+        new ScopedSignalHandler({SIGCHLD, SIGINT, SIGTERM}, signal_handler));
   }
 
   bool Run(const std::vector<std::string>& args);
@@ -89,13 +93,18 @@ class StatCommand : public Command {
   bool system_wide_collection_;
   bool child_inherit_;
   std::vector<pid_t> monitored_threads_;
+  std::vector<int> cpus_;
   std::vector<EventTypeAndModifier> measured_event_types_;
   EventSelectionSet event_selection_set_;
 
-  std::unique_ptr<SignalHandlerRegister> signal_handler_register_;
+  std::unique_ptr<ScopedSignalHandler> scoped_signal_handler_;
 };
 
 bool StatCommand::Run(const std::vector<std::string>& args) {
+  if (!CheckPerfEventLimit()) {
+    return false;
+  }
+
   // 1. Parse options, and use default measured event types if not given.
   std::vector<std::string> workload_args;
   if (!ParseOptions(args, &workload_args)) {
@@ -130,22 +139,17 @@ bool StatCommand::Run(const std::vector<std::string>& args) {
 
   // 3. Open perf_event_files.
   if (system_wide_collection_) {
-    if (!event_selection_set_.OpenEventFilesForAllCpus()) {
+    if (!event_selection_set_.OpenEventFilesForCpus(cpus_)) {
       return false;
     }
   } else {
-    if (!event_selection_set_.OpenEventFilesForThreads(monitored_threads_)) {
+    if (!event_selection_set_.OpenEventFilesForThreadsOnCpus(monitored_threads_, cpus_)) {
       return false;
     }
   }
 
   // 4. Count events while workload running.
   auto start_time = std::chrono::steady_clock::now();
-  if (!event_selection_set_.GetEnableOnExec()) {
-    if (!event_selection_set_.EnableEvents()) {
-      return false;
-    }
-  }
   if (workload != nullptr && !workload->Start()) {
     return false;
   }
@@ -174,6 +178,11 @@ bool StatCommand::ParseOptions(const std::vector<std::string>& args,
   for (i = 0; i < args.size() && args[i].size() > 0 && args[i][0] == '-'; ++i) {
     if (args[i] == "-a") {
       system_wide_collection_ = true;
+    } else if (args[i] == "--cpu") {
+      if (!NextArgumentOrError(args, &i)) {
+        return false;
+      }
+      cpus_ = GetCpusFromString(args[i]);
     } else if (args[i] == "-e") {
       if (!NextArgumentOrError(args, &i)) {
         return false;
@@ -406,6 +415,6 @@ bool StatCommand::ShowCounters(const std::vector<CountersInfo>& counters, double
   return true;
 }
 
-__attribute__((constructor)) static void RegisterStatCommand() {
+void RegisterStatCommand() {
   RegisterCommand("stat", [] { return std::unique_ptr<Command>(new StatCommand); });
 }