summaryrefslogtreecommitdiff
path: root/simpleperf/cmd_record.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2015-06-01 11:21:37 -0700
committerYabin Cui <yabinc@google.com>2015-06-04 15:26:32 -0700
commitf79f07e13c56f7ca3be1435cea7f8861daf7efaa (patch)
tree8c76bac6fe4d9b52b69e57393f5deecb18febd97 /simpleperf/cmd_record.cpp
parentd4637d6e7d17f48d9325fa133be82b06a408f523 (diff)
downloadextras-f79f07e13c56f7ca3be1435cea7f8861daf7efaa.tar.gz
Simpleperf: refactor command system.
Register a callback function to create a new command instance instead of registering a command instance. Then we can release resources in the command destructors, and don't need xxxCommandImpl classes any more. Bug: 19483574 Change-Id: Ibb54892ec0655fd43909347afd72bb08bc8a716c
Diffstat (limited to 'simpleperf/cmd_record.cpp')
-rw-r--r--simpleperf/cmd_record.cpp99
1 files changed, 44 insertions, 55 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index 94cf052a..83fa593a 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -31,7 +31,6 @@
#include "read_elf.h"
#include "record.h"
#include "record_file.h"
-#include "utils.h"
#include "workload.h"
static std::string default_measured_event_type = "cpu-cycles";
@@ -45,10 +44,34 @@ static std::unordered_map<std::string, uint64_t> branch_sampling_type_map = {
{"ind_call", PERF_SAMPLE_BRANCH_IND_CALL},
};
-class RecordCommandImpl {
+class RecordCommand : public Command {
public:
- RecordCommandImpl()
- : use_sample_freq_(true),
+ RecordCommand()
+ : Command("record", "record sampling info in perf.data",
+ "Usage: simpleperf record [options] [command [command-args]]\n"
+ " Gather sampling information when running [command]. If [command]\n"
+ " is not specified, sleep 1 is used instead.\n"
+ " -a System-wide collection.\n"
+ " -b Enable take branch stack sampling. Same as '-j any'\n"
+ " -c count Set event sample period.\n"
+ " -e event Select the event to sample (Use `simpleperf list`)\n"
+ " to find all possible event names.\n"
+ " -f freq Set event sample frequency.\n"
+ " -F freq Same as '-f freq'.\n"
+ " -j branch_filter1,branch_filter2,...\n"
+ " Enable taken branch stack sampling. Each sample\n"
+ " captures a series of consecutive taken branches.\n"
+ " The following filters are defined:\n"
+ " any: any type of branch\n"
+ " any_call: any function call or system call\n"
+ " any_ret: any function return or system call return\n"
+ " ind_call: any indirect branch\n"
+ " u: only when the branch target is at the user level\n"
+ " k: only when the branch target is in the kernel\n"
+ " This option requires at least one branch type among any,\n"
+ " any_call, any_ret, ind_call.\n"
+ " -o record_file_name Set record file name, default is perf.data.\n"),
+ use_sample_freq_(true),
sample_freq_(1000),
system_wide_collection_(false),
branch_sampling_(0),
@@ -59,7 +82,7 @@ class RecordCommandImpl {
saved_sigchild_handler_ = signal(SIGCHLD, [](int) {});
}
- ~RecordCommandImpl() {
+ ~RecordCommand() {
signal(SIGCHLD, saved_sigchild_handler_);
}
@@ -95,7 +118,7 @@ class RecordCommandImpl {
sighandler_t saved_sigchild_handler_;
};
-bool RecordCommandImpl::Run(const std::vector<std::string>& args) {
+bool RecordCommand::Run(const std::vector<std::string>& args) {
// 1. Parse options, and use default measured event type if not given.
std::vector<std::string> workload_args;
if (!ParseOptions(args, &workload_args)) {
@@ -165,7 +188,7 @@ bool RecordCommandImpl::Run(const std::vector<std::string>& args) {
return false;
}
auto callback =
- std::bind(&RecordCommandImpl::WriteData, this, std::placeholders::_1, std::placeholders::_2);
+ std::bind(&RecordCommand::WriteData, this, std::placeholders::_1, std::placeholders::_2);
while (true) {
if (!event_selection_set_.ReadMmapEventData(callback)) {
return false;
@@ -186,10 +209,10 @@ bool RecordCommandImpl::Run(const std::vector<std::string>& args) {
return true;
}
-bool RecordCommandImpl::ParseOptions(const std::vector<std::string>& args,
- std::vector<std::string>* non_option_args) {
+bool RecordCommand::ParseOptions(const std::vector<std::string>& args,
+ std::vector<std::string>* non_option_args) {
size_t i;
- for (i = 1; i < args.size() && args[i].size() > 0 && args[i][0] == '-'; ++i) {
+ 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] == "-b") {
@@ -242,8 +265,7 @@ bool RecordCommandImpl::ParseOptions(const std::vector<std::string>& args,
}
record_filename_ = args[i];
} else {
- LOG(ERROR) << "Unknown option for record command: '" << args[i] << "'\n";
- LOG(ERROR) << "Try `simpleperf help record`";
+ ReportUnknownOption(args, i);
return false;
}
}
@@ -257,7 +279,7 @@ bool RecordCommandImpl::ParseOptions(const std::vector<std::string>& args,
return true;
}
-bool RecordCommandImpl::SetMeasuredEventType(const std::string& event_type_name) {
+bool RecordCommand::SetMeasuredEventType(const std::string& event_type_name) {
const EventType* event_type = EventTypeFactory::FindEventTypeByName(event_type_name);
if (event_type == nullptr) {
return false;
@@ -266,7 +288,7 @@ bool RecordCommandImpl::SetMeasuredEventType(const std::string& event_type_name)
return true;
}
-bool RecordCommandImpl::SetEventSelection() {
+bool RecordCommand::SetEventSelection() {
event_selection_set_.AddEventType(*measured_event_type_);
if (use_sample_freq_) {
event_selection_set_.SetSampleFreq(sample_freq_);
@@ -280,11 +302,11 @@ bool RecordCommandImpl::SetEventSelection() {
return true;
}
-bool RecordCommandImpl::WriteData(const char* data, size_t size) {
+bool RecordCommand::WriteData(const char* data, size_t size) {
return record_file_writer_->WriteData(data, size);
}
-bool RecordCommandImpl::DumpKernelAndModuleMmaps() {
+bool RecordCommand::DumpKernelAndModuleMmaps() {
KernelMmap kernel_mmap;
std::vector<ModuleMmap> module_mmaps;
if (!GetKernelAndModuleMmaps(&kernel_mmap, &module_mmaps)) {
@@ -310,7 +332,7 @@ bool RecordCommandImpl::DumpKernelAndModuleMmaps() {
return true;
}
-bool RecordCommandImpl::DumpThreadCommAndMmaps() {
+bool RecordCommand::DumpThreadCommAndMmaps() {
std::vector<ThreadComm> thread_comms;
if (!GetThreadComms(&thread_comms)) {
return false;
@@ -343,14 +365,14 @@ bool RecordCommandImpl::DumpThreadCommAndMmaps() {
return true;
}
-bool RecordCommandImpl::DumpAdditionalFeatures() {
+bool RecordCommand::DumpAdditionalFeatures() {
if (!record_file_writer_->WriteFeatureHeader(1)) {
return false;
}
return DumpBuildIdFeature();
}
-bool RecordCommandImpl::DumpBuildIdFeature() {
+bool RecordCommand::DumpBuildIdFeature() {
std::vector<std::string> hit_kernel_modules;
std::vector<std::string> hit_user_files;
if (!record_file_writer_->GetHitModules(&hit_kernel_modules, &hit_user_files)) {
@@ -396,39 +418,6 @@ bool RecordCommandImpl::DumpBuildIdFeature() {
return true;
}
-class RecordCommand : public Command {
- public:
- RecordCommand()
- : Command("record", "record sampling info in perf.data",
- "Usage: simpleperf record [options] [command [command-args]]\n"
- " Gather sampling information when running [command]. If [command]\n"
- " is not specified, sleep 1 is used instead.\n"
- " -a System-wide collection.\n"
- " -b Enable take branch stack sampling. Same as '-j any'\n"
- " -c count Set event sample period.\n"
- " -e event Select the event to sample (Use `simpleperf list`)\n"
- " to find all possible event names.\n"
- " -f freq Set event sample frequency.\n"
- " -F freq Same as '-f freq'.\n"
- " -j branch_filter1,branch_filter2,...\n"
- " Enable taken branch stack sampling. Each sample\n"
- " captures a series of consecutive taken branches.\n"
- " The following filters are defined:\n"
- " any: any type of branch\n"
- " any_call: any function call or system call\n"
- " any_ret: any function return or system call return\n"
- " ind_call: any indirect branch\n"
- " u: only when the branch target is at the user level\n"
- " k: only when the branch target is in the kernel\n"
- " This option requires at least one branch type among any,\n"
- " any_call, any_ret, ind_call.\n"
- " -o record_file_name Set record file name, default is perf.data.\n") {
- }
-
- bool Run(const std::vector<std::string>& args) override {
- RecordCommandImpl impl;
- return impl.Run(args);
- }
-};
-
-RecordCommand record_command;
+__attribute__((constructor)) static void RegisterRecordCommand() {
+ RegisterCommand("record", [] { return std::unique_ptr<Command>(new RecordCommand()); });
+}