• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
26 struct 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  */
39 struct 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  */
52 struct 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  */
73 struct 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  */
90 struct 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  */
106 struct 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  */
124 enum axis_types {
125 	AXIS_EVENT,
126 	AXIS_TGID,
127 	AXIS_TID,
128 	AXIS_CPU,
129 	AXIS_MAX
130 };
131 
132 
133 struct 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 
161 std::ostream & operator<<(std::ostream &, profile_sample_files const &);
162 std::ostream & operator<<(std::ostream &, profile_dep_set const &);
163 std::ostream & operator<<(std::ostream &, profile_set const &);
164 std::ostream & operator<<(std::ostream &, profile_template const &);
165 std::ostream & operator<<(std::ostream &, profile_class const &);
166 std::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  */
177 profile_classes const
178 arrange_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  */
186 struct 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 
195 typedef 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  */
214 struct inverted_profile {
inverted_profileinverted_profile215 	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  */
243 std::list<inverted_profile> const
244 invert_profiles(profile_classes const & classes);
245 
246 #endif /* !ARRANGE_PROFILES_H */
247