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