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