operf_counter.h
Go to the documentation of this file.00001
00018 #ifndef OPERF_COUNTER_H_
00019 #define OPERF_COUNTER_H_
00020
00021 #include <sys/mman.h>
00022 #include <unistd.h>
00023 #include <sys/syscall.h>
00024 #include <stdint.h>
00025 #include <poll.h>
00026 #include <string>
00027 #include <vector>
00028 #include <map>
00029 #include <stdexcept>
00030 #include <limits.h>
00031 #include <istream>
00032 #include <fstream>
00033 #include "operf_event.h"
00034 #include "op_cpu_type.h"
00035 #include "operf_utils.h"
00036
00037 extern char * start_time_human_readable;
00038
00039 class operf_record;
00040
00041 #define OP_BASIC_SAMPLE_FORMAT (PERF_SAMPLE_ID | PERF_SAMPLE_IP \
00042 | PERF_SAMPLE_TID)
00043
00044 static inline int
00045 op_perf_event_open(struct perf_event_attr * attr,
00046 pid_t pid, int cpu, int group_fd,
00047 unsigned long flags)
00048 {
00049 return syscall(__NR_perf_event_open, attr, pid, cpu,
00050 group_fd, flags);
00051 }
00052
00053 #define OP_PERF_HANDLED_ERROR -101
00054
00055
00056 class operf_counter {
00057 public:
00058 operf_counter(operf_event_t & evt, bool enable_on_exec, bool callgraph,
00059 bool separate_by_cpu);
00060 ~operf_counter();
00061 int perf_event_open(pid_t ppid, int cpu, unsigned counter, operf_record * pr);
00062 const struct perf_event_attr * the_attr(void) const { return &attr; }
00063 int get_fd(void) const { return fd; }
00064 int get_id(void) const { return id; }
00065 const std::string get_event_name(void) const { return event_name; }
00066
00067 private:
00068 struct perf_event_attr attr;
00069 int fd;
00070 int id;
00071 std::string event_name;
00072 };
00073
00074
00075 class operf_record {
00076 public:
00077
00078
00079
00080
00081 operf_record(int output_fd, bool sys_wide, pid_t the_pid, bool pid_running,
00082 std::vector<operf_event_t> & evts, OP_perf_utils::vmlinux_info_t vi,
00083 bool callgraph, bool separate_by_cpu, bool output_fd_is_file);
00084 ~operf_record();
00085 void recordPerfData(void);
00086 int out_fd(void) const { return output_fd; }
00087 void add_to_total(int n) { total_bytes_recorded += n; }
00088 int get_total_bytes_recorded(void) const { return total_bytes_recorded; }
00089 void register_perf_event_id(unsigned counter, u64 id, perf_event_attr evt_attr);
00090 bool get_valid(void) { return valid; }
00091
00092 private:
00093 void create(std::string outfile, std::vector<operf_event_t> & evts);
00094 void setup(void);
00095 int prepareToRecord(int cpu, int fd);
00096 void write_op_header_info(void);
00097 int _write_header_to_file(void);
00098 int _write_header_to_pipe(void);
00099 int output_fd;
00100 bool write_to_file;
00101 struct pollfd * poll_data;
00102 std::vector<struct mmap_data> samples_array;
00103 int num_cpus;
00104 pid_t pid;
00105 bool pid_started;
00106 bool system_wide;
00107 bool callgraph;
00108 bool separate_cpu;
00109 std::vector< std::vector<operf_counter> > perfCounters;
00110 int total_bytes_recorded;
00111 int poll_count;
00112 struct OP_header opHeader;
00113 std::vector<operf_event_t> evts;
00114 bool valid;
00115 std::string vmlinux_file;
00116 u64 kernel_start, kernel_end;
00117 };
00118
00119 class operf_read {
00120 public:
00121 operf_read(void) : sample_data_fd(-1), inputFname(""), cpu_type(CPU_NO_GOOD) { valid = syswide = false;}
00122 void init(int sample_data_pipe_fd, std::string input_filename, std::string samples_dir, op_cpu cputype,
00123 std::vector<operf_event_t> & evts, bool systemwide);
00124 ~operf_read();
00125 int readPerfHeader(void);
00126 int convertPerfData(void);
00127 bool is_valid(void) {return valid; }
00128 int get_eventnum_by_perf_event_id(u64 id) const;
00129 inline const operf_event_t * get_event_by_counter(u32 counter) { return &evts[counter]; }
00130
00131 private:
00132 int sample_data_fd;
00133 std::string inputFname;
00134 std::string sampledir;
00135 std::ifstream istrm;
00136 struct OP_header opHeader;
00137 std::vector<operf_event_t> evts;
00138 bool valid;
00139 bool syswide;
00140 op_cpu cpu_type;
00141 int _get_one_perf_event(event_t *);
00142 int _read_header_info_with_ifstream(void);
00143 int _read_perf_header_from_file(void);
00144 int _read_perf_header_from_pipe(void);
00145 };
00146
00147
00148 #endif