profiler.c File Reference

#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]

Detailed Description

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
12/10/2007

Function Documentation

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.

Parameters:
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.

Parameters:
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.

Parameters:
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 }   


Variable Documentation

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.

Generated on Sun Nov 21 00:55:40 2010 for Covered by  doxygen 1.6.3