00001 /** 00002 * @file profile.h 00003 * Encapsulation for samples files over all profile classes 00004 * belonging to the same binary image 00005 * 00006 * @remark Copyright 2002 OProfile authors 00007 * @remark Read the file COPYING 00008 * 00009 * @author Philippe Elie 00010 * @author John Levon 00011 */ 00012 00013 #ifndef PROFILE_H 00014 #define PROFILE_H 00015 00016 #include <string> 00017 #include <map> 00018 #include <iterator> 00019 00020 #include "odb.h" 00021 #include "op_types.h" 00022 #include "utility.h" 00023 #include "populate_for_spu.h" 00024 00025 class opd_header; 00026 class op_bfd; 00027 00028 /** 00029 * Class containing a single sample file contents. 00030 * i.e. set of count values for VMA offsets for 00031 * a particular binary. 00032 */ 00033 class profile_t : noncopyable { 00034 public: 00035 /** 00036 * profile_t - construct an empty profile_t object 00037 */ 00038 profile_t(); 00039 00040 /// return true if no sample file has been loaded 00041 bool empty() const { return !file_header.get(); } 00042 00043 /// return the header of the last opened samples file 00044 opd_header const & get_header() const { 00045 return *file_header; 00046 } 00047 00048 /** 00049 * count samples count w/o recording them 00050 * @param filename sample filename 00051 * 00052 * convenience interface for raw access to sample count w/o recording 00053 * them. It's placed here so all access to samples files go through 00054 * profile_t static or non static member. 00055 */ 00056 static count_type sample_count(std::string const & filename); 00057 00058 /** 00059 * Indicate if given sample file is from a Cell Broadband Engine 00060 * SPU profile 00061 * @param filename sample filename 00062 * 00063 * Convenience interface put here so all access to samples files 00064 * go through profile_t static or non static member. 00065 */ 00066 static enum profile_type is_spu_sample_file(std::string const & filename); 00067 00068 /** 00069 * cumulate sample file to our container of samples 00070 * @param filename sample file name 00071 * 00072 * store samples for one sample file, sample file header is sanitized. 00073 * 00074 * all error are fatal 00075 */ 00076 void add_sample_file(std::string const & filename); 00077 00078 /// Set an appropriate start offset, see comments below. 00079 void set_offset(op_bfd const & abfd); 00080 00081 class const_iterator; 00082 typedef std::pair<const_iterator, const_iterator> iterator_pair; 00083 00084 /** 00085 * @param start start offset 00086 * @param end end offset 00087 * 00088 * return an iterator pair to [start, end) range 00089 */ 00090 iterator_pair 00091 samples_range(odb_key_t start, odb_key_t end) const; 00092 00093 /// return a pair of iterator for all samples 00094 iterator_pair samples_range() const; 00095 00096 private: 00097 /// helper for sample_count() and add_sample_file(). All error launch 00098 /// an exception. 00099 static void 00100 open_sample_file(std::string const & filename, odb_t &); 00101 00102 /// copy of the samples file header 00103 scoped_ptr<opd_header> file_header; 00104 00105 /// storage type for samples sorted by eip 00106 typedef std::map<odb_key_t, count_type> ordered_samples_t; 00107 00108 /** 00109 * Samples are stored in hash table, iterating over hash table don't 00110 * provide any ordering, the above count() interface rely on samples 00111 * ordered by eip. This map is only a temporary storage where samples 00112 * are ordered by eip. 00113 */ 00114 ordered_samples_t ordered_samples; 00115 00116 /** 00117 * For certain profiles, such as kernel/modules, and anon 00118 * regions with a matching binary, this value is non-zero, 00119 * and represents the file offset of the relevant section. 00120 * 00121 * For kernel profiles, this is done because we use the information 00122 * provided in /proc/ksyms, which only gives the mapped position of 00123 * .text, and the symbol _text from vmlinux. This value is used to fix 00124 * up the sample offsets for kernel code as a result of this difference 00125 * 00126 * In user-space samples, the sample offset is from the start of the 00127 * mapped file, as seen in /proc/pid/maps. This is fine for 00128 * mappings of permanent files, but with anon mappings, we need 00129 * to adjust the key values to be a file offset against the 00130 * *binary* (if there is one). This can obviously be different. 00131 * So we pass our anon mapping start VMA to op_bfd, which looks 00132 * for a section with that VMA, then returns the section's 00133 * filepos. So all is good. 00134 * 00135 * Finally, note that for cg we can't use this inside the 00136 * profile_t, as we're storing two offsets in the key value. So 00137 * we do it later in that case. 00138 * 00139 * Phew. 00140 */ 00141 u64 start_offset; 00142 }; 00143 00144 00145 // It will be easier to derive profile_t::const_iterator from 00146 // std::iterator<std::input_iterator_tag, unsigned int> but this doesn't 00147 // work for gcc <= 2.95 so we provide the neccessary typedef in the hard way. 00148 // See ISO C++ 17.4.3.1 § 1 and 14.7.3 § 9. 00149 namespace std { 00150 template <> 00151 struct iterator_traits<profile_t::const_iterator> { 00152 typedef ptrdiff_t difference_type; 00153 typedef count_type value_type; 00154 typedef count_type * pointer; 00155 typedef count_type & reference; 00156 typedef input_iterator_tag iterator_category; 00157 }; 00158 } 00159 00160 00161 class profile_t::const_iterator 00162 { 00163 typedef ordered_samples_t::const_iterator iterator_t; 00164 public: 00165 const_iterator() : start_offset(0) {} 00166 const_iterator(iterator_t it_, u64 start_offset_) 00167 : it(it_), start_offset(start_offset_) {} 00168 00169 count_type operator*() const { return it->second; } 00170 const_iterator & operator++() { ++it; return *this; } 00171 00172 odb_key_t vma() const { return it->first + start_offset; } 00173 count_type count() const { return **this; } 00174 00175 bool operator!=(const_iterator const & rhs) const { 00176 return it != rhs.it; 00177 } 00178 bool operator==(const_iterator const & rhs) const { 00179 return it == rhs.it; 00180 } 00181 00182 private: 00183 iterator_t it; 00184 u64 start_offset; 00185 }; 00186 00187 #endif /* !PROFILE_H */
1.6.1