2 * @file libperf_events/operf_counter.h
3 * C++ class definition that abstracts the user-to-kernel interface
4 * for using Linux Performance Events Subsystem.
6 * @remark Copyright 2011 OProfile authors
7 * @remark Read the file COPYING
9 * Created on: Dec 7, 2011
10 * @author Maynard Johnson
11 * (C) Copyright IBM Corp. 2011
13 * Modified by Maynard Johnson <maynardj@us.ibm.com>
14 * (C) Copyright IBM Corporation 2012, 2014
18 #ifndef OPERF_COUNTER_H_
19 #define OPERF_COUNTER_H_
23 #include <sys/syscall.h>
33 #include "operf_event.h"
34 #include "op_cpu_type.h"
35 #include "operf_utils.h"
37 extern char * start_time_human_readable;
41 #define OP_BASIC_SAMPLE_FORMAT (PERF_SAMPLE_ID | PERF_SAMPLE_IP \
45 op_perf_event_open(struct perf_event_attr * attr,
46 pid_t pid, int cpu, int group_fd,
49 return syscall(__NR_perf_event_open, attr, pid, cpu,
53 #define OP_PERF_HANDLED_ERROR -101
54 #define OP_PERF_NO_SAMPLE_ID 0xdeadbeefdeadbeefULL
59 operf_counter(operf_event_t & evt, bool enable_on_exec, bool callgraph,
60 bool separate_by_cpu, bool inherit, int event_number);
62 int perf_event_open(pid_t pid, int cpu, operf_record * pr, bool print_error);
63 const struct perf_event_attr * the_attr(void) const { return &attr; }
64 int get_fd(void) const { return fd; }
65 int get_id(void) const { return id; }
66 int get_evt_num(void) const { return evt_num; }
67 const std::string get_event_name(void) const { return event_name; }
70 struct perf_event_attr attr;
74 std::string event_name;
80 /* For system-wide profiling, set sys_wide=true, the_pid=-1, and pid_running=false.
81 * For single app profiling, set sys_wide=false, the_pid=<processID-to-profile>,
82 * and pid_running=true if profiling an already active process; otherwise false.
84 operf_record(int output_fd, bool sys_wide, pid_t the_pid, bool pid_running,
85 std::vector<operf_event_t> & evts, OP_perf_utils::vmlinux_info_t vi,
86 bool callgraph, bool separate_by_cpu, bool output_fd_is_file,
87 int _convert_read_pipe, int _convert_write_pipe);
89 void recordPerfData(void);
90 int out_fd(void) const { return output_fd; }
91 void add_to_total(int n) { total_bytes_recorded += n; }
92 void add_process(struct comm_event proc) { procs[proc.tid] = proc; }
93 unsigned int get_total_bytes_recorded(void) const { return total_bytes_recorded; }
94 void register_perf_event_id(unsigned counter, u64 id, perf_event_attr evt_attr);
95 bool get_valid(void) { return valid; }
98 void create(std::string outfile, std::vector<operf_event_t> & evts);
100 int prepareToRecord(void);
101 int _prepare_to_record_one_fd(int idx, int fd);
102 int _start_recoding_new_thread(pid_t id);
103 void record_process_info(void);
104 void write_op_header_info(void);
105 int _write_header_to_file(void);
106 int _write_header_to_pipe(void);
111 // Array of size 'num_cpus_used_for_perf_event_open * num_pids * num_events'
112 struct pollfd * poll_data;
113 std::vector<struct mmap_data> samples_array;
115 pid_t pid_to_profile;
116 /* When doing --pid or --system-wide profiling, we'll obtain process information
117 * for all processes to be profiled (including forked/cloned processes) and store
118 * that information in a collection of type 'comm_event'. We'll use this collection
119 * for synthesizing PERF_RECORD_COMM events into the profile data stream.
121 std::map<u32, struct comm_event> procs;
126 std::vector<operf_counter> perfCounters;
127 unsigned int total_bytes_recorded;
129 struct OP_header opHeader;
130 std::vector<operf_event_t> evts;
132 std::string vmlinux_file;
133 u64 kernel_start, kernel_end;
138 operf_read(std::vector<operf_event_t> & _evts)
139 : sample_data_fd(-1), inputFname(""), evts(_evts), cpu_type(CPU_NO_GOOD)
140 { valid = syswide = false;
141 write_comm_pipe = read_comm_pipe = 1;
142 post_profiling_pipe = -1; }
143 void init(int sample_data_pipe_fd, std::string input_filename, std::string samples_dir, op_cpu cputype,
144 bool systemwide, int _record_write_pipe, int _record_read_pipe,
145 int _post_profiling_pipe);
147 int readPerfHeader(void);
148 unsigned int convertPerfData(void);
149 bool is_valid(void) {return valid; }
150 int get_eventnum_by_perf_event_id(u64 id) const;
151 inline const operf_event_t * get_event_by_counter(u32 counter) { return &evts[counter]; }
152 int get_write_comm_pipe(void) { return write_comm_pipe; }
153 int get_read_comm_pipe(void) { return read_comm_pipe; }
154 void add_sample_id_to_opHeader(u64 sample_id);
160 int post_profiling_pipe;
161 std::string inputFname;
162 std::string sampledir;
164 struct OP_header opHeader;
165 std::vector<operf_event_t> & evts;
169 int _read_header_info_with_ifstream(void);
170 int _read_perf_header_from_file(void);
171 int _read_perf_header_from_pipe(void);
175 #endif /* OPERF_COUNTER_H_ */