| 1 | /****************************************************************************** |
| 2 | * Copyright (c) 2000-2016 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 | * Contributors: |
| 9 | * Balasko, Jeno |
| 10 | * Baranyi, Botond |
| 11 | * |
| 12 | ******************************************************************************/ |
| 13 | |
| 14 | #ifndef PROFILER_HH |
| 15 | #define PROFILER_HH |
| 16 | |
| 17 | #include <signal.h> |
| 18 | #include "ProfilerTools.hh" |
| 19 | |
| 20 | /** This class performs profiling and code coverage on lines and functions in |
| 21 | * TTCN-3 code (requires the -z compiler option). |
| 22 | * Customizable through the configuration file's [PROFILER] section. */ |
| 23 | class TTCN3_Profiler { |
| 24 | public: |
| 25 | |
| 26 | /** Constructor */ |
| 27 | TTCN3_Profiler(); |
| 28 | /** Destructor |
| 29 | * In single mode and in the Host Controller's process in parallel mode: |
| 30 | * - imports data gathered on the previous run (if data aggregation is set) |
| 31 | * - imports data gathered by all other processes (only in parallel mode) |
| 32 | * - prints statistics (if necessary) |
| 33 | * Afterwards, in all cases: |
| 34 | * - exports data gathered in this process (including any imported data) |
| 35 | * - frees allocated memory */ |
| 36 | ~TTCN3_Profiler(); |
| 37 | |
| 38 | /** Reactivates the profiler if it was stopped before, data gathering will resume */ |
| 39 | void start(); |
| 40 | /** Deactivates the profiler, no more data will be gathered until it is reactivated */ |
| 41 | void stop(); |
| 42 | |
| 43 | /** Enables or disables profiling - called by the config file parser */ |
| 44 | void set_disable_profiler(boolean p_disable_profiler); |
| 45 | /** Enables or disables code coverage - called by the config file parser */ |
| 46 | void set_disable_coverage(boolean p_disable_coverage); |
| 47 | /** Sets the database file name (default is "profiler.db" - called by the config file parser */ |
| 48 | void set_database_filename(const char* p_database_filename); |
| 49 | /** Enables or disables data aggregation - called by the config file parser */ |
| 50 | void set_aggregate_data(boolean p_aggregate_data); |
| 51 | /** Sets the statistics file name (default is "profiler.stats" - called by the config file parser */ |
| 52 | void set_stats_filename(const char* p_stats_filename); |
| 53 | /** Enables or disables the printing of statistics - called by the config file parser */ |
| 54 | void set_disable_stats(boolean p_disable_stats); |
| 55 | /** Disables all statistics entry flags - called by the config file parser */ |
| 56 | void reset_stats_flags(); |
| 57 | /** Enables the specified statistics entry flags - called by the config file parser */ |
| 58 | void add_stats_flags(unsigned int p_flags); |
| 59 | |
| 60 | /** Returns true if profiling is disabled */ |
| 61 | boolean is_profiler_disabled() const; |
| 62 | /** Returns true if the profiler is currently running (not stopped) */ |
| 63 | boolean is_running() const; |
| 64 | |
| 65 | /** Stores the PID of a newly created PTC or MTC (in parallel mode only) */ |
| 66 | void add_child_process(pid_t p_pid); |
| 67 | |
| 68 | /** Adds the data from the database file to the local database */ |
| 69 | void import_data(pid_t p_pid = 0); |
| 70 | /** Writes the local database to the database file (overwrites the file) */ |
| 71 | void export_data(); |
| 72 | |
| 73 | /** Calculates and prints statistics from the gathered data */ |
| 74 | void print_stats(); |
| 75 | |
| 76 | /** Resets data related to the previous location and time (the local database is not changed) */ |
| 77 | void reset(); |
| 78 | /** Returns the current time (in seconds) */ |
| 79 | static timeval get_time(); |
| 80 | /** Called when a TTCN-3 function starts execution - stores data */ |
| 81 | void enter_function(const char* filename, int lineno); |
| 82 | /** Called when a TTCN-3 code line starts execution - stores data */ |
| 83 | void execute_line(const char* filename, int lineno); |
| 84 | /** Returns the index of a TTCN-3 file's entry in the local database */ |
| 85 | int get_element(const char* filename); |
| 86 | /** Returns the index of a TTCN-3 function's entry in the database |
| 87 | * @param element index of the file (where the function is declared) |
| 88 | * @param lineno function start line */ |
| 89 | int get_function(int element, int lineno); |
| 90 | /** Creates a new TTCN-3 function entry and inserts it in the database |
| 91 | * @param element file entry's index |
| 92 | * @param lineno function start line |
| 93 | * @param function_name name of the function */ |
| 94 | void create_function(int element, int lineno, const char* function_name); |
| 95 | /** Returns the index of a TTCN-3 code line's entry in the database */ |
| 96 | int get_line(int element, int lineno); |
| 97 | /** Creates a new TTCN-3 code line entry and inserts it into the database */ |
| 98 | void create_line(int element, int lineno); |
| 99 | /** Adds elapsed time to the specified TTCN-3 code line's total time */ |
| 100 | void add_line_time(timeval elapsed, int element, int lineno); |
| 101 | /** Adds elapsed time to the specified TTCN-3 function's total time */ |
| 102 | void add_function_time(timeval elapsed, int element, int lineno); |
| 103 | /** Called when a TTCN-3 function's execution ends - stores data */ |
| 104 | void update_last(); |
| 105 | /** Stores data related to the previous location */ |
| 106 | void set_prev(int stack_len, const char* filename, int lineno); |
| 107 | |
| 108 | private: |
| 109 | /** If true, the profiler ignores execute_line, enter_function and update_last calls */ |
| 110 | boolean stopped; |
| 111 | /** Profiling is disabled if true */ |
| 112 | boolean disable_profiler; |
| 113 | /** Code coverage is disabled if true */ |
| 114 | boolean disable_coverage; |
| 115 | /** Contains the database file name */ |
| 116 | char* database_filename; |
| 117 | /** If true, data gathered by previous runs will be added to the data gathered |
| 118 | * in this run */ |
| 119 | boolean aggregate_data; |
| 120 | /** Contains the statistics file name */ |
| 121 | char* stats_filename; |
| 122 | /** Statistics will not be calculated and printed if true */ |
| 123 | boolean disable_stats; |
| 124 | /** Flags that determine which statistics entries are displayed */ |
| 125 | unsigned int stats_flags; |
| 126 | /** The time measured at the previous TTCN-3 code line */ |
| 127 | timeval prev_time; |
| 128 | /** Name of the TTCN-3 file, where the last executed line is (not owned) */ |
| 129 | const char* prev_file; |
| 130 | /** The number of the previously executed line */ |
| 131 | int prev_line; |
| 132 | /** The local database */ |
| 133 | Profiler_Tools::profiler_db_t profiler_db; |
| 134 | /** The stack length at the previously executed line */ |
| 135 | int prev_stack_len; |
| 136 | /** Contains the PIDs of the child processes (only relevant in the Host |
| 137 | * Controller's process, in parallel mode) */ |
| 138 | Vector<pid_t> pid_list; |
| 139 | }; |
| 140 | |
| 141 | /** The global TTCN3_Profiler object |
| 142 | * |
| 143 | * One instance is created in each process (in parallel mode). |
| 144 | * After construction the configuration file parser may change the profiler's settings. |
| 145 | * The destructor merges its data with that of other processes (and possibly with previous runs) |
| 146 | * through the database file. The last destructor (the one in the Host Controller's process) |
| 147 | * prints the statistics (if enabled). */ |
| 148 | extern TTCN3_Profiler ttcn3_prof; |
| 149 | |
| 150 | /** Helper class for profiling |
| 151 | * |
| 152 | * Its instances depict the current call stack. One instance is created at the start |
| 153 | * of each TTCN-3 function execution, and it's destroyed at the function's end. */ |
| 154 | class TTCN3_Stack_Depth { |
| 155 | public: |
| 156 | /** Entry for one function call in the call stack */ |
| 157 | struct call_stack_timer_item_t { |
| 158 | /** Stack length before the function call */ |
| 159 | int stack_len; |
| 160 | /** File name, where the calling function is declared (not owned) */ |
| 161 | const char* caller_file; |
| 162 | /** File name, where the called function is declared (not owned) */ |
| 163 | const char* func_file; |
| 164 | /** Calling function's start line */ |
| 165 | int caller_line; |
| 166 | /** Called function's start line */ |
| 167 | int start_line; |
| 168 | /** Time elapsed in this function call */ |
| 169 | timeval elapsed; |
| 170 | /** If true, then this is the first entry of this function and caller pair |
| 171 | * (only used in case of gross line times) */ |
| 172 | boolean first_call; |
| 173 | /** If true, then this function has appeared before in the call stack |
| 174 | * (only used in case of gross function times)*/ |
| 175 | boolean recursive_call; |
| 176 | }; |
| 177 | |
| 178 | /** Constructor - increases the stack depth */ |
| 179 | TTCN3_Stack_Depth(); |
| 180 | /** Destructor - decreases the stack depth, updates call times in the profiler */ |
| 181 | ~TTCN3_Stack_Depth(); |
| 182 | |
| 183 | /** Sets whether line times should include function call times - called by the config file parser */ |
| 184 | static void set_net_line_times(boolean p_net_line_times); |
| 185 | /** Sets whether function times should include embedded function times - called by the config file parser */ |
| 186 | static void set_net_func_times(boolean p_net_func_times); |
| 187 | |
| 188 | /** Returns the current stack depth */ |
| 189 | static int depth() { return current_depth; } |
| 190 | /** Inserts a new function call entry into the call stack database */ |
| 191 | static void add_stack(int stack_len, const char* caller_file, const char* func_file, |
| 192 | int caller_line, int start_line); |
| 193 | /** Removes the last entry from the call stack database */ |
| 194 | static void remove_stack(); |
| 195 | /** Adds the elapsed time to all entries in the call stack database */ |
| 196 | static void update_stack_elapsed(timeval elapsed); |
| 197 | private: |
| 198 | /** The current stack depth (starts from 0)*/ |
| 199 | static int current_depth; |
| 200 | /** The call stack database */ |
| 201 | static Vector<call_stack_timer_item_t> call_stack_timer_db; |
| 202 | /** If true, line times will not include the execution times of functions called |
| 203 | * in that line */ |
| 204 | static boolean net_line_times; |
| 205 | /** If true, function times will not include the execution times of functions |
| 206 | * called in that function */ |
| 207 | static boolean net_func_times; |
| 208 | }; |
| 209 | |
| 210 | #endif /* PROFILER_HH */ |
| 211 | |