#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"
#include "event_fd.h"
#include "event_selection_set.h"
#include "event_type.h"
+#include "scoped_signal_handler.h"
#include "utils.h"
#include "workload.h"
"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"
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);
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)) {
// 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;
}
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;
return true;
}
-__attribute__((constructor)) static void RegisterStatCommand() {
+void RegisterStatCommand() {
RegisterCommand("stat", [] { return std::unique_ptr<Command>(new StatCommand); });
}