diff options
author | Yabin Cui <yabinc@google.com> | 2015-06-01 11:21:37 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2015-06-04 15:26:32 -0700 |
commit | f79f07e13c56f7ca3be1435cea7f8861daf7efaa (patch) | |
tree | 8c76bac6fe4d9b52b69e57393f5deecb18febd97 /simpleperf/cmd_record.cpp | |
parent | d4637d6e7d17f48d9325fa133be82b06a408f523 (diff) | |
download | extras-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.cpp | 99 |
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()); }); +} |