arrange_profiles.h

Go to the documentation of this file.
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 */

Generated on Thu Jul 17 19:52:46 2008 for oprofile by  doxygen 1.4.6