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     /* For system-wide profiling, set sys_wide=true, the_pid=-1, and pid_running=false.
00078      * For single app profiling, set sys_wide=false, the_pid=<processID-to-profile>,
00079      * and pid_running=true if profiling an already active process; otherwise false.
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 /* OPERF_COUNTER_H_ */

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1