diff options
author | Yabin Cui <yabinc@google.com> | 2017-02-23 15:54:11 -0800 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2017-02-23 15:55:21 -0800 |
commit | ada97db3d4336faac601663e8bb4b59835ae49a0 (patch) | |
tree | d7e036162f24d6991ffc158c04927bf197f7c7af /simpleperf/cmd_report.cpp | |
parent | d9d23181768df567d166b79a89cfc0408e086509 (diff) | |
download | extras-ada97db3d4336faac601663e8bb4b59835ae49a0.tar.gz |
simpleperf: generate one report for each event attr.
Bug: http://b/35475170
Test: run simpleperf_unit_test.
Test: run report.py.
Change-Id: Ie9329a64c701bce38f7b440c16cb47e99e83db45
Diffstat (limited to 'simpleperf/cmd_report.cpp')
-rw-r--r-- | simpleperf/cmd_report.cpp | 95 |
1 files changed, 65 insertions, 30 deletions
diff --git a/simpleperf/cmd_report.cpp b/simpleperf/cmd_report.cpp index 3b727a5e..0aa7b8ad 100644 --- a/simpleperf/cmd_report.cpp +++ b/simpleperf/cmd_report.cpp @@ -243,6 +243,31 @@ class ReportCmdSampleTreeBuilder uint64_t total_period_; }; +struct SampleTreeBuilderOptions { + SampleComparator<SampleEntry> comparator; + ThreadTree* thread_tree; + std::unordered_set<std::string> comm_filter; + std::unordered_set<std::string> dso_filter; + std::unordered_set<std::string> symbol_filter; + std::unordered_set<int> pid_filter; + std::unordered_set<int> tid_filter; + bool use_branch_address; + bool accumulate_callchain; + bool build_callchain; + bool use_caller_as_callchain_root; + bool strict_unwind_arch_check; + + std::unique_ptr<ReportCmdSampleTreeBuilder> CreateSampleTreeBuilder() { + std::unique_ptr<ReportCmdSampleTreeBuilder> builder( + new ReportCmdSampleTreeBuilder(comparator, thread_tree)); + builder->SetFilters(pid_filter, tid_filter, comm_filter, dso_filter, symbol_filter); + builder->SetBranchSampleOption(use_branch_address); + builder->SetCallChainSampleOptions(accumulate_callchain, build_callchain, + use_caller_as_callchain_root, strict_unwind_arch_check); + return builder; + } +}; + using ReportCmdSampleTreeSorter = SampleTreeSorter<SampleEntry>; using ReportCmdSampleTreeDisplayer = SampleTreeDisplayer<SampleEntry, SampleTree>; @@ -343,8 +368,11 @@ class ReportCommand : public Command { std::unique_ptr<RecordFileReader> record_file_reader_; std::vector<EventAttrWithName> event_attrs_; ThreadTree thread_tree_; - SampleTree sample_tree_; - std::unique_ptr<ReportCmdSampleTreeBuilder> sample_tree_builder_; + // Create a SampleTreeBuilder and SampleTree for each event_attr. + std::vector<SampleTree> sample_tree_; + SampleTreeBuilderOptions sample_tree_builder_options_; + std::vector<std::unique_ptr<ReportCmdSampleTreeBuilder>> sample_tree_builder_; + std::unique_ptr<ReportCmdSampleTreeSorter> sample_tree_sorter_; std::unique_ptr<ReportCmdSampleTreeDisplayer> sample_tree_displayer_; bool use_branch_address_; @@ -397,11 +425,6 @@ bool ReportCommand::ParseOptions(const std::vector<std::string>& args) { std::string vmlinux; bool print_sample_count = false; std::vector<std::string> sort_keys = {"comm", "pid", "tid", "dso", "symbol"}; - std::unordered_set<std::string> comm_filter; - std::unordered_set<std::string> dso_filter; - std::unordered_set<std::string> symbol_filter; - std::unordered_set<int> pid_filter; - std::unordered_set<int> tid_filter; for (size_t i = 0; i < args.size(); ++i) { if (args[i] == "-b") { @@ -410,7 +433,8 @@ bool ReportCommand::ParseOptions(const std::vector<std::string>& args) { accumulate_callchain_ = true; } else if (args[i] == "--comms" || args[i] == "--dsos") { std::unordered_set<std::string>& filter = - (args[i] == "--comms" ? comm_filter : dso_filter); + (args[i] == "--comms" ? sample_tree_builder_options_.comm_filter + : sample_tree_builder_options_.dso_filter); if (!NextArgumentOrError(args, &i)) { return false; } @@ -478,7 +502,8 @@ bool ReportCommand::ParseOptions(const std::vector<std::string>& args) { } else if (args[i] == "--pids" || args[i] == "--tids") { const std::string& option = args[i]; std::unordered_set<int>& filter = - (option == "--pids" ? pid_filter : tid_filter); + (option == "--pids" ? sample_tree_builder_options_.pid_filter + : sample_tree_builder_options_.tid_filter); if (!NextArgumentOrError(args, &i)) { return false; } @@ -502,7 +527,7 @@ bool ReportCommand::ParseOptions(const std::vector<std::string>& args) { return false; } std::vector<std::string> strs = android::base::Split(args[i], ";"); - symbol_filter.insert(strs.begin(), strs.end()); + sample_tree_builder_options_.symbol_filter.insert(strs.begin(), strs.end()); } else if (args[i] == "--symfs") { if (!NextArgumentOrError(args, &i)) { return false; @@ -607,10 +632,8 @@ bool ReportCommand::ParseOptions(const std::vector<std::string>& args) { } } - sample_tree_builder_.reset( - new ReportCmdSampleTreeBuilder(comparator, &thread_tree_)); - sample_tree_builder_->SetFilters(pid_filter, tid_filter, comm_filter, - dso_filter, symbol_filter); + sample_tree_builder_options_.comparator = comparator; + sample_tree_builder_options_.thread_tree = &thread_tree_; SampleComparator<SampleEntry> sort_comparator; sort_comparator.AddCompareFunction(CompareTotalPeriod); @@ -690,28 +713,36 @@ bool ReportCommand::ReadFeaturesFromRecordFile() { } bool ReportCommand::ReadSampleTreeFromRecordFile() { - sample_tree_builder_->SetBranchSampleOption(use_branch_address_); + sample_tree_builder_options_.use_branch_address = use_branch_address_; // Normally do strict arch check when unwinding stack. But allow unwinding // 32-bit processes on 64-bit devices for system wide profiling. - bool strict_unwind_arch_check = !system_wide_collection_; - sample_tree_builder_->SetCallChainSampleOptions( - accumulate_callchain_, print_callgraph_, !callgraph_show_callee_, - strict_unwind_arch_check); + sample_tree_builder_options_.strict_unwind_arch_check = !system_wide_collection_; + sample_tree_builder_options_.accumulate_callchain = accumulate_callchain_; + sample_tree_builder_options_.build_callchain = print_callgraph_; + sample_tree_builder_options_.use_caller_as_callchain_root = !callgraph_show_callee_; + + for (size_t i = 0; i < event_attrs_.size(); ++i) { + sample_tree_builder_.push_back(sample_tree_builder_options_.CreateSampleTreeBuilder()); + } + if (!record_file_reader_->ReadDataSection( [this](std::unique_ptr<Record> record) { return ProcessRecord(std::move(record)); })) { return false; } - sample_tree_ = sample_tree_builder_->GetSampleTree(); - sample_tree_sorter_->Sort(sample_tree_.samples, print_callgraph_); + for (size_t i = 0; i < sample_tree_builder_.size(); ++i) { + sample_tree_.push_back(sample_tree_builder_[i]->GetSampleTree()); + sample_tree_sorter_->Sort(sample_tree_.back().samples, print_callgraph_); + } return true; } bool ReportCommand::ProcessRecord(std::unique_ptr<Record> record) { thread_tree_.Update(*record); if (record->type() == PERF_RECORD_SAMPLE) { - sample_tree_builder_->ProcessSampleRecord( + size_t attr_id = record_file_reader_->GetAttrIndexOfRecord(record.get()); + sample_tree_builder_[attr_id]->ProcessSampleRecord( *static_cast<const SampleRecord*>(record.get())); } else if (record->type() == PERF_RECORD_TRACING_DATA) { const auto& r = *static_cast<TracingDataRecord*>(record.get()); @@ -745,8 +776,18 @@ bool ReportCommand::PrintReport() { file_handler.reset(report_fp); } PrintReportContext(report_fp); - sample_tree_displayer_->DisplaySamples(report_fp, sample_tree_.samples, - &sample_tree_); + for (size_t i = 0; i < event_attrs_.size(); ++i) { + if (i != 0) { + fprintf(report_fp, "\n"); + } + EventAttrWithName& attr = event_attrs_[i]; + SampleTree& sample_tree = sample_tree_[i]; + fprintf(report_fp, "Event: %s (type %u, config %llu)\n", attr.name.c_str(), + attr.attr.type, attr.attr.config); + fprintf(report_fp, "Samples: %" PRIu64 "\n", sample_tree.total_samples); + fprintf(report_fp, "Event count: %" PRIu64 "\n\n", sample_tree.total_period); + sample_tree_displayer_->DisplaySamples(report_fp, sample_tree.samples, &sample_tree); + } fflush(report_fp); if (ferror(report_fp) != 0) { PLOG(ERROR) << "print report failed"; @@ -760,12 +801,6 @@ void ReportCommand::PrintReportContext(FILE* report_fp) { fprintf(report_fp, "Cmdline: %s\n", record_cmdline_.c_str()); } fprintf(report_fp, "Arch: %s\n", GetArchString(record_file_arch_).c_str()); - for (const auto& attr : event_attrs_) { - fprintf(report_fp, "Event: %s (type %u, config %llu)\n", attr.name.c_str(), - attr.attr.type, attr.attr.config); - } - fprintf(report_fp, "Samples: %" PRIu64 "\n", sample_tree_.total_samples); - fprintf(report_fp, "Event count: %" PRIu64 "\n\n", sample_tree_.total_period); } } // namespace |