00001
00006 #include "ctl/profile.h"
00007 #include <stdio.h>
00008
00009
00010 static ctl_profile* ctl_profile_list = NULL;
00011
00016 void ctl_profiles_dump(void)
00017 {
00018 const ctl_profile* curr = ctl_profile_list;
00019 if( NULL != curr )
00020 {
00021 debug_log( LOG_PROFILE, "Profile traces\n" );
00022 do
00023 {
00024 char buff[512];
00025 curr->print( buff, countof(buff), curr );
00026 debug_log( LOG_PROFILE, " %s\n", buff );
00027 curr = curr->next;
00028 }
00029 while( curr );
00030 }
00031 }
00032
00036 void ctl_profiles_global_reset(void)
00037 {
00038 ctl_profile* curr = ctl_profile_list;
00039 ctl_profile_list = NULL;
00040 while( curr )
00041 {
00042 ctl_profile* next = curr->next;
00043 memset(curr,0,sizeof(*curr));
00044 curr = next;
00045 }
00046 }
00047
00048
00049
00050 static int ctl_profile_print( char* buff, size_t size, const ctl_profile* self )
00051 {
00052 size_t len;
00053 if( self->usPrev < 0 )
00054 return snprintf( buff, size, szconst(char,"%s: Pending"), self->label );
00055 len = snprintf( buff, size, szconst(char,"%s: "), self->label );
00056 len += ctl_ustime_print_seconds( buff+len, size-len, self->usPrev );
00057 return len;
00058 }
00059
00065 void ctl_profile_init( ctl_profile* self, const char* label )
00066 {
00067 self->label = label;
00068 self->type = ctl_profile_type_profile;
00069 self->print = ctl_profile_print;
00070 self->usPrev = -1;
00071 self->usCurr = -1;
00072
00073 self->next = ctl_profile_list;
00074 ctl_profile_list = self;
00075 }
00076
00077
00078
00079 static int ctl_profile_average_print( char* buff, size_t size, const ctl_profile* self )
00080 {
00081 const ctl_profile_average* aself = (const ctl_profile_average*)self;
00082 size_t len;
00083 if( 0 == aself->count )
00084 return snprintf( buff, size, szconst(char,"%s: Pending"), self->label );
00085 len = snprintf( buff, size, szconst(char,"%s: times:%llu total:"), self->label, aself->count );
00086 len += ctl_ustime_print_seconds( buff+len, size-len, aself->total );
00087 len += snprintf( buff+len, size-len, szconst(char," avg:") );
00088 len += ctl_ustime_print_seconds( buff+len, size-len, aself->total/aself->count );
00089 len += snprintf( buff+len, size-len, szconst(char," min:") );
00090 len += ctl_ustime_print_seconds( buff+len, size-len, aself->min );
00091 len += snprintf( buff+len, size-len, szconst(char," max:") );
00092 len += ctl_ustime_print_seconds( buff+len, size-len, aself->max );
00093 return len;
00094 }
00095
00100 void ctl_profiles_dump_averages_sheet(void)
00101 {
00102 const ctl_profile* curr = ctl_profile_list;
00103 if( NULL != curr )
00104 {
00105 debug_log( LOG_PROFILE, "\"Label\",\"Times Invoked\",\"Total Time\",\"Average Time\",\"Minimum Time\",\"Maximum Time\"\n" );
00106 do
00107 {
00108 if( ctl_profile_type_average == curr->type )
00109 {
00110 const ctl_profile_average* aself = (const ctl_profile_average*)curr;
00111 if( 0 == aself->count )
00112 {
00113 debug_log( LOG_PROFILE, szconst(char,"%s,0,0,0,0,0\n"), curr->label );
00114 }
00115 else
00116 {
00117 char buff[32];
00118 debug_log( LOG_PROFILE, szconst(char,"\"%s\",%llu,"), curr->label, aself->count );
00119 ctl_ustime_print_seconds( buff, countof(buff), aself->total );
00120 debug_log( LOG_PROFILE, szconst(char,"%s,"), buff );
00121 ctl_ustime_print_seconds( buff, countof(buff), aself->total/aself->count );
00122 debug_log( LOG_PROFILE, szconst(char,"%s,"), buff );
00123 ctl_ustime_print_seconds( buff, countof(buff), aself->min );
00124 debug_log( LOG_PROFILE, szconst(char,"%s,"), buff );
00125 ctl_ustime_print_seconds( buff, countof(buff), aself->max );
00126 debug_log( LOG_PROFILE, szconst(char,"%s\n"), buff );
00127 }
00128 }
00129 curr = curr->next;
00130 }
00131 while( curr );
00132 }
00133 }
00134
00140 void ctl_profile_average_init( ctl_profile_average* self, const char* label )
00141 {
00142 ctl_profile_init( &self->profile, label );
00143 self->profile.type = ctl_profile_type_average;
00144 self->profile.print = ctl_profile_average_print;
00145 self->total = self->max = 0;
00146 self->min = int64_max;
00147 self->count = 0;
00148 }
00149
00150 static int ctl_profile_counter_print( char* buff, size_t size, const ctl_profile* self )
00151 {
00152 const ctl_profile_counter* aself = (const ctl_profile_counter*)self;
00153 ustime ustotal = aself->last-aself->began;
00154 if( 0 == aself->count || 0 == ustotal )
00155 return snprintf( buff, size, szconst(char,"%s: Pending"), self->label );
00156 return snprintf( buff, size, szconst(char,"%s: %d"), self->label, (int)((aself->count * (1000000.0/ustotal))+0.1) );
00157 }
00158
00165 void ctl_profile_counter_init( ctl_profile_counter* self, const char* label, mstime window )
00166 {
00167 ctl_profile_init( &self->profile, label );
00168 self->profile.type = ctl_profile_type_counter;
00169 self->profile.print = ctl_profile_counter_print;
00170 self->window = window;
00171 self->began = self->last = ctl_ustime();
00172 self->count = 0;
00173 }
00174
00175 static int ctl_profile_testpoint_print( char* buff, size_t size, const ctl_profile* self )
00176 {
00177 const ctl_profile_testpoint* aself = (const ctl_profile_testpoint*)self;
00178 if( 0 == aself->count )
00179 return snprintf( buff, size, szconst(char,"%s: Pending"), self->label );
00180 return snprintf( buff, size, szconst(char,"%s: times:%lld min:%lld max:%lld"), self->label, aself->count, aself->min, aself->max );
00181 }
00182
00189 void ctl_profile_testpoint_init( ctl_profile_testpoint* self, const char* label )
00190 {
00191 ctl_profile_init( &self->profile, label );
00192 self->count = 0;
00193 self->value = 0;
00194 self->min = int64_max;
00195 self->max = int64_min;
00196 self->profile.type = ctl_profile_type_testpoint;
00197 self->profile.print = ctl_profile_testpoint_print;
00198 }