Menu

[0caea8]: / perfprofd / perf_data_converter.cc  Maximize  Restore  History

Download this file

131 lines (119 with data), 4.4 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "perf_data_converter.h"
#include "quipper/perf_parser.h"
#include <map>
using std::map;
namespace wireless_android_logging_awp {
struct RangeTarget {
RangeTarget(uint64 start, uint64 end, uint64 to)
: start(start), end(end), to(to) {}
bool operator<(const RangeTarget &r) const {
if (start != r.start) {
return start < r.start;
} else if (end != r.end) {
return end < r.end;
} else {
return to < r.to;
}
}
uint64 start;
uint64 end;
uint64 to;
};
struct BinaryProfile {
map<uint64, uint64> address_count_map;
map<RangeTarget, uint64> range_count_map;
};
wireless_android_play_playlog::AndroidPerfProfile
RawPerfDataToAndroidPerfProfile(const string &perf_file) {
wireless_android_play_playlog::AndroidPerfProfile ret;
quipper::PerfParser parser;
if (!parser.ReadFile(perf_file) || !parser.ParseRawEvents()) {
return ret;
}
typedef map<string, BinaryProfile> ModuleProfileMap;
typedef map<string, ModuleProfileMap> ProgramProfileMap;
ProgramProfileMap name_profile_map;
uint64 total_samples = 0;
for (const auto &event : parser.parsed_events()) {
if (!event.raw_event ||
event.raw_event->header.type != PERF_RECORD_SAMPLE) {
continue;
}
string dso_name = event.dso_and_offset.dso_name();
string program_name;
if (dso_name == "[kernel.kallsyms]_text") {
program_name = "kernel";
dso_name = "[kernel.kallsyms]";
} else if (event.command() == "") {
program_name = "unknown_program";
} else {
program_name = event.command();
}
name_profile_map[program_name][dso_name].address_count_map[
event.dso_and_offset.offset()]++;
total_samples++;
for (size_t i = 1; i < event.branch_stack.size(); i++) {
if (dso_name == event.branch_stack[i - 1].to.dso_name()) {
uint64 start = event.branch_stack[i].to.offset();
uint64 end = event.branch_stack[i - 1].from.offset();
uint64 to = event.branch_stack[i - 1].to.offset();
// The interval between two taken branches should not be too large.
if (end < start || end - start > (1 << 20)) {
LOG(WARNING) << "Bogus LBR data: " << start << "->" << end;
continue;
}
name_profile_map[program_name][dso_name].range_count_map[
RangeTarget(start, end, to)]++;
}
}
}
map<string, int> name_id_map;
for (const auto &program_profile : name_profile_map) {
for (const auto &module_profile : program_profile.second) {
name_id_map[module_profile.first] = 0;
}
}
int current_index = 0;
for (auto iter = name_id_map.begin(); iter != name_id_map.end(); ++iter) {
iter->second = current_index++;
}
map<string, string> name_buildid_map;
parser.GetFilenamesToBuildIDs(&name_buildid_map);
ret.set_total_samples(total_samples);
for (const auto &name_id : name_id_map) {
auto load_module = ret.add_load_modules();
load_module->set_name(name_id.first);
auto nbmi = name_buildid_map.find(name_id.first);
if (nbmi != name_buildid_map.end()) {
const std::string &build_id = nbmi->second;
if (build_id.size() == 40 && build_id.substr(32) == "00000000") {
load_module->set_build_id(build_id.substr(0, 32));
} else {
load_module->set_build_id(build_id);
}
}
}
for (const auto &program_profile : name_profile_map) {
auto program = ret.add_programs();
program->set_name(program_profile.first);
for (const auto &module_profile : program_profile.second) {
int32 module_id = name_id_map[module_profile.first];
auto module = program->add_modules();
module->set_load_module_id(module_id);
for (const auto &addr_count : module_profile.second.address_count_map) {
auto address_samples = module->add_address_samples();
address_samples->add_address(addr_count.first);
address_samples->set_count(addr_count.second);
}
for (const auto &range_count : module_profile.second.range_count_map) {
auto range_samples = module->add_range_samples();
range_samples->set_start(range_count.first.start);
range_samples->set_end(range_count.first.end);
range_samples->set_to(range_count.first.to);
range_samples->set_count(range_count.second);
}
}
}
return ret;
}
} // namespace wireless_android_logging_awp
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.