Upstream | cc2ee17 | 1970-01-12 13:46:40 +0000 | [diff] [blame^] | 1 | /** |
| 2 | * @file arrange_profiles.h |
| 3 | * Classify and process a list of candidate sample files |
| 4 | * into merged sets and classes. |
| 5 | * |
| 6 | * @remark Copyright 2003 OProfile authors |
| 7 | * @remark Read the file COPYING |
| 8 | * |
| 9 | * @author John Levon |
| 10 | */ |
| 11 | |
| 12 | #ifndef ARRANGE_PROFILES_H |
| 13 | #define ARRANGE_PROFILES_H |
| 14 | |
| 15 | #include <string> |
| 16 | #include <list> |
| 17 | #include <vector> |
| 18 | #include <iosfwd> |
| 19 | |
| 20 | #include "image_errors.h" |
| 21 | |
| 22 | /** |
| 23 | * store merging options options used to classify profiles |
| 24 | */ |
| 25 | struct merge_option { |
| 26 | bool cpu; |
| 27 | bool lib; |
| 28 | bool tid; |
| 29 | bool tgid; |
| 30 | bool unitmask; |
| 31 | }; |
| 32 | |
| 33 | |
| 34 | /** |
| 35 | * This describes which parameters are set for each |
| 36 | * equivalence class. |
| 37 | */ |
| 38 | struct profile_template { |
| 39 | std::string event; |
| 40 | std::string count; |
| 41 | std::string unitmask; |
| 42 | std::string tgid; |
| 43 | std::string tid; |
| 44 | std::string cpu; |
| 45 | }; |
| 46 | |
| 47 | |
| 48 | /** |
| 49 | * A samples filename + its associated callgraph sample filename. |
| 50 | */ |
| 51 | struct profile_sample_files { |
| 52 | /** |
| 53 | * This member can be empty since it is possible to get callgraph |
| 54 | * w/o any samples to the binary. e.g an application which defer all |
| 55 | * works to shared library but if arrange_profiles receive a sample |
| 56 | * file list filtered from cg file sample_filename can't be empty |
| 57 | */ |
| 58 | std::string sample_filename; |
| 59 | /** |
| 60 | * List of callgraph sample filename. If the {dep} part of |
| 61 | * cg_filename != {cg} part it's a cross binary samples file. |
| 62 | */ |
| 63 | std::list<std::string> cg_files; |
| 64 | }; |
| 65 | |
| 66 | |
| 67 | /** |
| 68 | * A number of profiles files that are all dependent on |
| 69 | * the same main (application) profile, for the same |
| 70 | * dependent image. |
| 71 | */ |
| 72 | struct profile_dep_set { |
| 73 | /// which dependent image is this set for |
| 74 | std::string lib_image; |
| 75 | |
| 76 | /// the actual sample files optionnaly including callgraph sample files |
| 77 | std::list<profile_sample_files> files; |
| 78 | }; |
| 79 | |
| 80 | /** |
| 81 | * A number of profile files all for the same binary with the same |
| 82 | * profile specification (after merging). Includes the set of dependent |
| 83 | * profile files, if any. |
| 84 | * |
| 85 | * For example, we could have image == "/bin/bash", where files |
| 86 | * contains all profiles against /bin/bash, and deps contains |
| 87 | * the sample file list for /lib/libc.so, /lib/ld.so etc. |
| 88 | */ |
| 89 | struct profile_set { |
| 90 | std::string image; |
| 91 | |
| 92 | /// the actual sample files for the main image and the asociated |
| 93 | /// callgraph files |
| 94 | std::list<profile_sample_files> files; |
| 95 | |
| 96 | /// all profile files dependent on the main image |
| 97 | std::list<profile_dep_set> deps; |
| 98 | }; |
| 99 | |
| 100 | |
| 101 | /** |
| 102 | * A class collection of profiles. This is an equivalence class and |
| 103 | * will correspond to columnar output of opreport. |
| 104 | */ |
| 105 | struct profile_class { |
| 106 | std::list<profile_set> profiles; |
| 107 | |
| 108 | /// human-readable column name |
| 109 | std::string name; |
| 110 | |
| 111 | /// human-readable long name |
| 112 | std::string longname; |
| 113 | |
| 114 | /// merging matches against this |
| 115 | profile_template ptemplate; |
| 116 | }; |
| 117 | |
| 118 | |
| 119 | /** |
| 120 | * The "axis" says what we've used to split the sample |
| 121 | * files into the classes. Only one is allowed. |
| 122 | */ |
| 123 | enum axis_types { |
| 124 | AXIS_EVENT, |
| 125 | AXIS_TGID, |
| 126 | AXIS_TID, |
| 127 | AXIS_CPU, |
| 128 | AXIS_MAX |
| 129 | }; |
| 130 | |
| 131 | |
| 132 | struct profile_classes { |
| 133 | /** |
| 134 | * This is only set if we're not classifying on event/count |
| 135 | * anyway - if we're classifying on event/count, then we'll |
| 136 | * already output the details of each class's event/count. |
| 137 | * |
| 138 | * It's only used when classifying by CPU, tgid etc. so the |
| 139 | * user can still see what perfctr event was used. |
| 140 | */ |
| 141 | std::string event; |
| 142 | |
| 143 | /// CPU info |
| 144 | std::string cpuinfo; |
| 145 | |
| 146 | /// the actual classes |
| 147 | std::vector<profile_class> v; |
| 148 | |
| 149 | /// the axis of the classes |
| 150 | axis_types axis; |
| 151 | |
| 152 | /// is this class set comparable with another? |
| 153 | bool matches(profile_classes const & classes); |
| 154 | }; |
| 155 | |
| 156 | |
| 157 | std::ostream & operator<<(std::ostream &, profile_sample_files const &); |
| 158 | std::ostream & operator<<(std::ostream &, profile_dep_set const &); |
| 159 | std::ostream & operator<<(std::ostream &, profile_set const &); |
| 160 | std::ostream & operator<<(std::ostream &, profile_template const &); |
| 161 | std::ostream & operator<<(std::ostream &, profile_class const &); |
| 162 | std::ostream & operator<<(std::ostream &, profile_classes const &); |
| 163 | |
| 164 | |
| 165 | /** |
| 166 | * Take a list of sample filenames, and process them into a set of |
| 167 | * classes containing profile_sets. Merging is done at this stage |
| 168 | * as well as attaching dependent profiles to the main image. |
| 169 | * |
| 170 | * The classes correspond to the columns you'll get in opreport: |
| 171 | * this can be a number of events, or different CPUs, etc. |
| 172 | */ |
| 173 | profile_classes const |
| 174 | arrange_profiles(std::list<std::string> const & files, |
| 175 | merge_option const & merge_by); |
| 176 | |
| 177 | |
| 178 | /** |
| 179 | * A set of sample files where the image binary to open |
| 180 | * are all the same. |
| 181 | */ |
| 182 | struct image_set { |
| 183 | /// this is main app image, *not* necessarily |
| 184 | /// the one we need to open |
| 185 | std::string app_image; |
| 186 | |
| 187 | /// the sample files |
| 188 | std::list<profile_sample_files> files; |
| 189 | }; |
| 190 | |
| 191 | typedef std::list<image_set> image_group_set; |
| 192 | |
| 193 | /** |
| 194 | * All sample files where the binary image to open is |
| 195 | * the same. |
| 196 | * |
| 197 | * This is the "inverse" to some degree of profile_set. |
| 198 | * For example, here we might have image = "/lib/libc.so", |
| 199 | * with groups being the profile classifications |
| 200 | * tgid:404, tgid:301, etc. |
| 201 | * |
| 202 | * Within each group there's a number of image_sets. |
| 203 | * All the sample files listed within the image_sets |
| 204 | * are still for /lib/libc.so, but they may have |
| 205 | * different app_image values, e.g. /bin/bash. |
| 206 | * We need to keep track of the app_image values to |
| 207 | * make opreport give the right info in the "app" |
| 208 | * column. |
| 209 | */ |
| 210 | struct inverted_profile { |
| 211 | inverted_profile() : error(image_ok) {} |
| 212 | /// the image to open |
| 213 | std::string image; |
| 214 | |
| 215 | /// an error found in reading the image |
| 216 | mutable image_error error; |
| 217 | |
| 218 | /// all sample files with data for the above image |
| 219 | std::vector<image_group_set> groups; |
| 220 | }; |
| 221 | |
| 222 | |
| 223 | class extra_images; |
| 224 | |
| 225 | /** |
| 226 | * Invert the profile set. For opreport -l, opannotate etc., |
| 227 | * processing the profile_classes directly is slow, because |
| 228 | * we end up opening BFDs multiple times (for each class, |
| 229 | * dependent images etc.). This function returns an inverted |
| 230 | * set of sample files, where the primary sort is on the binary |
| 231 | * image to open. |
| 232 | * |
| 233 | * Thus each element in the returned list is for exactly one |
| 234 | * binary file that we're going to bfd_openr(). Attached to that |
| 235 | * is the actual sample files we need to process for that binary |
| 236 | * file. In order to get the output right, these have to be |
| 237 | * marked with the profile class they're from (hence the groups |
| 238 | * vector), and the app image that owned the sample file, if |
| 239 | * applicable (hence image_set). |
| 240 | */ |
| 241 | std::list<inverted_profile> const |
| 242 | invert_profiles(std::string archive_path, profile_classes const & classes, |
| 243 | extra_images const & extra); |
| 244 | |
| 245 | #endif /* !ARRANGE_PROFILES_H */ |