af710487 |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (c) 2000-2015 Ericsson Telecom AB |
3 | // All rights reserved. This program and the accompanying materials |
4 | // are made available under the terms of the Eclipse Public License v1.0 |
5 | // which accompanies this distribution, and is available at |
6 | // http://www.eclipse.org/legal/epl-v10.html |
7 | /////////////////////////////////////////////////////////////////////////////// |
8 | |
9 | #ifndef PROFILER_HH |
10 | #define PROFILER_HH |
11 | |
12 | #include "Vector.hh" |
13 | #include "Types.h" |
a38c6d4c |
14 | #include <sys/time.h> |
af710487 |
15 | |
16 | /** This class performs profiling and code coverage on lines and functions in |
17 | * TTCN-3 code (requires the -z compiler option). |
18 | * Customizable through the configuration file's [PROFILER] section. */ |
19 | class TTCN3_Profiler { |
20 | public: |
21 | |
22 | /** Database entry for one file */ |
23 | struct profiler_db_item_t { |
24 | /** Database entry for one line */ |
25 | struct profiler_line_data_t { |
a38c6d4c |
26 | /** Line number */ |
27 | int lineno; |
af710487 |
28 | /** The line's total execution time */ |
a38c6d4c |
29 | timeval total_time; |
af710487 |
30 | /** The number of times this line was executed */ |
31 | int exec_count; |
32 | }; |
33 | /** Database entry for one function (including test cases, alt steps, the control part, etc.) */ |
34 | struct profiler_function_data_t { |
35 | /** Function name (owned) */ |
36 | char* name; |
37 | /** Function starting line */ |
38 | int lineno; |
39 | /** The function's total execution time */ |
a38c6d4c |
40 | timeval total_time; |
af710487 |
41 | /** The number of times this function was executed */ |
42 | int exec_count; |
43 | }; |
44 | /** TTCN-3 File name (relative path, owned) */ |
45 | char* filename; |
a38c6d4c |
46 | /** Contains database entries for all the lines in this file */ |
af710487 |
47 | Vector<profiler_line_data_t> lines; |
a38c6d4c |
48 | /** Contains database entries for all the functions in this file */ |
af710487 |
49 | Vector<profiler_function_data_t> functions; |
50 | }; |
51 | |
a38c6d4c |
52 | enum profiler_stats_flag_t { |
53 | // flags for each statistics entry |
54 | STATS_NUMBER_OF_LINES = 0x0000001, |
55 | STATS_LINE_DATA_RAW = 0x0000002, |
56 | STATS_FUNC_DATA_RAW = 0x0000004, |
57 | STATS_LINE_AVG_RAW = 0x0000008, |
58 | STATS_FUNC_AVG_RAW = 0x0000010, |
59 | STATS_LINE_TIMES_SORTED_BY_MOD = 0x0000020, |
60 | STATS_FUNC_TIMES_SORTED_BY_MOD = 0x0000040, |
61 | STATS_LINE_TIMES_SORTED_TOTAL = 0x0000080, |
62 | STATS_FUNC_TIMES_SORTED_TOTAL = 0x0000100, |
63 | STATS_LINE_COUNT_SORTED_BY_MOD = 0x0000200, |
64 | STATS_FUNC_COUNT_SORTED_BY_MOD = 0x0000400, |
65 | STATS_LINE_COUNT_SORTED_TOTAL = 0x0000800, |
66 | STATS_FUNC_COUNT_SORTED_TOTAL = 0x0001000, |
67 | STATS_LINE_AVG_SORTED_BY_MOD = 0x0002000, |
68 | STATS_FUNC_AVG_SORTED_BY_MOD = 0x0004000, |
69 | STATS_LINE_AVG_SORTED_TOTAL = 0x0008000, |
70 | STATS_FUNC_AVG_SORTED_TOTAL = 0x0010000, |
71 | STATS_TOP10_LINE_TIMES = 0x0020000, |
72 | STATS_TOP10_FUNC_TIMES = 0x0040000, |
73 | STATS_TOP10_LINE_COUNT = 0x0080000, |
74 | STATS_TOP10_FUNC_COUNT = 0x0100000, |
75 | STATS_TOP10_LINE_AVG = 0x0200000, |
76 | STATS_TOP10_FUNC_AVG = 0x0400000, |
77 | STATS_UNUSED_LINES = 0x0800000, |
78 | STATS_UNUSED_FUNC = 0x1000000, |
79 | // grouped entries |
80 | STATS_ALL_RAW_DATA = 0x000001E, |
81 | STATS_LINE_DATA_SORTED_BY_MOD = 0x0002220, |
82 | STATS_FUNC_DATA_SORTED_BY_MOD = 0x0004440, |
83 | STATS_LINE_DATA_SORTED_TOTAL = 0x0008880, |
84 | STATS_FUNC_DATA_SORTED_TOTAL = 0x0011100, |
85 | STATS_LINE_DATA_SORTED = 0x000AAA0, |
86 | STATS_FUNC_DATA_SORTED = 0x0015540, |
87 | STATS_ALL_DATA_SORTED = 0x001FFE0, |
88 | STATS_TOP10_LINE_DATA = 0x02A0000, |
89 | STATS_TOP10_FUNC_DATA = 0x0540000, |
90 | STATS_TOP10_ALL_DATA = 0x07E0000, |
91 | STATS_UNUSED_DATA = 0x1800000, |
92 | STATS_ALL = 0x1FFFFFF |
93 | }; |
94 | |
af710487 |
95 | /** Constructor */ |
96 | TTCN3_Profiler(); |
a38c6d4c |
97 | /** Destructor |
98 | * In single mode and in the Host Controller's process in parallel mode: |
99 | * - imports data gathered on the previous run (if data aggregation is set) |
100 | * - imports data gathered by all other processes (only in parallel mode) |
101 | * - prints statistics (if necessary) |
102 | * Afterwards, in all cases: |
103 | * - exports data gathered in this process (including any imported data) |
104 | * - frees allocated memory */ |
af710487 |
105 | ~TTCN3_Profiler(); |
106 | |
a38c6d4c |
107 | /** Reactivates the profiler if it was stopped before, data gathering will resume */ |
108 | void start(); |
109 | /** Deactivates the profiler, no more data will be gathered until it is reactivated */ |
110 | void stop(); |
111 | |
af710487 |
112 | /** Enables or disables profiling - called by the config file parser */ |
113 | void set_disable_profiler(boolean p_disable_profiler); |
114 | /** Enables or disables code coverage - called by the config file parser */ |
115 | void set_disable_coverage(boolean p_disable_coverage); |
116 | /** Sets the database file name (default is "profiler.db" - called by the config file parser */ |
117 | void set_database_filename(const char* p_database_filename); |
118 | /** Enables or disables data aggregation - called by the config file parser */ |
119 | void set_aggregate_data(boolean p_aggregate_data); |
120 | /** Sets the statistics file name (default is "profiler.stats" - called by the config file parser */ |
121 | void set_stats_filename(const char* p_stats_filename); |
122 | /** Enables or disables the printing of statistics - called by the config file parser */ |
123 | void set_disable_stats(boolean p_disable_stats); |
a38c6d4c |
124 | /** Disables all statistics entry flags - called by the config file parser */ |
125 | void reset_stats_flags(); |
126 | /** Enables the specified statistics entry flags - called by the config file parser */ |
127 | void add_stats_flags(unsigned int p_flags); |
af710487 |
128 | |
129 | /** Returns true if profiling is disabled */ |
130 | boolean is_profiler_disabled() const; |
a38c6d4c |
131 | /** Returns true if the profiler is currently running (not stopped) */ |
132 | boolean is_running() const; |
af710487 |
133 | |
a38c6d4c |
134 | /** Stores the component reference of a newly created PTC (in parallel mode only) */ |
135 | void add_ptc(component p_comp_ref); |
136 | |
af710487 |
137 | /** Adds the data from the database file to the local database */ |
a38c6d4c |
138 | void import_data(component p_comp_ref = NULL_COMPREF); |
af710487 |
139 | /** Writes the local database to the database file (overwrites the file) */ |
140 | void export_data(); |
141 | |
142 | /** Calculates and prints statistics from the gathered data */ |
143 | void print_stats(); |
144 | |
145 | /** Resets data related to the previous location and time (the local database is not changed) */ |
146 | void reset(); |
147 | /** Returns the current time (in seconds) */ |
a38c6d4c |
148 | static timeval get_time(); |
af710487 |
149 | /** Called when a TTCN-3 function starts execution - stores data */ |
a38c6d4c |
150 | void enter_function(const char* filename, int lineno); |
af710487 |
151 | /** Called when a TTCN-3 code line starts execution - stores data */ |
152 | void execute_line(const char* filename, int lineno); |
153 | /** Returns the index of a TTCN-3 file's entry in the local database */ |
154 | int get_element(const char* filename); |
155 | /** Returns the index of a TTCN-3 function's entry in the database |
156 | * @param element index of the file (where the function is declared) |
157 | * @param lineno function start line */ |
158 | int get_function(int element, int lineno); |
159 | /** Creates a new TTCN-3 function entry and inserts it in the database |
160 | * @param element file entry's index |
161 | * @param lineno function start line |
162 | * @param function_name name of the function */ |
163 | void create_function(int element, int lineno, const char* function_name); |
a38c6d4c |
164 | /** Returns the index of a TTCN-3 code line's entry in the database */ |
165 | int get_line(int element, int lineno); |
166 | /** Creates a new TTCN-3 code line entry and inserts it into the database */ |
167 | void create_line(int element, int lineno); |
af710487 |
168 | /** Adds elapsed time to the specified TTCN-3 code line's total time */ |
a38c6d4c |
169 | void add_line_time(timeval elapsed, int element, int lineno); |
af710487 |
170 | /** Adds elapsed time to the specified TTCN-3 function's total time*/ |
a38c6d4c |
171 | void add_function_time(timeval elapsed, int element, int lineno); |
af710487 |
172 | /** Called when a TTCN-3 function's execution ends - stores data */ |
173 | void update_last(); |
174 | /** Stores data related to the previous location */ |
175 | void set_prev(int stack_len, const char* filename, int lineno); |
176 | |
177 | private: |
a38c6d4c |
178 | /** If true, the profiler ignores execute_line, enter_function and update_last calls */ |
179 | boolean stopped; |
af710487 |
180 | /** Profiling is disabled if true */ |
181 | boolean disable_profiler; |
182 | /** Code coverage is disabled if true */ |
183 | boolean disable_coverage; |
184 | /** Contains the database file name */ |
185 | char* database_filename; |
186 | /** If true, data gathered by previous runs will be added to the data gathered |
187 | * in this run */ |
188 | boolean aggregate_data; |
189 | /** Contains the statistics file name */ |
190 | char* stats_filename; |
191 | /** Statistics will not be calculated and printed if true */ |
192 | boolean disable_stats; |
a38c6d4c |
193 | /** Flags that determine which statistics entries are displayed */ |
194 | unsigned int stats_flags; |
af710487 |
195 | /** The time measured at the previous TTCN-3 code line */ |
a38c6d4c |
196 | timeval prev_time; |
af710487 |
197 | /** Name of the TTCN-3 file, where the last executed line is (not owned) */ |
198 | const char* prev_file; |
199 | /** The number of the previously executed line */ |
200 | int prev_line; |
201 | /** The local database */ |
202 | Vector<profiler_db_item_t> profiler_db; |
203 | /** The stack length at the previously executed line */ |
204 | int prev_stack_len; |
a38c6d4c |
205 | /** Contains the component references of all PTCs (only relevant in the Host |
206 | * Controller's process, in parallel mode) */ |
207 | Vector<component> ptc_list; |
af710487 |
208 | }; |
209 | |
210 | /** The global TTCN3_Profiler object |
211 | * |
212 | * One instance is created in each process (in parallel mode). |
213 | * After construction the configuration file parser may change the profiler's settings. |
214 | * The destructor merges its data with that of other processes (and possibly with previous runs) |
215 | * through the database file. The last destructor (the one in the Host Controller's process) |
216 | * prints the statistics (if enabled). */ |
217 | extern TTCN3_Profiler ttcn3_prof; |
218 | |
219 | /** Helper class for profiling |
220 | * |
221 | * Its instances depict the current call stack. One instance is created at the start |
222 | * of each TTCN-3 function execution, and it's destroyed at the function's end. */ |
223 | class TTCN3_Stack_Depth { |
a38c6d4c |
224 | public: |
af710487 |
225 | /** Entry for one function call in the call stack */ |
226 | struct call_stack_timer_item_t { |
227 | /** Stack length before the function call */ |
228 | int stack_len; |
229 | /** File name, where the calling function is declared (not owned) */ |
230 | const char* caller_file; |
a38c6d4c |
231 | /** File name, where the called function is declared (not owned) */ |
af710487 |
232 | const char* func_file; |
233 | /** Calling function's start line */ |
234 | int caller_line; |
235 | /** Called function's start line */ |
236 | int start_line; |
237 | /** Time elapsed in this function call */ |
a38c6d4c |
238 | timeval elapsed; |
239 | /** If true, then this is the first entry of this function and caller pair |
240 | * (only used in case of gross line times) */ |
241 | boolean first_call; |
242 | /** If true, then this function has appeared before in the call stack |
243 | * (only used in case of gross function times)*/ |
244 | boolean recursive_call; |
af710487 |
245 | }; |
246 | |
247 | /** Constructor - increases the stack depth */ |
248 | TTCN3_Stack_Depth(); |
249 | /** Destructor - decreases the stack depth, updates call times in the profiler */ |
250 | ~TTCN3_Stack_Depth(); |
251 | |
a38c6d4c |
252 | /** Sets whether line times should include function call times - called by the config file parser */ |
253 | static void set_net_line_times(boolean p_net_line_times); |
254 | /** Sets whether function times should include embedded function times - called by the config file parser */ |
255 | static void set_net_func_times(boolean p_net_func_times); |
256 | |
af710487 |
257 | /** Returns the current stack depth */ |
258 | static int depth() { return current_depth; } |
259 | /** Inserts a new function call entry into the call stack database */ |
260 | static void add_stack(int stack_len, const char* caller_file, const char* func_file, |
261 | int caller_line, int start_line); |
262 | /** Removes the last entry from the call stack database */ |
263 | static void remove_stack(); |
264 | /** Adds the elapsed time to all entries in the call stack database */ |
a38c6d4c |
265 | static void update_stack_elapsed(timeval elapsed); |
af710487 |
266 | private: |
267 | /** The current stack depth (starts from 0)*/ |
268 | static int current_depth; |
269 | /** The call stack database */ |
270 | static Vector<call_stack_timer_item_t> call_stack_timer_db; |
a38c6d4c |
271 | /** If true, line times will not include the execution times of functions called |
272 | * in that line */ |
273 | static boolean net_line_times; |
274 | /** If true, function times will not include the execution times of functions |
275 | * called in that function */ |
276 | static boolean net_func_times; |
af710487 |
277 | }; |
278 | |
279 | #endif /* PROFILER_HH */ |
280 | |