Instrumentation.c

Go to the documentation of this file.
00001 #define _INSTRUMENTATION_C_
00002 
00003 #include <sys/time.h>
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <string.h>
00007 #include "Instrumentation.h"
00008 
00009 InstData *instCreate(){
00010         InstData *instData = (InstData*)malloc(sizeof(InstData));
00011 
00012         int i;
00013         //initialize void states
00014         for (i=0;i<TIMER_NUM_VOID_STATES;i++){
00015                 timerclear(&instData->voidStates[i].timing);
00016                 instData->voidStates[i].stateName = timerStateNames[i]; 
00017                 instData->voidStates[i].isUserState = 0;
00018         }
00019 
00020         //user stuff
00021     instData->numUserStates = 0;
00022     instData->userStates = NULL;
00023 
00024         //start timer
00025         gettimeofday(&instData->tv, &instData->tz);
00026 
00027         //current state and state stack
00028         instData->currentState = &instData->voidStates[TIMER_VOID];
00029         instData->stackedStates = stCreate();
00030 
00031         return instData;
00032 }
00033 
00034 void instDestroy(InstData **instDataPointerAddress){
00035         //free user states
00036         int i;
00037         InstData *instData = instDataPointerAddress[0];
00038         if (instData->numUserStates > 0 ){
00039                 for (i=0;i<instData->numUserStates;i++){
00040                         free(instData->userStates[i].stateName);
00041                 }
00042                 free(instData->userStates);
00043         }
00044         
00045         free(instData);
00046         instDataPointerAddress[0] = NULL;
00047 }
00048 
00049 void instSetDir(InstData *inst, char *dir){
00050         int len = strlen(dir);
00051         if (len > MAX_IDIR_LENGTH){
00052                 len =  MAX_IDIR_LENGTH;
00053                 fprintf(stderr, "%s %d: warning, dir length too big, truncating\n", __FILE__, __LINE__);
00054         }
00055         strncpy(inst->instDir, dir, len);
00056         inst->instDir[len] = '\0';
00057 
00058         //now we create the directory
00059         char cmd[MAX_IDIR_LENGTH + 15];
00060         sprintf(cmd, "mkdir -p %s", dir);
00061         if (system(cmd) != 0){
00062                 fprintf(stderr, "%s %d: error, cant create %s instrumention directory\n", __FILE__, __LINE__, inst->instDir);
00063         }       
00064 }
00065 
00066 
00067 static void instComputeTimings(InstData *inst){
00068         InstState *currentState = inst->currentState;
00069 
00070         struct timeval tv;
00071         struct timezone tz; //not used
00072 
00073         //get the time
00074         gettimeofday(&tv, &tz);
00075 
00076         //now we substract the time we just got from the current timing
00077         //we add 1000000 to usecs and subtract 1 from seconds, then we adjust later
00078         suseconds_t usecs = 1000000 + tv.tv_usec - inst->tv.tv_usec;
00079         time_t secs = tv.tv_sec - inst->tv.tv_sec - 1;
00080 
00081         //and compute the for the current state
00082         struct timeval *curTiming = (&currentState->timing);
00083         curTiming->tv_sec += secs;
00084         curTiming->tv_usec += usecs;
00085 
00086         //adjust timings, as usecs cant be bigger than 1000000
00087         while (curTiming->tv_usec > 1000000){
00088                 curTiming->tv_sec++;
00089                 curTiming->tv_usec -= 1000000;
00090         }
00091 }
00092 
00093 void instEnterState(InstData *inst, InstState *state){
00094         //compute the timings
00095         instComputeTimings(inst);
00096         
00097         //push current state
00098         stPush(inst->stackedStates, inst->currentState);
00099 
00100         //change state
00101         inst->currentState = state;
00102         
00103         //update the current timer
00104         gettimeofday(&inst->tv, &inst->tz);
00105 }
00106 
00107 void instLeaveState(InstData *inst){
00108         //compute the timings
00109         instComputeTimings(inst);
00110         
00111         //pop a state current state
00112         InstState *state;
00113         if (stPop(inst->stackedStates, (void**)&state) == -1){
00114                 fprintf(stderr, "%s %d, %s: cant pop stack\n", __FILE__, __LINE__, __FUNCTION__);
00115                 return;
00116         }
00117 
00118         //change state
00119         inst->currentState = state;
00120         
00121         //update the current timer
00122         gettimeofday(&inst->tv, &inst->tz);
00123 
00124 }
00125 
00126 void instSwitchState(InstData *inst, InstState *state){
00127         //compute timing for current state
00128         instComputeTimings(inst);
00129         //change state
00130         inst->currentState = state;
00131         //update the current timer
00132         gettimeofday(&inst->tv, &inst->tz);
00133 }
00134 
00135 void instSaveTimings(InstData *inst, char *filename, char *label){
00136         char fullName[MAX_IDIR_LENGTH + MAX_FNAME_LENGTH];
00137         sprintf(fullName, "%s/%s", inst->instDir, filename);
00138         FILE *fp = fopen(fullName, "a+");
00139         if (fp == NULL){
00140                 fprintf(stderr, "%s %d: cannot open %s for writing timing results\n", __FILE__, __LINE__, fullName);
00141                 return;
00142         }
00143         int i;
00144         fprintf(fp, "\nExecution time for %s\n", label);
00145         //we dont print last state
00146         for (i=0;i<TIMER_NUM_VOID_STATES-1;i++){
00147                 fprintf(fp, "%-20s: %10ld.%06ld seconds\n", 
00148                                 inst->voidStates[i].stateName, 
00149                                 inst->voidStates[i].timing.tv_sec, 
00150                                 inst->voidStates[i].timing.tv_usec);
00151         }
00152         if (inst->numUserStates > 0){
00153         fprintf(fp, "User States:\n");
00154                 for (i=0;i<inst->numUserStates;i++){
00155                         fprintf(fp, "%-20s: %10ld.%06ld seconds\n", 
00156                                         inst->userStates[i].stateName,
00157                                         inst->userStates[i].timing.tv_sec, 
00158                                         inst->userStates[i].timing.tv_usec);
00159                 }
00160         }
00161         fclose(fp);
00162 }
00163 
00164 /// \todo Copy the data from user
00165 void instSetUserStates(InstData *inst, char **userStates, int numStates){
00166         inst->numUserStates = numStates;
00167         inst->userStates = (InstState*)malloc(sizeof(InstState)*numStates);
00168         int i;
00169         for (i=0;i<numStates;i++){
00170                 timerclear(&inst->userStates[i].timing);
00171                 inst->userStates[i].stateName = strdup(userStates[i]);
00172                 inst->userStates[i].isUserState = 1;
00173         }
00174 }
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 

Generated on Tue Jan 17 19:18:38 2006 for Void by  doxygen 1.4.6