blob: 8057c67c3c143822ff705e78b8714c33419c7079 [file] [log] [blame]
/**
* @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 */