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
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
00021 instData->numUserStates = 0;
00022 instData->userStates = NULL;
00023
00024
00025 gettimeofday(&instData->tv, &instData->tz);
00026
00027
00028 instData->currentState = &instData->voidStates[TIMER_VOID];
00029 instData->stackedStates = stCreate();
00030
00031 return instData;
00032 }
00033
00034 void instDestroy(InstData **instDataPointerAddress){
00035
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
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;
00072
00073
00074 gettimeofday(&tv, &tz);
00075
00076
00077
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
00082 struct timeval *curTiming = (¤tState->timing);
00083 curTiming->tv_sec += secs;
00084 curTiming->tv_usec += usecs;
00085
00086
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
00095 instComputeTimings(inst);
00096
00097
00098 stPush(inst->stackedStates, inst->currentState);
00099
00100
00101 inst->currentState = state;
00102
00103
00104 gettimeofday(&inst->tv, &inst->tz);
00105 }
00106
00107 void instLeaveState(InstData *inst){
00108
00109 instComputeTimings(inst);
00110
00111
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
00119 inst->currentState = state;
00120
00121
00122 gettimeofday(&inst->tv, &inst->tz);
00123
00124 }
00125
00126 void instSwitchState(InstData *inst, InstState *state){
00127
00128 instComputeTimings(inst);
00129
00130 inst->currentState = state;
00131
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
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
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