| /** |
| * @file arrange_profiles.h |
| * Classify and process a list of candidate sample files |
| * into merged sets and classes. |
| * |
| * @remark Copyright 2003 OProfile authors |
| * @remark Read the file COPYING |
| * |
| * @author John Levon |
| */ |
| |
| #ifndef ARRANGE_PROFILES_H |
| #define ARRANGE_PROFILES_H |
| |
| #include <string> |
| #include <list> |
| #include <vector> |
| #include <iosfwd> |
| |
| #include "image_errors.h" |
| #include "locate_images.h" |
| |
| /** |
| * store merging options options used to classify profiles |
| */ |
| struct merge_option { |
| bool cpu; |
| bool lib; |
| bool tid; |
| bool tgid; |
| bool unitmask; |
| }; |
| |
| |
| /** |
| * This describes which parameters are set for each |
| * equivalence class. |
| */ |
| struct profile_template { |
| std::string event; |
| std::string count; |
| std::string unitmask; |
| std::string tgid; |
| std::string tid; |
| std::string cpu; |
| }; |
| |
| |
| /** |
| * A samples filename + its associated callgraph sample filename. |
| */ |
| struct profile_sample_files { |
| /** |
| * This member can be empty since it is possible to get callgraph |
| * w/o any samples to the binary. e.g an application which defer all |
| * works to shared library but if arrange_profiles receive a sample |
| * file list filtered from cg file sample_filename can't be empty |
| */ |
| std::string sample_filename; |
| /** |
| * List of callgraph sample filename. If the {dep} part of |
| * cg_filename != {cg} part it's a cross binary samples file. |
| */ |
| std::list<std::string> cg_files; |
| }; |
| |
| |
| /** |
| * A number of profiles files that are all dependent on |
| * the same main (application) profile, for the same |
| * dependent image. |
| */ |
| struct profile_dep_set { |
| /// which dependent image is this set for |
| std::string lib_image; |
| |
| /// the actual sample files optionnaly including callgraph sample files |
| std::list<profile_sample_files> files; |
| }; |
| |
| /** |
| * A number of profile files all for the same binary with the same |
| * profile specification (after merging). Includes the set of dependent |
| * profile files, if any. |
| * |
| * For example, we could have image == "/bin/bash", where files |
| * contains all profiles against /bin/bash, and deps contains |
| * the sample file list for /lib/libc.so, /lib/ld.so etc. |
| */ |
| struct profile_set { |
| std::string image; |
| |
| /// the actual sample files for the main image and the asociated |
| /// callgraph files |
| std::list<profile_sample_files> files; |
| |
| /// all profile files dependent on the main image |
| std::list<profile_dep_set> deps; |
| }; |
| |
| |
| /** |
| * A class collection of profiles. This is an equivalence class and |
| * will correspond to columnar output of opreport. |
| */ |
| struct profile_class { |
| std::list<profile_set> profiles; |
| |
| /// human-readable column name |
| std::string name; |
| |
| /// human-readable long name |
| std::string longname; |
| |
| /// merging matches against this |
| profile_template ptemplate; |
| }; |
| |
| |
| /** |
| * The "axis" says what we've used to split the sample |
| * files into the classes. Only one is allowed. |
| */ |
| enum axis_types { |
| AXIS_EVENT, |
| AXIS_TGID, |
| AXIS_TID, |
| AXIS_CPU, |
| AXIS_MAX |
| }; |
| |
| |
| struct profile_classes { |
| /** |
| * This is only set if we're not classifying on event/count |
| * anyway - if we're classifying on event/count, then we'll |
| * already output the details of each class's event/count. |
| * |
| * It's only used when classifying by CPU, tgid etc. so the |
| * user can still see what perfctr event was used. |
| */ |
| std::string event; |
| |
| /// CPU info |
| std::string cpuinfo; |
| |
| /// the actual classes |
| std::vector<profile_class> v; |
| |
| /// the axis of the classes |
| axis_types axis; |
| |
| /// the extra images to consider for this profile_classes |
| extra_images extra_found_images; |
| |
| /// is this class set comparable with another? |
| bool matches(profile_classes const & classes); |
| }; |
| |
| |
| std::ostream & operator<<(std::ostream &, profile_sample_files const &); |
| std::ostream & operator<<(std::ostream &, profile_dep_set const &); |
| std::ostream & operator<<(std::ostream &, profile_set const &); |
| std::ostream & operator<<(std::ostream &, profile_template const &); |
| std::ostream & operator<<(std::ostream &, profile_class const &); |
| std::ostream & operator<<(std::ostream &, profile_classes const &); |
| |
| |
| /** |
| * Take a list of sample filenames, and process them into a set of |
| * classes containing profile_sets. Merging is done at this stage |
| * as well as attaching dependent profiles to the main image. |
| * |
| * The classes correspond to the columns you'll get in opreport: |
| * this can be a number of events, or different CPUs, etc. |
| */ |
| profile_classes const |
| arrange_profiles(std::list<std::string> const & files, |
| merge_option const & merge_by, extra_images const & extra); |
| |
| |
| /** |
| * A set of sample files where the image binary to open |
| * are all the same. |
| */ |
| struct image_set { |
| /// this is main app image, *not* necessarily |
| /// the one we need to open |
| std::string app_image; |
| |
| /// the sample files |
| std::list<profile_sample_files> files; |
| }; |
| |
| typedef std::list<image_set> image_group_set; |
| |
| /** |
| * All sample files where the binary image to open is |
| * the same. |
| * |
| * This is the "inverse" to some degree of profile_set. |
| * For example, here we might have image = "/lib/libc.so", |
| * with groups being the profile classifications |
| * tgid:404, tgid:301, etc. |
| * |
| * Within each group there's a number of image_sets. |
| * All the sample files listed within the image_sets |
| * are still for /lib/libc.so, but they may have |
| * different app_image values, e.g. /bin/bash. |
| * We need to keep track of the app_image values to |
| * make opreport give the right info in the "app" |
| * column. |
| */ |
| struct inverted_profile { |
| inverted_profile() : error(image_ok) {} |
| /// the image to open |
| std::string image; |
| |
| /// an error found in reading the image |
| mutable image_error error; |
| |
| /// all sample files with data for the above image |
| std::vector<image_group_set> groups; |
| }; |
| |
| |
| /** |
| * Invert the profile set. For opreport -l, opannotate etc., |
| * processing the profile_classes directly is slow, because |
| * we end up opening BFDs multiple times (for each class, |
| * dependent images etc.). This function returns an inverted |
| * set of sample files, where the primary sort is on the binary |
| * image to open. |
| * |
| * Thus each element in the returned list is for exactly one |
| * binary file that we're going to bfd_openr(). Attached to that |
| * is the actual sample files we need to process for that binary |
| * file. In order to get the output right, these have to be |
| * marked with the profile class they're from (hence the groups |
| * vector), and the app image that owned the sample file, if |
| * applicable (hence image_set). |
| */ |
| std::list<inverted_profile> const |
| invert_profiles(profile_classes const & classes); |
| |
| #endif /* !ARRANGE_PROFILES_H */ |