#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. | |
| void | profiler_dealloc () |
| void | profiler_sort_by_calls (FILE *ofile) |
| void | profiler_sort_by_time (FILE *ofile) |
| void | profiler_sort_by_avg_time (FILE *ofile) |
| void | profiler_report () |
| Output profiler report. | |
Variables | |
| bool | profiling_mode = TRUE |
| char * | profiling_output = NULL |
| unsigned int | stack [4096] |
| unsigned int | stack_size = 0 |
| timer * | sim_timer = NULL |
| char | user_msg [USER_MSG_LENGTH] |
|
|
Deallocates all allocated memory for profiler.
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 }
|
|
|
Function to be called whenever a new function is entered.
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 }
|
|
|
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.
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 }
|
|
|
Output profiler report. Generates profiling report if the profiling mode is set to TRUE.
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 }
|
|
|
Sets the profiling output file to the given value.
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 }
|
|
|
Sets the current profiling mode to the given value.
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
Current profiling mode value |
|
|
Name of output profiling file |
|
|
|
|
|
Stack of profiles that have been called |
|
|
Current size of the profile stack |
|
|
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. |
1.3.4