00001 /** 00002 * @file arrange_profiles.h 00003 * Classify and process a list of candidate sample files 00004 * into merged sets and classes. 00005 * 00006 * @remark Copyright 2003 OProfile authors 00007 * @remark Read the file COPYING 00008 * 00009 * @author John Levon 00010 */ 00011 00012 #ifndef ARRANGE_PROFILES_H 00013 #define ARRANGE_PROFILES_H 00014 00015 #include <string> 00016 #include <list> 00017 #include <vector> 00018 #include <iosfwd> 00019 00020 #include "image_errors.h" 00021 #include "locate_images.h" 00022 00023 /** 00024 * store merging options options used to classify profiles 00025 */ 00026 struct merge_option { 00027 bool cpu; 00028 bool lib; 00029 bool tid; 00030 bool tgid; 00031 bool unitmask; 00032 }; 00033 00034 00035 /** 00036 * This describes which parameters are set for each 00037 * equivalence class. 00038 */ 00039 struct profile_template { 00040 std::string event; 00041 std::string count; 00042 std::string unitmask; 00043 std::string tgid; 00044 std::string tid; 00045 std::string cpu; 00046 }; 00047 00048 00049 /** 00050 * A samples filename + its associated callgraph sample filename. 00051 */ 00052 struct profile_sample_files { 00053 /** 00054 * This member can be empty since it is possible to get callgraph 00055 * w/o any samples to the binary. e.g an application which defer all 00056 * works to shared library but if arrange_profiles receive a sample 00057 * file list filtered from cg file sample_filename can't be empty 00058 */ 00059 std::string sample_filename; 00060 /** 00061 * List of callgraph sample filename. If the {dep} part of 00062 * cg_filename != {cg} part it's a cross binary samples file. 00063 */ 00064 std::list<std::string> cg_files; 00065 }; 00066 00067 00068 /** 00069 * A number of profiles files that are all dependent on 00070 * the same main (application) profile, for the same 00071 * dependent image. 00072 */ 00073 struct profile_dep_set { 00074 /// which dependent image is this set for 00075 std::string lib_image; 00076 00077 /// the actual sample files optionnaly including callgraph sample files 00078 std::list<profile_sample_files> files; 00079 }; 00080 00081 /** 00082 * A number of profile files all for the same binary with the same 00083 * profile specification (after merging). Includes the set of dependent 00084 * profile files, if any. 00085 * 00086 * For example, we could have image == "/bin/bash", where files 00087 * contains all profiles against /bin/bash, and deps contains 00088 * the sample file list for /lib/libc.so, /lib/ld.so etc. 00089 */ 00090 struct profile_set { 00091 std::string image; 00092 00093 /// the actual sample files for the main image and the asociated 00094 /// callgraph files 00095 std::list<profile_sample_files> files; 00096 00097 /// all profile files dependent on the main image 00098 std::list<profile_dep_set> deps; 00099 }; 00100 00101 00102 /** 00103 * A class collection of profiles. This is an equivalence class and 00104 * will correspond to columnar output of opreport. 00105 */ 00106 struct profile_class { 00107 std::list<profile_set> profiles; 00108 00109 /// human-readable column name 00110 std::string name; 00111 00112 /// human-readable long name 00113 std::string longname; 00114 00115 /// merging matches against this 00116 profile_template ptemplate; 00117 }; 00118 00119 00120 /** 00121 * The "axis" says what we've used to split the sample 00122 * files into the classes. Only one is allowed. 00123 */ 00124 enum axis_types { 00125 AXIS_EVENT, 00126 AXIS_TGID, 00127 AXIS_TID, 00128 AXIS_CPU, 00129 AXIS_MAX 00130 }; 00131 00132 00133 struct profile_classes { 00134 /** 00135 * This is only set if we're not classifying on event/count 00136 * anyway - if we're classifying on event/count, then we'll 00137 * already output the details of each class's event/count. 00138 * 00139 * It's only used when classifying by CPU, tgid etc. so the 00140 * user can still see what perfctr event was used. 00141 */ 00142 std::string event; 00143 00144 /// CPU info 00145 std::string cpuinfo; 00146 00147 /// the actual classes 00148 std::vector<profile_class> v; 00149 00150 /// the axis of the classes 00151 axis_types axis; 00152 00153 /// the extra images to consider for this profile_classes 00154 extra_images extra_found_images; 00155 00156 /// is this class set comparable with another? 00157 bool matches(profile_classes const & classes); 00158 }; 00159 00160 00161 std::ostream & operator<<(std::ostream &, profile_sample_files const &); 00162 std::ostream & operator<<(std::ostream &, profile_dep_set const &); 00163 std::ostream & operator<<(std::ostream &, profile_set const &); 00164 std::ostream & operator<<(std::ostream &, profile_template const &); 00165 std::ostream & operator<<(std::ostream &, profile_class const &); 00166 std::ostream & operator<<(std::ostream &, profile_classes const &); 00167 00168 00169 /** 00170 * Take a list of sample filenames, and process them into a set of 00171 * classes containing profile_sets. Merging is done at this stage 00172 * as well as attaching dependent profiles to the main image. 00173 * 00174 * The classes correspond to the columns you'll get in opreport: 00175 * this can be a number of events, or different CPUs, etc. 00176 */ 00177 profile_classes const 00178 arrange_profiles(std::list<std::string> const & files, 00179 merge_option const & merge_by, extra_images const & extra); 00180 00181 00182 /** 00183 * A set of sample files where the image binary to open 00184 * are all the same. 00185 */ 00186 struct image_set { 00187 /// this is main app image, *not* necessarily 00188 /// the one we need to open 00189 std::string app_image; 00190 00191 /// the sample files 00192 std::list<profile_sample_files> files; 00193 }; 00194 00195 typedef std::list<image_set> image_group_set; 00196 00197 /** 00198 * All sample files where the binary image to open is 00199 * the same. 00200 * 00201 * This is the "inverse" to some degree of profile_set. 00202 * For example, here we might have image = "/lib/libc.so", 00203 * with groups being the profile classifications 00204 * tgid:404, tgid:301, etc. 00205 * 00206 * Within each group there's a number of image_sets. 00207 * All the sample files listed within the image_sets 00208 * are still for /lib/libc.so, but they may have 00209 * different app_image values, e.g. /bin/bash. 00210 * We need to keep track of the app_image values to 00211 * make opreport give the right info in the "app" 00212 * column. 00213 */ 00214 struct inverted_profile { 00215 inverted_profile() : error(image_ok) {} 00216 /// the image to open 00217 std::string image; 00218 00219 /// an error found in reading the image 00220 mutable image_error error; 00221 00222 /// all sample files with data for the above image 00223 std::vector<image_group_set> groups; 00224 }; 00225 00226 00227 /** 00228 * Invert the profile set. For opreport -l, opannotate etc., 00229 * processing the profile_classes directly is slow, because 00230 * we end up opening BFDs multiple times (for each class, 00231 * dependent images etc.). This function returns an inverted 00232 * set of sample files, where the primary sort is on the binary 00233 * image to open. 00234 * 00235 * Thus each element in the returned list is for exactly one 00236 * binary file that we're going to bfd_openr(). Attached to that 00237 * is the actual sample files we need to process for that binary 00238 * file. In order to get the output right, these have to be 00239 * marked with the profile class they're from (hence the groups 00240 * vector), and the app image that owned the sample file, if 00241 * applicable (hence image_set). 00242 */ 00243 std::list<inverted_profile> const 00244 invert_profiles(profile_classes const & classes); 00245 00246 #endif /* !ARRANGE_PROFILES_H */
1.6.1