30 #include <sys/syscall.h>
31 #include <linux/perf_event.h>
33 #define COUNTER_SIZE (sizeof(void*))
34 #define BUFFER_SIZE 256
35 #define PRETTY_PRINT_WIDTH 13
56 struct perf_event_attr* attr,
57 pid_t pid,
int cpu,
int group_fd,
58 unsigned long flags) {
59 attr->size =
sizeof(*attr);
60 return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags);
65 memset(attr, 0,
sizeof(perf_event_attr));
69 attr->type = PERF_TYPE_SOFTWARE;
70 attr->config = PERF_COUNT_SW_CPU_CLOCK;
73 attr->type = PERF_TYPE_SOFTWARE;
74 attr->config = PERF_COUNT_SW_PAGE_FAULTS;
77 attr->type = PERF_TYPE_SOFTWARE;
78 attr->config = PERF_COUNT_SW_PAGE_FAULTS;
81 attr->type = PERF_TYPE_SOFTWARE;
82 attr->config = PERF_COUNT_SW_CPU_MIGRATIONS;
85 attr->type = PERF_TYPE_HARDWARE;
86 attr->config = PERF_COUNT_HW_CPU_CYCLES;
89 attr->type = PERF_TYPE_HARDWARE;
90 attr->config = PERF_COUNT_HW_INSTRUCTIONS;
93 attr->type = PERF_TYPE_HARDWARE;
94 attr->config = PERF_COUNT_HW_CACHE_REFERENCES;
97 attr->type = PERF_TYPE_HARDWARE;
98 attr->config = PERF_COUNT_HW_CACHE_MISSES;
101 attr->type = PERF_TYPE_HARDWARE;
102 attr->config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
105 attr->type = PERF_TYPE_HARDWARE;
106 attr->config = PERF_COUNT_HW_BRANCH_MISSES;
109 attr->type = PERF_TYPE_HARDWARE;
110 attr->config = PERF_COUNT_HW_BUS_CYCLES;
126 return "ContextSwitches";
128 return "CPUMigrations";
132 return "Instructions";
146 return "PeakVmUsage";
152 return "BytesWritten";
167 perf_event_attr attr;
181 data.type = TUnit::TIME_NS;
183 data.type = TUnit::UNIT;
193 data.type = TUnit::BYTES;
219 data.type = TUnit::BYTES;
239 for (
int i = 0; i <
counters_.size(); i++) {
243 if (
counters_[i].type == TUnit::TIME_NS) {
244 buffer[i] /= 1000000;
262 ifstream file(
"/proc/self/io", ios::in);
269 size_t colon = buf.find(
':');
270 if (colon == string::npos)
goto end;
271 buf = buf.substr(colon + 1);
272 istringstream stream(buf);
276 for (
int i = 0; i <
counters_.size(); ++i) {
278 buffer[i] = values[
counters_[i].proc_io_line_number];
282 if (file.is_open()) file.close();
287 ifstream file(
"/proc/self/status", ios::in);
292 for (
int i = 0; i <
counters_.size(); ++i) {
294 size_t field = buf.find(
counters_[i].proc_status_field);
295 if (field == string::npos)
continue;
297 buf = buf.substr(colon + 1);
298 istringstream stream(buf);
301 buffer[i] = value * 1024;
305 if (file.is_open()) file.close();
314 for (
int i = 0; i <
counters_.size(); ++i) {
342 for (
int i = 0; i <
counters_.size(); ++i) {
386 string fixed_name =
name;
387 if (fixed_name.size() == 0) {
390 fixed_name = ss.str();
393 vector<int64_t> buffer(
counters_.size());
404 if (snapshot < 0 || snapshot >=
snapshots_.size())
return NULL;
409 ostream& stream = *s;
410 stream << setw(8) <<
"Snapshot";
418 const vector<int64_t>& snapshot =
snapshots_[s];
419 for (
int i = 0; i < snapshot.size(); ++i) {
const StringSearch UrlParser::colon_search & colon
bool InitSysCounter(Counter counter)
std::string proc_status_field
For PROC_SELF_STATUS. Field name for counter.
bool InitProcSelfIOCounter(Counter counter)
bool GetProcSelfIOCounters(std::vector< int64_t > &snapshot)
std::vector< std::vector< int64_t > > snapshots_
void PrettyPrint(std::ostream *out) const
Prints out the names and results for all snapshots to 'out'.
bool InitProcSelfStatusCounter(Counter counter)
static std::string Print(bool value, TUnit::type ignored, bool verbose=false)
bool GetProcSelfStatusCounters(std::vector< int64_t > &snapshot)
int fd
For SYS_PERF_COUNTER. File descriptor where the counter value is stored.
std::vector< std::string > counter_names_
static string GetCounterName(PerfCounters::Counter counter)
bool GetSysCounters(std::vector< int64_t > &snapshot)
std::vector< std::string > snapshot_names_
int proc_io_line_number
For PROC_SELF_IO. Line number from /proc/self/io file with this counter's value.
void Snapshot(const std::string &name="")
static bool InitEventAttr(perf_event_attr *attr, PerfCounters::Counter counter)
std::vector< CounterData > counters_
static int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, unsigned long flags)
bool AddDefaultCounters()
#define PRETTY_PRINT_WIDTH
const std::vector< int64_t > * counters(int snapshot) const
Returns the results of that snapshot.