arrange_profiles.h revision cc2ee177dbb3befca43e36cfc56778b006c3d050
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 */ 25struct 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 */ 38struct 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 */ 51struct 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 */ 72struct 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 */ 89struct 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 */ 105struct 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 */ 123enum axis_types { 124 AXIS_EVENT, 125 AXIS_TGID, 126 AXIS_TID, 127 AXIS_CPU, 128 AXIS_MAX 129}; 130 131 132struct 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 157std::ostream & operator<<(std::ostream &, profile_sample_files const &); 158std::ostream & operator<<(std::ostream &, profile_dep_set const &); 159std::ostream & operator<<(std::ostream &, profile_set const &); 160std::ostream & operator<<(std::ostream &, profile_template const &); 161std::ostream & operator<<(std::ostream &, profile_class const &); 162std::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 */ 173profile_classes const 174arrange_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 */ 182struct 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 191typedef 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 */ 210struct 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 223class 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 */ 241std::list<inverted_profile> const 242invert_profiles(std::string archive_path, profile_classes const & classes, 243 extra_images const & extra); 244 245#endif /* !ARRANGE_PROFILES_H */ 246