00001 #include "tracer.h"
00002
00003 TrcData *trcCreateData( char * filename )
00004 {
00005 TrcData * trc;
00006
00007 trc = (TrcData*) malloc( sizeof(TrcData) );
00008 if ( ( trc->tracefile = fopen( filename, "a") ) == NULL )
00009 {
00010 fprintf(stderr, "%s %d, %s: Cannot open file \"%s\" for writing tracing data.\n", __FILE__, __LINE__, __FUNCTION__, filename);
00011 return( NULL );
00012 }
00013
00014 gettimeofday( &(trc->initTime), NULL );
00015 trc->firstFlush = 1;
00016
00017 trc->currentState = NULL;
00018 trc->stackedStates = stCreate();
00019 trc->savedStates = listCreate();
00020 trc->numSavedStates = trc->numStackedStates = 0;
00021 return trc;
00022 }
00023
00024 void trcDestroyData( TrcData ** trcPointer )
00025 {
00026 if( *trcPointer == NULL ){
00027 printf(
00028 "%s %d, %s: Warning! Trying to destroy previously destroyed data.\n",
00029 __FILE__,
00030 __LINE__,
00031 __FUNCTION__
00032 );
00033 return;
00034 }
00035 if( (*trcPointer)->numStackedStates > 0 )
00036 printf(
00037 "%s %d, %s: Warning, there were still %d stacked states when trcData was destroyed !\n",
00038 __FILE__,
00039 __LINE__,
00040 __FUNCTION__,
00041 (*trcPointer)->numStackedStates
00042 );
00043
00044 while( (*trcPointer)->numStackedStates > 0 )
00045 trcLeaveState( *trcPointer );
00046
00047 trcFlush( (*trcPointer) );
00048 fclose( (*trcPointer)->tracefile );
00049 free( (*trcPointer) );
00050 *trcPointer = NULL;
00051 }
00052
00053 void trcEnterState(TrcData *trc, char * types, ...)
00054 {
00055 int i, j, *aux;
00056 char * saux;
00057 TrcState * state;
00058 va_list argList;
00059
00060 state = malloc( sizeof( TrcState ));
00061 state->numAttributes = strlen( types );
00062 j = 0;
00063 state->numPosAttributes = 0;
00064 for( i = 0; i < state->numAttributes; i++ )
00065 {
00066 if( types[i] == 'i' || types[i] == 's' || types[i] == 'a' )
00067 j++;
00068 else if( types[i] == 'I' || types[i] == 'S' || types[i] == 'A' )
00069 state->numPosAttributes++;
00070 else
00071 fprintf(stderr, "%s [%d], %s: Unknown attibute type.\n",
00072 __FILE__, __LINE__, __FUNCTION__);
00073 }
00074
00075 va_start( argList, j );
00076
00077 state->attributes=(TrcAttribute*)malloc(sizeof(TrcAttribute)*state->numAttributes);
00078
00079 state->numPosAttributes = 0;
00080 for ( i = 0; i < state->numAttributes; i++ )
00081 {
00082 state->attributes[i].type = types[i];
00083 switch( types[i] )
00084 {
00085 case 'i':
00086 state->attributes[i].value = malloc( sizeof(int) );
00087 aux = state->attributes[i].value;
00088 (*aux) = va_arg( argList, int );
00089 break;
00090 case 'a':
00091 aux = va_arg( argList, int* );
00092 state->attributes[i].value = (void *)aux;
00093 break;
00094 case 's':
00095 saux = va_arg( argList, char* );
00096 state->attributes[i].value = (void *)saux;
00097 break;
00098 case 'I':
00099 state->attributes[i].value = NULL;
00100 break;
00101 case 'A':
00102 state->attributes[i].value = NULL;
00103 break;
00104 case 'S':
00105 state->attributes[i].value = NULL;
00106 break;
00107 }
00108 }
00109
00110 va_end( argList );
00111
00112
00113 gettimeofday( &(state->initTime), NULL );
00114 getrusage( RUSAGE_SELF, &(state->initRusage) );
00115
00116
00117 stPush(trc->stackedStates, trc->currentState);
00118 trc->numStackedStates++;
00119
00120
00121 trc->currentState = state;
00122 return;
00123 }
00124
00125 void trcResetCurrentState( TrcData * trc )
00126 {
00127 gettimeofday( &(trc->currentState->initTime), NULL );
00128 }
00129
00130 void trcLeaveState(TrcData *trc, ...)
00131 {
00132 va_list argList;
00133 int i, args, *aux;
00134 char * saux;
00135
00136
00137 TrcState *state;
00138 if (( trc->numStackedStates <= 0 ) || stPop(trc->stackedStates, (void**)&state) == -1)
00139 {
00140 fprintf(
00141 stderr, "%s %d, %s: Leaving unexisting state. Stack empty (stackedStates=%d).\n",
00142 __FILE__,
00143 __LINE__,
00144 __FUNCTION__,
00145 trc->numStackedStates
00146 );
00147 return;
00148 }
00149 trc->numStackedStates--;
00150
00151 gettimeofday( &(trc->currentState->endTime), NULL);
00152 getrusage( RUSAGE_SELF, &(trc->currentState->endRusage) );
00153 va_start( argList, trc->currentState->numPosAttributes );
00154 for( i = 0; i < trc->currentState->numAttributes; i++ )
00155 {
00156 switch( trc->currentState->attributes[i].type )
00157 {
00158 case 'I':
00159 trc->currentState->attributes[i].value = malloc( sizeof(int) );
00160 aux = trc->currentState->attributes[i].value;
00161 (*aux) = va_arg( argList, int );
00162 break;
00163 case 'A':
00164 aux = va_arg( argList, int* );
00165 trc->currentState->attributes[i].value = (void *)aux;
00166 break;
00167 case 'S':
00168 saux = va_arg( argList, char* );
00169 trc->currentState->attributes[i].value = (void *)saux;
00170 break;
00171 }
00172 }
00173 va_end( argList );
00174
00175
00176 listInsertTail(trc->savedStates, (void*)trc->currentState);
00177 trc->numSavedStates++;
00178
00179
00180 trc->currentState = state;
00181
00182 if( trc->numSavedStates >= MAXSAVEDSTATES )
00183 trcFlush( trc );
00184
00185 return;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 static void trcPrintStateData( FILE * file, TrcState * state )
00208 {
00209 int i, j, *aux, *size;
00210 char * saux;
00211
00212 for( i = 0; i < state->numAttributes; i++ )
00213 {
00214 switch( state->attributes[i].type )
00215 {
00216 case 'i':
00217 aux = state->attributes[i].value;
00218 fprintf( file, SEPARATOR"%d", *aux );
00219 break;
00220 case 'I':
00221 aux = state->attributes[i].value;
00222 fprintf( file, SEPARATOR"%d", *aux );
00223 break;
00224 case 's':
00225 saux = state->attributes[i].value;
00226 fprintf( file, SEPARATOR"%s", saux );
00227 break;
00228 case 'S':
00229 saux = state->attributes[i].value;
00230 fprintf( file, SEPARATOR"%s", saux );
00231 break;
00232 case 'a':
00233 size = state->attributes[i].value;
00234 for( j = 1; j <= *size; j++ )
00235 {
00236 aux = size + j;
00237 fprintf( file, SEPARATOR"%d", *aux );
00238 }
00239 break;
00240 case 'A':
00241 size = state->attributes[i].value;
00242 for( j = 1; j <= *size; j++ )
00243 {
00244 aux = size + j;
00245 fprintf( file, SEPARATOR"%d", *aux );
00246 }
00247 break;
00248
00249 }
00250 }
00251 return;
00252 }
00253
00254 void trcFlush(TrcData *trc)
00255 {
00256 TrcState * state;
00257 int i;
00258 if ( trc->firstFlush )
00259 {
00260 fprintf( trc->tracefile, "%lu\n", trc->initTime.tv_usec+(1000000*trc->initTime.tv_sec));
00261 trc->firstFlush = 0;
00262 }
00263
00264 for( i = 0; i < trc->numSavedStates; i++ )
00265 {
00266 listRemoveHead( trc->savedStates, (void**)&state );
00267 fprintf(
00268 trc->tracefile,
00269 "%ld"SEPARATOR"%ld"SEPARATOR"%ld"SEPARATOR"%ld",
00270 (state->initTime.tv_usec + (1000000 * state->initTime.tv_sec)) -
00271 (trc->initTime.tv_usec + (1000000 * trc->initTime.tv_sec )),
00272 (state->endTime.tv_usec + (1000000 * state->endTime.tv_sec)) -
00273 (trc->initTime.tv_usec + (1000000 * trc->initTime.tv_sec )),
00274 (state->initRusage.ru_utime.tv_usec + (1000000 * state->initRusage.ru_utime.tv_sec)) +
00275 (state->initRusage.ru_stime.tv_usec + (1000000 * state->initRusage.ru_stime.tv_sec)),
00276 (state->endRusage.ru_utime.tv_usec + (1000000 * state->endRusage.ru_utime.tv_sec)) +
00277 (state->endRusage.ru_stime.tv_usec + (1000000 * state->endRusage.ru_stime.tv_sec))
00278 );
00279 trcPrintStateData( trc->tracefile, state );
00280 fprintf( trc->tracefile, "\n" );
00281 free( state->attributes );
00282 free( state );
00283 }
00284 trc->numSavedStates = 0;
00285 return;
00286 }
00287
00288 int * trcIArrayToTrc( int size, int * array )
00289 {
00290 int * aux = malloc( sizeof( int ) * (size + 1) );
00291 int i;
00292 aux[0] = size;
00293 for( i = 1; i <= size; i++ )
00294 aux[i] = array[i-1];
00295 return aux;
00296 }
00297
00298 #ifdef TRACER_MAINTEST
00299
00300 int main( int argc, char ** argv )
00301 {
00302 TrcData * trc;
00303 int array[4] = { 12, 23, 3 , 6 };
00304 int * bliu;
00305 printf("Creating data...\n"); fflush( NULL ); trc = trcCreateData( "./bla" );
00306 printf("Entering state 0...\n");
00307 trcEnterState(trc, "si", "Teste_de_instrumentação", 0);
00308 fflush( NULL );
00309 printf("Entering state 1...\n");
00310 fflush( NULL );
00311 bliu = trcIArrayToTrc( 4, array );
00312 printf("%d, %d, %d, %d, %d\n", bliu[0], bliu[1], bliu[2], bliu[3], bliu[4] );
00313 trcEnterState(trc, "siI", "Teste_de_instrumentação", 1, trcIArrayToTrc( 4, array ));
00314 printf("Leaving state 1...\n"); fflush( NULL ); trcLeaveState(trc);
00315 printf("Destroying data...\n"); fflush( NULL ); trcDestroyData(&trc);
00316 return(0);
00317 }
00318
00319 #endif