summaryrefslogtreecommitdiff
path: root/simpleperf/cmd_report.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2017-02-23 15:54:11 -0800
committerYabin Cui <yabinc@google.com>2017-02-23 15:55:21 -0800
commitada97db3d4336faac601663e8bb4b59835ae49a0 (patch)
treed7e036162f24d6991ffc158c04927bf197f7c7af /simpleperf/cmd_report.cpp
parentd9d23181768df567d166b79a89cfc0408e086509 (diff)
downloadextras-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.cpp95
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