#include <stdio.h>
#include <assert.h>
#include "profiler.h"
Functions | |
void | profiler_set_mode (bool value) |
Sets the current profiling mode to the given value. | |
void | profiler_set_filename (const char *fname) |
Sets the profiling output file to the given value. | |
void | profiler_enter (unsigned int index) |
Function to be called whenever a new function is entered. | |
void | profiler_exit (unsigned int index) |
Function to be called whenever a timed function is exited. | |
static void | profiler_dealloc () |
static void | profiler_sort_by_calls (FILE *ofile) |
static void | profiler_sort_by_time (FILE *ofile) |
static void | profiler_sort_by_avg_time (FILE *ofile) |
void | profiler_report () |
Output profiler report. | |
Variables | |
bool | profiling_mode = TRUE |
static char * | profiling_output = NULL |
static unsigned int | stack [4096] |
static unsigned int | stack_size = 0 |
char | user_msg [USER_MSG_LENGTH] |
static void profiler_dealloc | ( | ) | [static] |
Deallocates all allocated memory for profiler.
References free_safe, NUM_PROFILES, and profiling_output.
Referenced by profiler_report().
00124 { 00125 00126 int i; /* Loop iterator */ 00127 00128 /* Deallocate profiling output name */ 00129 free_safe( profiling_output, (strlen( profiling_output ) + 1) ); 00130 00131 /* Iterate through the profiler array and deallocate all timer structures */ 00132 for( i=0; i<NUM_PROFILES; i++ ) { 00133 free_safe( profiles[i].time_in, sizeof( timer ) ); 00134 } 00135 00136 }
void profiler_enter | ( | unsigned int | index | ) |
Function to be called whenever a new function is entered.
index | Profiler index of current function. |
Increases the current call count for the current function, stops the timer for the last running counter and starts the timer for the current function.
References stack, and stack_size.
00084 { 00085 00086 /* Stop the last running timer if we are going to be timed */ 00087 if( (stack_size > 0) && profiles[index].timed && profiles[stack[stack_size-1]].timed ) { 00088 timer_stop( &profiles[stack[stack_size-1]].time_in ); 00089 } 00090 00091 /* Increment the calls counter */ 00092 profiles[index].calls++; 00093 00094 /* Start the timer for this function, if needed */ 00095 if( profiles[index].timed ) { 00096 timer_start( &profiles[index].time_in ); 00097 stack[stack_size] = index; 00098 stack_size++; 00099 } 00100 00101 }
void profiler_exit | ( | unsigned int | index | ) |
Function to be called whenever a timed function is exited.
Gets called when leaving a profiling function. Stops the current timer and pops the stack.
References stack, and stack_size.
00106 { 00107 00108 /* Stop the current timer */ 00109 timer_stop( &profiles[index].time_in ); 00110 00111 /* Pop the stack */ 00112 stack_size--; 00113 00114 /* Start the timer, if needed */ 00115 if( (stack_size > 0) && profiles[stack[stack_size-1]].timed ) { 00116 timer_start( &profiles[stack[stack_size-1]].time_in ); 00117 } 00118 00119 }
void profiler_report | ( | ) |
Output profiler report.
Generates profiling report if the profiling mode is set to TRUE.
References FATAL, free_safe, print_output(), profiler_dealloc(), profiler_sort_by_avg_time(), profiler_sort_by_calls(), profiler_sort_by_time(), profiling_mode, profiling_output, user_msg, and USER_MSG_LENGTH.
Referenced by main().
00296 { 00297 00298 FILE* ofile; /* File stream pointer to output file */ 00299 00300 if( profiling_mode ) { 00301 00302 assert( profiling_output != NULL ); 00303 00304 if( (ofile = fopen( profiling_output, "w" )) != NULL ) { 00305 00306 unsigned int rv; 00307 00308 /* Stop the simulation timer and deallocate it */ 00309 timer_stop( &sim_timer ); 00310 00311 /* Output profiling results */ 00312 profiler_sort_by_time( ofile ); 00313 profiler_sort_by_avg_time( ofile ); 00314 profiler_sort_by_calls( ofile ); 00315 00316 /* Close the output file */ 00317 rv = fclose( ofile ); 00318 assert( rv == 0 ); 00319 00320 } else { 00321 00322 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unable to open profiling output file \"%s\" for writing", profiling_output ); 00323 assert( rv < USER_MSG_LENGTH ); 00324 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00325 00326 } 00327 00328 } 00329 00330 /* Deallocate sim_timer */ 00331 free_safe( sim_timer, sizeof( timer ) ); 00332 00333 /* Delete memory associated with the profiler */ 00334 profiler_dealloc(); 00335 00336 }
void profiler_set_filename | ( | const char * | fname | ) |
Sets the profiling output file to the given value.
fname | Name of output profiling file. |
Sets the profiling output file to the given value.
References free_safe, profiling_output, and strdup_safe.
Referenced by covered_sim_calltf(), and main().
00069 { 00070 00071 /* Deallocate profiling output name, if one was already specified */ 00072 free_safe( profiling_output, (strlen( profiling_output ) + 1) ); 00073 00074 profiling_output = strdup_safe( fname ); 00075 00076 }
void profiler_set_mode | ( | bool | value | ) |
Sets the current profiling mode to the given value.
value | New value to set profiling mode to |
Sets the current profiling mode to the given value.
References profiling_mode.
Referenced by covered_sim_calltf(), and main().
00052 { 00053 00054 profiling_mode = value; 00055 00056 #ifdef HAVE_SYS_TIME_H 00057 if( profiling_mode ) { 00058 timer_start( &sim_timer ); 00059 } 00060 #endif 00061 00062 }
static void profiler_sort_by_avg_time | ( | FILE * | ofile | ) | [static] |
References NUM_PROFILES.
Referenced by profiler_report().
00240 { 00241 00242 int largest; /* Index of largest calls profile */ 00243 int i; /* Loop iterator */ 00244 int j; /* Loop iterator */ 00245 int list[NUM_PROFILES]; /* List of indices that can be used to sort */ 00246 int tmp; /* Used for value swapping */ 00247 00248 /* Prepare a list of key/value pairs */ 00249 for( i=0; i<NUM_PROFILES; i++ ) { 00250 list[i] = i; 00251 } 00252 00253 /* Display header for this section */ 00254 fprintf( ofile, "==============================================================================\n" ); 00255 fprintf( ofile, "= Sort by avg. time Profile =\n" ); 00256 fprintf( ofile, "==============================================================================\n" ); 00257 fprintf( ofile, "\n" ); 00258 fprintf( ofile, "Total simulation time: %ld\n", (long int)sim_timer->total ); 00259 fprintf( ofile, "\n" ); 00260 fprintf( ofile, "------------------------------------------------------------------------------------------------------\n" ); 00261 fprintf( ofile, "Function Name calls time avg. time mallocs frees\n" ); 00262 fprintf( ofile, "------------------------------------------------------------------------------------------------------\n" ); 00263 00264 /* Output them in order of most to least */ 00265 for( i=(NUM_PROFILES-1); i>=0; i-- ) { 00266 largest = 0; 00267 for( j=0; j<i; j++ ) { 00268 if( (profiles[list[j]].time_in != NULL) && 00269 ((profiles[list[largest]].time_in == NULL) || 00270 ((profiles[list[j]].time_in->total / profiles[list[j]].calls) > (profiles[list[largest]].time_in->total / profiles[list[largest]].calls))) ) { 00271 largest = j; 00272 } 00273 } 00274 tmp = list[j]; 00275 list[j] = list[largest]; 00276 list[largest] = tmp; 00277 if( profiles[list[j]].calls > 0 ) { 00278 if( profiles[list[j]].time_in == NULL ) { 00279 fprintf( ofile, " %-40.40s %10d NA NA %10d %10d\n", 00280 profiles[list[j]].func_name, profiles[list[j]].calls, profiles[list[j]].mallocs, profiles[list[j]].frees ); 00281 } else { 00282 fprintf( ofile, " %-40.40s %10d %10ld %10.3f %10d %10d\n", 00283 profiles[list[j]].func_name, profiles[list[j]].calls, (long int)profiles[list[j]].time_in->total, 00284 (float)(profiles[list[j]].time_in->total / (profiles[list[j]].calls * 1.0)), profiles[list[j]].mallocs, profiles[list[j]].frees ); 00285 } 00286 } 00287 } 00288 00289 fprintf( ofile, "\n\n\n" ); 00290 00291 }
static void profiler_sort_by_calls | ( | FILE * | ofile | ) | [static] |
References NUM_PROFILES.
Referenced by profiler_report().
00138 { 00139 00140 int largest; /* Index of largest calls profile */ 00141 int i; /* Loop iterator */ 00142 int j; /* Loop iterator */ 00143 int list[NUM_PROFILES]; /* List of indices that can be used to sort */ 00144 int tmp; /* Used for value swapping */ 00145 00146 /* Prepare a list of key/value pairs */ 00147 for( i=0; i<NUM_PROFILES; i++ ) { 00148 list[i] = i; 00149 } 00150 00151 /* Display header for this section */ 00152 fprintf( ofile, "==============================================================================\n" ); 00153 fprintf( ofile, "= Sort by calls Profile =\n" ); 00154 fprintf( ofile, "==============================================================================\n" ); 00155 fprintf( ofile, "\n" ); 00156 fprintf( ofile, "Total simulation time: %ld\n", (long int)sim_timer->total ); 00157 fprintf( ofile, "\n" ); 00158 fprintf( ofile, "------------------------------------------------------------------------------------------------------\n" ); 00159 fprintf( ofile, "Function Name calls time avg. time mallocs frees\n" ); 00160 fprintf( ofile, "------------------------------------------------------------------------------------------------------\n" ); 00161 00162 /* Output them in order of most to least */ 00163 for( i=(NUM_PROFILES-1); i>=0; i-- ) { 00164 largest = 0; 00165 for( j=0; j<i; j++ ) { 00166 if( profiles[list[j]].calls > profiles[list[largest]].calls ) { 00167 largest = j; 00168 } 00169 } 00170 tmp = list[j]; 00171 list[j] = list[largest]; 00172 list[largest] = tmp; 00173 if( profiles[list[j]].calls > 0 ) { 00174 if( profiles[list[j]].time_in == NULL ) { 00175 fprintf( ofile, " %-40.40s %10d NA NA %10d %10d\n", 00176 profiles[list[j]].func_name, profiles[list[j]].calls, profiles[list[j]].mallocs, profiles[list[j]].frees ); 00177 } else { 00178 fprintf( ofile, " %-40.40s %10d %10ld %10.3f %10d %10d\n", 00179 profiles[list[j]].func_name, profiles[list[j]].calls, (long int)profiles[list[j]].time_in->total, 00180 (float)(profiles[list[j]].time_in->total / (profiles[list[j]].calls * 1.0)), profiles[list[j]].mallocs, profiles[list[j]].frees ); 00181 } 00182 } 00183 } 00184 00185 fprintf( ofile, "\n\n\n" ); 00186 00187 }
static void profiler_sort_by_time | ( | FILE * | ofile | ) | [static] |
References NUM_PROFILES.
Referenced by profiler_report().
00189 { 00190 00191 int largest; /* Index of largest calls profile */ 00192 int i; /* Loop iterator */ 00193 int j; /* Loop iterator */ 00194 int list[NUM_PROFILES]; /* List of indices that can be used to sort */ 00195 int tmp; /* Used for value swapping */ 00196 00197 /* Prepare a list of key/value pairs */ 00198 for( i=0; i<NUM_PROFILES; i++ ) { 00199 list[i] = i; 00200 } 00201 00202 /* Display header for this section */ 00203 fprintf( ofile, "==============================================================================\n" ); 00204 fprintf( ofile, "= Sort by time Profile =\n" ); 00205 fprintf( ofile, "==============================================================================\n" ); 00206 fprintf( ofile, "\n" ); 00207 fprintf( ofile, "Total simulation time: %ld\n", (long int)sim_timer->total ); 00208 fprintf( ofile, "\n" ); 00209 fprintf( ofile, "------------------------------------------------------------------------------------------------------\n" ); 00210 fprintf( ofile, "Function Name calls time avg. time mallocs frees\n" ); 00211 fprintf( ofile, "------------------------------------------------------------------------------------------------------\n" ); 00212 00213 /* Output them in order of most to least */ 00214 for( i=(NUM_PROFILES-1); i>=0; i-- ) { 00215 largest = 0; 00216 for( j=0; j<i; j++ ) { 00217 if( (profiles[list[j]].time_in != NULL) && ((profiles[list[largest]].time_in == NULL) || (profiles[list[j]].time_in->total > profiles[list[largest]].time_in->total)) ) { 00218 largest = j; 00219 } 00220 } 00221 tmp = list[j]; 00222 list[j] = list[largest]; 00223 list[largest] = tmp; 00224 if( profiles[list[j]].calls > 0 ) { 00225 if( profiles[list[j]].time_in == NULL ) { 00226 fprintf( ofile, " %-40.40s %10d NA NA %10d %10d\n", 00227 profiles[list[j]].func_name, profiles[list[j]].calls, profiles[list[j]].mallocs, profiles[list[j]].frees ); 00228 } else { 00229 fprintf( ofile, " %-40.40s %10d %10ld %10.3f %10d %10d\n", 00230 profiles[list[j]].func_name, profiles[list[j]].calls, (long int)profiles[list[j]].time_in->total, 00231 (float)(profiles[list[j]].time_in->total / (profiles[list[j]].calls * 1.0)), profiles[list[j]].mallocs, profiles[list[j]].frees ); 00232 } 00233 } 00234 } 00235 00236 fprintf( ofile, "\n\n\n" ); 00237 00238 }
bool profiling_mode = TRUE |
Current profiling mode value
Referenced by profiler_report(), and profiler_set_mode().
char* profiling_output = NULL [static] |
Name of output profiling file
Referenced by profiler_dealloc(), profiler_report(), and profiler_set_filename().
unsigned int stack[4096] [static] |
Stack of profiles that have been called
Referenced by profiler_enter(), and profiler_exit().
unsigned int stack_size = 0 [static] |
Current size of the profile stack
Referenced by profiler_enter(), and profiler_exit().
char user_msg[USER_MSG_LENGTH] |
Holds some output that will be displayed via the print_output command. This is created globally so that memory does not need to be reallocated for each function that wishes to use it.