Index: generic/nsfProfile.c =================================================================== diff -u -rbb0d12c63024e25ca81a370eb934dbbe2b7a10fd -r9e2f4e90caad3a50467c015e990ba64a2c168dd2 --- generic/nsfProfile.c (.../nsfProfile.c) (revision bb0d12c63024e25ca81a370eb934dbbe2b7a10fd) +++ generic/nsfProfile.c (.../nsfProfile.c) (revision 9e2f4e90caad3a50467c015e990ba64a2c168dd2) @@ -15,133 +15,233 @@ #include "nsfInt.h" +typedef struct NsfProfileData { + long microSec; + long count; +} NsfProfileData; + #if defined(NSF_PROFILE) -void -NsfProfileFillTable(Tcl_HashTable* table, Tcl_DString* key, - double totalMicroSec) { - Tcl_HashEntry* hPtr; - char* keyStr = Tcl_DStringValue(key); - long int* value; +static void +NsfProfileFillTable(Tcl_HashTable *table, char *keyStr, double totalMicroSec) { + NsfProfileData *value; + Tcl_HashEntry *hPtr; + int isNew; - hPtr = Tcl_FindHashEntry(table, keyStr); - if (!hPtr) { - int nw; - hPtr = Tcl_CreateHashEntry(table, keyStr, &nw); - if (!nw) - return; - value = (long int*) ckalloc (sizeof(long int)); - *value = 0; + hPtr = Tcl_CreateHashEntry(table, keyStr, &isNew); + if (isNew) { + value = (NsfProfileData *)ckalloc(sizeof(NsfProfileData)); + value->microSec = 0; + value->count = 0; Tcl_SetHashValue(hPtr, (ClientData) value); - } else - value = (long int*) Tcl_GetHashValue (hPtr); - - *value += totalMicroSec; - - - /* { - long int* d = (long int*) Tcl_GetHashValue (hPtr); - fprintf(stderr, "Entered %s ... %ld\n", Tcl_GetHashKey(table, hPtr), *d); - }*/ - + } else { + value = (NsfProfileData *)Tcl_GetHashValue (hPtr); + } + value->microSec += totalMicroSec; + value->count ++; } void -NsfProfileEvaluateData(Tcl_Interp* interp, NsfCallStackContent *cscPtr) { +NsfProfileEvaluateData(Tcl_Interp *interp, NsfCallStackContent *cscPtr) { double totalMicroSec; - NsfObject* obj = cscPtr->self; + NsfObject *obj = cscPtr->self; NsfClass *cl = cscPtr->cl; long int startSec = cscPtr->startSec; long int startUsec = cscPtr->startUsec; CONST char *methodName = cscPtr->methodName; - Tcl_DString objectKey, methodKey; - NsfProfile* profile = &RUNTIME_STATE(interp)->profile; + Tcl_DString methodKey, objectKey; + NsfProfile *profile = &RUNTIME_STATE(interp)->profile; struct timeval trt; gettimeofday(&trt, NULL); - totalMicroSec = (trt.tv_sec - startSec) * 1000000 + - (trt.tv_usec - startUsec); - + totalMicroSec = (trt.tv_sec - startSec) * 1000000 + (trt.tv_usec - startUsec); profile->overallTime += totalMicroSec; if (obj->teardown == 0 || !obj->id) { return; } + Tcl_DStringInit(&objectKey); - Tcl_DStringAppend(&objectKey, ObjStr(obj->cmdName), -1); + Tcl_DStringAppend(&objectKey, ObjectName(obj), -1); + Tcl_DStringAppend(&objectKey, " (", 1); + Tcl_DStringAppend(&objectKey, ClassName(obj->cl), -1); + Tcl_DStringAppend(&objectKey, " )", 1); Tcl_DStringInit(&methodKey); Tcl_DStringAppend(&methodKey, cl ? ObjStr(cl->object.cmdName) : ObjStr(obj->cmdName), -1); - Tcl_DStringAppend(&methodKey, "->", 2); + Tcl_DStringAppend(&methodKey, " ", 1); Tcl_DStringAppend(&methodKey, methodName, -1); if (cl) { Tcl_DStringAppend(&methodKey, " method", 7); } else { - Tcl_DStringAppend(&methodKey, " object method", 14); + Tcl_DStringAppend(&methodKey, " object-method", 14); } - NsfProfileFillTable(&profile->objectData, &objectKey, totalMicroSec); - NsfProfileFillTable(&profile->methodData, &methodKey, totalMicroSec); + { + NsfCallStackContent *cscPtrTop = NsfCallStackGetTopFrame(interp, NULL); + if (cscPtrTop) { + NsfClass *cl = cscPtrTop->cl; + NsfObject *obj = cscPtrTop->self; + CONST char *methodName = cscPtrTop->methodName; + + Tcl_DStringAppend(&methodKey, " ", 1); + Tcl_DStringAppend(&methodKey, cl ? ObjStr(cl->object.cmdName) : ObjStr(obj->cmdName), -1); + Tcl_DStringAppend(&methodKey, " ", 1); + Tcl_DStringAppend(&methodKey, methodName, -1); + if (cl) { + Tcl_DStringAppend(&methodKey, " method", 7); + } else { + Tcl_DStringAppend(&methodKey, " object-method", 14); + } + } else { + Tcl_DStringAppend(&methodKey, " - - -", 6); + } + } + + NsfProfileFillTable(&profile->objectData, Tcl_DStringValue(&objectKey), totalMicroSec); + NsfProfileFillTable(&profile->methodData, Tcl_DStringValue(&methodKey), totalMicroSec); Tcl_DStringFree(&objectKey); Tcl_DStringFree(&methodKey); } -void -NsfProfilePrintTable(Tcl_HashTable* table) { - Tcl_HashEntry* topValueHPtr; - long int* topValue; +static void +NsfProfilePrintTable(Tcl_HashTable *table) { + Tcl_HashEntry *topValueHPtr; + assert(table); + do { + NsfProfileData *topValue; Tcl_HashSearch hSrch; - Tcl_HashEntry* hPtr = table ? - Tcl_FirstHashEntry(table, &hSrch) : 0; - char* topKey = 0; + Tcl_HashEntry *hPtr; + char *topKey = NULL; - topValueHPtr = 0; - topValue = 0; + topValueHPtr = NULL; + topValue = NULL; - for (; hPtr != 0; hPtr = Tcl_NextHashEntry(&hSrch)) { - long int *val = (long int*) Tcl_GetHashValue(hPtr); - if (val && (!topValue || (topValue && *val >= *topValue))) { - topValue = val; + for (hPtr = Tcl_FirstHashEntry(table, &hSrch); hPtr; + hPtr = Tcl_NextHashEntry(&hSrch)) { + NsfProfileData *value = (NsfProfileData *) Tcl_GetHashValue(hPtr); + if (value && + (!topValue || (topValue && value->microSec >= topValue->microSec))) { + topValue = value; topValueHPtr = hPtr; - topKey = Tcl_GetHashKey(table, hPtr); + topKey = Tcl_GetHashKey(table, hPtr); } } if (topValueHPtr) { - fprintf(stderr, " %15ld %s\n", *topValue, topKey); - ckfree((char*) topValue); + fprintf(stderr, " %15ld %10ld %s\n", topValue->microSec, topValue->count, topKey); + ckfree((char *) topValue); Tcl_DeleteHashEntry(topValueHPtr); } } while (topValueHPtr); } void NsfProfilePrintData(Tcl_Interp *interp) { - NsfProfile* profile = &RUNTIME_STATE(interp)->profile; + NsfProfile *profilePtr = &RUNTIME_STATE(interp)->profile; + struct timeval trt; fprintf(stderr, "------------------------------------------------------------------\n"); fprintf(stderr, "\nXOTcl Profile Information\n\n"); fprintf(stderr, "------------------------------------------------------------------\n"); - fprintf(stderr, "Overall Elapsed Time %ld\n", - profile->overallTime); + fprintf(stderr, "Overall Elapsed Time %ld\n", profilePtr->overallTime); fprintf(stderr, "------------------------------------------------------------------\n"); - fprintf(stderr, " MICROSECONDS OBJECT-NAME\n"); - NsfProfilePrintTable(&profile->objectData); + fprintf(stderr, " MICROSECONDS COUNT OBJECT-NAME\n"); + NsfProfilePrintTable(&profilePtr->objectData); fprintf(stderr, "------------------------------------------------------------------\n"); - fprintf(stderr, " MICROSECONDS (CL/OBJ)->METHOD-NAME\n"); - NsfProfilePrintTable(&profile->methodData); + fprintf(stderr, " MICROSECONDS COUNT (CL/OBJ)->METHOD-NAME\n"); + NsfProfilePrintTable(&profilePtr->methodData); fprintf(stderr, "------------------------------------------------------------------\n"); + + gettimeofday(&trt, NULL); + profilePtr->startSec = trt.tv_sec; + profilePtr->startUSec = trt.tv_usec; + profilePtr->overallTime = 0; } +static void +NsfProfileClearTable(Tcl_HashTable *table) { + Tcl_HashSearch hSrch; + Tcl_HashEntry *hPtr; + + assert(table); + for (hPtr = Tcl_FirstHashEntry(table, &hSrch); hPtr; + hPtr = Tcl_NextHashEntry(&hSrch)) { + NsfProfileData *value = (NsfProfileData *) Tcl_GetHashValue(hPtr); + ckfree((char *) value); + Tcl_DeleteHashEntry(hPtr); + } +} + +void +NsfProfileClearData(Tcl_Interp *interp) { + NsfProfile *profilePtr = &RUNTIME_STATE(interp)->profile; + struct timeval trt; + + NsfProfileClearTable(&profilePtr->objectData); + NsfProfileClearTable(&profilePtr->methodData); + + gettimeofday(&trt, NULL); + profilePtr->startSec = trt.tv_sec; + profilePtr->startUSec = trt.tv_usec; + profilePtr->overallTime = 0; +} + +static Tcl_Obj* +NsfProfileGetTable(Tcl_Interp *interp, Tcl_HashTable *table) { + Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_HashSearch hSrch; + Tcl_HashEntry *hPtr; + + assert(table); + for (hPtr = Tcl_FirstHashEntry(table, &hSrch); hPtr; + hPtr = Tcl_NextHashEntry(&hSrch)) { + NsfProfileData *value = (NsfProfileData *) Tcl_GetHashValue(hPtr); + char *key = Tcl_GetHashKey(table, hPtr); + Tcl_Obj *subList = Tcl_NewListObj(0, NULL); + + Tcl_ListObjAppendElement(interp, subList, Tcl_NewStringObj(key, -1)); + Tcl_ListObjAppendElement(interp, subList, Tcl_NewIntObj(value->microSec)); + Tcl_ListObjAppendElement(interp, subList, Tcl_NewIntObj(value->count)); + Tcl_ListObjAppendElement(interp, list, subList); + } + return list; +} + +void +NsfProfileGetData(Tcl_Interp *interp) { + Tcl_Obj *list = Tcl_NewListObj(0, NULL); + NsfProfile *profilePtr = &RUNTIME_STATE(interp)->profile; + long totalMicroSec; + struct timeval trt; + + gettimeofday(&trt, NULL); + totalMicroSec = (trt.tv_sec - profilePtr->startSec) * 1000000 + (trt.tv_usec - profilePtr->startUSec); + + Tcl_ListObjAppendElement(interp, list, Tcl_NewIntObj(totalMicroSec)); + Tcl_ListObjAppendElement(interp, list, Tcl_NewIntObj(profilePtr->overallTime)); + Tcl_ListObjAppendElement(interp, list, NsfProfileGetTable(interp, &profilePtr->objectData)); + Tcl_ListObjAppendElement(interp, list, NsfProfileGetTable(interp, &profilePtr->methodData)); + + Tcl_SetObjResult(interp, list); +} + void NsfProfileInit(Tcl_Interp *interp) { - RUNTIME_STATE(interp)->profile.overallTime = 0; + NsfProfile *profilePtr = &RUNTIME_STATE(interp)->profile; + struct timeval trt; + Tcl_InitHashTable(&RUNTIME_STATE(interp)->profile.objectData, TCL_STRING_KEYS); Tcl_InitHashTable(&RUNTIME_STATE(interp)->profile.methodData, TCL_STRING_KEYS); + + gettimeofday(&trt, NULL); + profilePtr->startSec = trt.tv_sec; + profilePtr->startUSec = trt.tv_usec; + profilePtr->overallTime = 0; } #endif