From 8bdf996e1c0f915efec203a6bc613ba68be79afe Mon Sep 17 00:00:00 2001 From: "blythe%netscape.com" Date: Mon, 13 May 2002 01:48:30 +0000 Subject: [PATCH] Not part of a normal build. Have the categories become context aware. Each context will naturally have it's own set of category runs. --- tools/trace-malloc/spacecategory.c | 131 +++++++++++++++++++---------- tools/trace-malloc/spacetrace.c | 37 ++++++-- tools/trace-malloc/spacetrace.h | 10 ++- 3 files changed, 121 insertions(+), 57 deletions(-) diff --git a/tools/trace-malloc/spacecategory.c b/tools/trace-malloc/spacecategory.c index 93a4ac999f06..f7f2ea8e5b1a 100644 --- a/tools/trace-malloc/spacecategory.c +++ b/tools/trace-malloc/spacecategory.c @@ -207,6 +207,14 @@ STCategoryNode* NewCategoryNode(const char* catName, STCategoryNode* parent, STG node = (STCategoryNode *) calloc(1, sizeof(STCategoryNode)); if (!node) return NULL; + + node->runs = (STRun**)calloc(g->mCommandLineOptions.mContexts, sizeof(STRun*)); + if(NULL == node->runs) + { + free(node); + return NULL; + } + node->categoryName = catName; /* Set parent of child */ @@ -508,7 +516,7 @@ STCategoryNode* matchAllocation(STGlobals* g, STAllocation* aAllocation) ** The root of the tree is in the globls as the tree is dependent on the ** category file (options) rather than the run. */ -int categorizeAllocation(STOptions* inOptions, STAllocation* aAllocation, STGlobals* g) +int categorizeAllocation(STOptions* inOptions, STContext* inContext, STAllocation* aAllocation, STGlobals* g) { /* Run through the rules in order to see if this allcation matches ** any of them. @@ -525,14 +533,14 @@ int categorizeAllocation(STOptions* inOptions, STAllocation* aAllocation, STGlob } /* Create run for node if not already */ - if (!node->run) + if (!node->runs[inContext->mIndex]) { /* ** Create run with positive timestamp as we can harvest it later ** for callsite details summarization */ - node->run = createRun(PR_IntervalNow()); - if (!node->run) + node->runs[inContext->mIndex] = createRun(PR_IntervalNow()); + if (!node->runs[inContext->mIndex]) { REPORT_ERROR(__LINE__, categorizeAllocation_No_Memory); return -1; @@ -540,27 +548,27 @@ int categorizeAllocation(STOptions* inOptions, STAllocation* aAllocation, STGlob } /* Add allocation into node. We expand the table of allocations in steps */ - if (node->run->mAllocationCount % ST_ALLOC_STEP == 0) + if (node->runs[inContext->mIndex]->mAllocationCount % ST_ALLOC_STEP == 0) { /* Need more space */ STAllocation** allocs; - allocs = (STAllocation**) realloc(node->run->mAllocations, - (node->run->mAllocationCount + ST_ALLOC_STEP) * sizeof(STAllocation*)); + allocs = (STAllocation**) realloc(node->runs[inContext->mIndex]->mAllocations, + (node->runs[inContext->mIndex]->mAllocationCount + ST_ALLOC_STEP) * sizeof(STAllocation*)); if (!allocs) { REPORT_ERROR(__LINE__, categorizeAllocation_No_Memory); return -1; } - node->run->mAllocations = allocs; + node->runs[inContext->mIndex]->mAllocations = allocs; } - node->run->mAllocations[node->run->mAllocationCount++] = aAllocation; + node->runs[inContext->mIndex]->mAllocations[node->runs[inContext->mIndex]->mAllocationCount++] = aAllocation; /* ** Make sure run's stats are calculated. We dont go update the parents of allocation ** at this time. That will happen when we focus on this category. This updating of ** stats will provide us fast categoryreports. */ - recalculateAllocationCost(inOptions, node->run, aAllocation, PR_FALSE); + recalculateAllocationCost(inOptions, node->runs[inContext->mIndex], aAllocation, PR_FALSE); /* Propogate upwards the statistics */ /* XXX */ @@ -570,20 +578,42 @@ int categorizeAllocation(STOptions* inOptions, STAllocation* aAllocation, STGlob return 0; } -typedef PRBool STCategoryNodeProcessor(STRequest* inRequest, STOptions* inOptions, void* clientData, STCategoryNode* node); +typedef PRBool STCategoryNodeProcessor(STRequest* inRequest, STOptions* inOptions, STContext* inContext, void* clientData, STCategoryNode* node); -PRBool freeNodeRunProcessor(STRequest* inRequest, STOptions* inOptions, void* clientData, STCategoryNode* node) +PRBool freeNodeRunProcessor(STRequest* inRequest, STOptions* inOptions, STContext* inContext, void* clientData, STCategoryNode* node) { - if (node->run) + if (node->runs && node->runs[inContext->mIndex]) { - freeRun(node->run); - node->run = NULL; + freeRun(node->runs[inContext->mIndex]); + node->runs[inContext->mIndex] = NULL; } return PR_TRUE; } +PRBool freeNodeRunsProcessor(STRequest* inRequest, STOptions* inOptions, STContext* inContext, void* clientData, STCategoryNode* node) +{ + if (node->runs) + { + PRUint32 loop = 0; + + for(loop = 0; loop < globals.mCommandLineOptions.mContexts; loop++) + { + if (node->runs[loop]) + { + freeRun(node->runs[loop]); + node->runs[loop] = NULL; + } + } + + free(node->runs); + node->runs = NULL; + } + + return PR_TRUE; +} + #if defined(DEBUG_dp) -PRBool printNodeProcessor(STRequest* inRequest, STOptions* inOptions, void* clientData, STCategoryNode* node) +PRBool printNodeProcessor(STRequest* inRequest, STOptions* inOptions, STContext* inContext, void* clientData, STCategoryNode* node) { STCategoryNode* root = (STCategoryNode*) clientData; fprintf(stderr, "%-25s [ %9s size", node->categoryName, @@ -597,6 +627,12 @@ PRBool printNodeProcessor(STRequest* inRequest, STOptions* inOptions, void* clie #endif +typedef struct __struct_optcon { + STOptions* mOptions; + STContext* mContext; +} +optcon; + /* ** compareNode ** @@ -608,9 +644,9 @@ int compareNode(const void* aNode1, const void* aNode2, void* aContext) int retval = 0; STCategoryNode* node1, * node2; PRUint32 a, b; - STOptions* inOptions = (STOptions*)aContext; + optcon *oc = (optcon*)aContext; - if (!aNode1 || !aNode2 || !inOptions) + if (!aNode1 || !aNode2 || !oc->mOptions || !oc->mContext) return 0; node1 = *((STCategoryNode **) aNode1); @@ -618,16 +654,16 @@ int compareNode(const void* aNode1, const void* aNode2, void* aContext) if (node1 && node2) { - if (inOptions->mOrderBy == ST_COUNT) + if (oc->mOptions->mOrderBy == ST_COUNT) { - a = (node1->run) ? node1->run->mStats.mCompositeCount : 0; - b = (node2->run) ? node2->run->mStats.mCompositeCount : 0; + a = (node1->runs[oc->mContext->mIndex]) ? node1->runs[oc->mContext->mIndex]->mStats.mCompositeCount : 0; + b = (node2->runs[oc->mContext->mIndex]) ? node2->runs[oc->mContext->mIndex]->mStats.mCompositeCount : 0; } else { /* Default is by size */ - a = (node1->run) ? node1->run->mStats.mSize : 0; - b = (node2->run) ? node2->run->mStats.mSize : 0; + a = (node1->runs[oc->mContext->mIndex]) ? node1->runs[oc->mContext->mIndex]->mStats.mSize : 0; + b = (node2->runs[oc->mContext->mIndex]) ? node2->runs[oc->mContext->mIndex]->mStats.mSize : 0; } if (a < b) retval = __LINE__; @@ -637,10 +673,17 @@ int compareNode(const void* aNode1, const void* aNode2, void* aContext) return retval; } -PRBool sortNodeProcessor(STRequest* inRequest, STOptions* inOptions, void* clientData, STCategoryNode* node) +PRBool sortNodeProcessor(STRequest* inRequest, STOptions* inOptions, STContext* inContext, void* clientData, STCategoryNode* node) { if (node->nchildren) - NS_QuickSort(node->children, node->nchildren, sizeof(STCategoryNode *), compareNode, inOptions); + { + optcon context; + + context.mOptions = inOptions; + context.mContext = inContext; + + NS_QuickSort(node->children, node->nchildren, sizeof(STCategoryNode *), compareNode, &context); + } return PR_TRUE; } @@ -655,7 +698,7 @@ PRBool sortNodeProcessor(STRequest* inRequest, STOptions* inOptions, void* clien */ #define MODINC(n, mod) ((n+1) % mod) -void walkTree(STCategoryNode* root, STCategoryNodeProcessor func, STRequest* inRequest, STOptions* inOptions, void *clientData, int maxdepth) +void walkTree(STCategoryNode* root, STCategoryNodeProcessor func, STRequest* inRequest, STOptions* inOptions, STContext* inContext, void *clientData, int maxdepth) { STCategoryNode* nodes[1024], *node; PRUint32 begin, end, i; @@ -668,7 +711,7 @@ void walkTree(STCategoryNode* root, STCategoryNodeProcessor func, STRequest* inR while (begin != end) { node = nodes[begin]; - ret = (*func)(inRequest, inOptions, clientData, node); + ret = (*func)(inRequest, inOptions, inContext, clientData, node); if (ret == PR_FALSE) { /* Abort */ @@ -713,9 +756,9 @@ int freeRule(STCategoryRule* rule) return 0; } -void freeNodeRun(STCategoryNode* root) +void freeNodeRuns(STCategoryNode* root) { - walkTree(root, freeNodeRunProcessor, NULL, NULL, NULL, 0); + walkTree(root, freeNodeRunsProcessor, NULL, NULL, NULL, NULL, 0); } void freeNodeMap(STGlobals* g) @@ -738,7 +781,7 @@ int freeCategories(STGlobals* g) /* ** walk the tree and free runs held in nodes */ - freeNodeRun(&g->mCategoryRoot); + freeNodeRuns(&g->mCategoryRoot); /* ** delete nodemap. This is the where nodes get deleted. @@ -764,7 +807,7 @@ int freeCategories(STGlobals* g) ** categorize all the allocations of the run using the rules into ** a tree rooted at globls.mCategoryRoot */ -int categorizeRun(STOptions* inOptions, const STRun* aRun, STGlobals* g) +int categorizeRun(STOptions* inOptions, STContext* inContext, const STRun* aRun, STGlobals* g) { PRUint32 i; #if defined(DEBUG_dp) @@ -775,20 +818,20 @@ int categorizeRun(STOptions* inOptions, const STRun* aRun, STGlobals* g) /* ** First, cleanup our tree */ - walkTree(&g->mCategoryRoot, freeNodeRunProcessor, NULL, inOptions, NULL, 0); + walkTree(&g->mCategoryRoot, freeNodeRunProcessor, NULL, inOptions, inContext, NULL, 0); if (g->mNCategoryMap > 0) { for (i = 0; i < aRun->mAllocationCount; i++) { - categorizeAllocation(inOptions, aRun->mAllocations[i], g); + categorizeAllocation(inOptions, inContext, aRun->mAllocations[i], g); } } /* ** the run is always going to be the one corresponding to the root node */ - g->mCategoryRoot.run = (STRun *) aRun; + g->mCategoryRoot.runs[inContext->mIndex] = (STRun *) aRun; g->mCategoryRoot.categoryName = ST_ROOT_CATEGORY_NAME; #if defined(DEBUG_dp) @@ -802,10 +845,10 @@ int categorizeRun(STOptions* inOptions, const STRun* aRun, STGlobals* g) /* ** sort the tree based on our sort criterion */ - walkTree(&g->mCategoryRoot, sortNodeProcessor, NULL, inOptions, NULL, 0); + walkTree(&g->mCategoryRoot, sortNodeProcessor, NULL, inOptions, inContext, NULL, 0); #if defined(DEBUG_dp) - walkTree(&g->mCategoryRoot, printNodeProcessor, NULL, inOptions, &g->mCategoryRoot, 0); + walkTree(&g->mCategoryRoot, printNodeProcessor, NULL, inOptions, inContext, &g->mCategoryRoot, 0); #endif return 0; @@ -818,36 +861,36 @@ int categorizeRun(STOptions* inOptions, const STRun* aRun, STGlobals* g) ** Generate the category report - a list of all categories and details about each ** depth parameter controls how deep we traverse the category tree. */ -PRBool displayCategoryNodeProcessor(STRequest* inRequest, STOptions* inOptions, void* clientData, STCategoryNode* node) +PRBool displayCategoryNodeProcessor(STRequest* inRequest, STOptions* inOptions, STContext* inContext, void* clientData, STCategoryNode* node) { STCategoryNode* root = (STCategoryNode *) clientData; PRUint32 byteSize = 0, heapCost = 0, count = 0; double percent = 0; STOptions customOps; - if (node->run) + if (node->runs[inContext->mIndex]) { /* ** Byte size */ - byteSize = node->run->mStats.mSize; + byteSize = node->runs[inContext->mIndex]->mStats.mSize; /* ** Composite count */ - count = node->run->mStats.mCompositeCount; + count = node->runs[inContext->mIndex]->mStats.mCompositeCount; /* ** Heap operation cost **/ - heapCost = node->run->mStats.mHeapRuntimeCost; + heapCost = node->runs[inContext->mIndex]->mStats.mHeapRuntimeCost; /* ** % of total size */ - if (root->run) + if (root->runs[inContext->mIndex]) { - percent = ((double) byteSize) / root->run->mStats.mSize * 100; + percent = ((double) byteSize) / root->runs[inContext->mIndex]->mStats.mSize * 100; } } @@ -887,7 +930,7 @@ int displayCategoryReport(STRequest* inRequest, STCategoryNode *root, int depth) " \n" ); - walkTree(root, displayCategoryNodeProcessor, inRequest, &inRequest->mOptions, root, depth); + walkTree(root, displayCategoryNodeProcessor, inRequest, &inRequest->mOptions, inRequest->mContext, root, depth); PR_fprintf(inRequest->mFD, "\n"); diff --git a/tools/trace-malloc/spacetrace.c b/tools/trace-malloc/spacetrace.c index 1c9e58b10c75..7dbd20baa63f 100644 --- a/tools/trace-malloc/spacetrace.c +++ b/tools/trace-malloc/spacetrace.c @@ -1283,11 +1283,11 @@ void freeRun(STRun* aRun) ** Returns NULL on failure. ** Must call freeRun() with the new STRun. */ -STRun* createRunFromGlobal(STOptions* inOptions) +STRun* createRunFromGlobal(STOptions* inOptions, STContext* inContext) { STRun* retval = NULL; - if(NULL != inOptions) + if(NULL != inOptions && NULL != inContext) { /* ** We stamp the run. @@ -1327,7 +1327,7 @@ STRun* createRunFromGlobal(STOptions* inOptions) /* ** Categorize the run. */ - failure = categorizeRun(inOptions, retval, &globals); + failure = categorizeRun(inOptions, inContext, retval, &globals); if (0 != failure) { REPORT_ERROR(__LINE__, categorizeRun); @@ -1341,9 +1341,9 @@ STRun* createRunFromGlobal(STOptions* inOptions) if (node) { /* Recalculate cost of run */ - recalculateRunCost(inOptions, node->run); + recalculateRunCost(inOptions, node->runs[inContext->mIndex]); - retval = node->run; + retval = node->runs[inContext->mIndex]; } } } @@ -4915,7 +4915,7 @@ STContext* contextLookup(STOptions* inOptions) { unlock = PR_TRUE; - retval->mSortedRun = createRunFromGlobal(&inCache->mItems[retval->mIndex].mOptions); + retval->mSortedRun = createRunFromGlobal(&inCache->mItems[retval->mIndex].mOptions, &inCache->mItems[retval->mIndex].mContext); } /* @@ -4936,8 +4936,8 @@ STContext* contextLookup(STOptions* inOptions) if(node) { /* Recalculate cost of run */ - recalculateRunCost(&inCache->mItems[retval->mIndex].mOptions, node->run); - retval->mSortedRun = node->run; + recalculateRunCost(&inCache->mItems[retval->mIndex].mOptions, node->runs[retval->mIndex]); + retval->mSortedRun = node->runs[retval->mIndex]; } #if ST_WANT_GRAPHS @@ -5486,7 +5486,7 @@ void handleClient(void* inArg) ** mime type, otherwise, say it is text/html. */ PR_fprintf(aFD, "HTTP/1.1 200 OK%s", crlf); - PR_fprintf(aFD, "Server: %s%s", "$Id: spacetrace.c,v 1.34 2002/05/13 00:01:15 blythe%netscape.com Exp $", crlf); + PR_fprintf(aFD, "Server: %s%s", "$Id: spacetrace.c,v 1.35 2002/05/13 01:48:29 blythe%netscape.com Exp $", crlf); PR_fprintf(aFD, "Content-type: "); if(NULL != strstr(start, ".png")) { @@ -6057,6 +6057,16 @@ int main(int aArgCount, char** aArgArray) REPORT_ERROR(__LINE__, initCaches); } + /* + ** Small category code init. + */ + globals.mCategoryRoot.runs = (STRun**)calloc(globals.mCommandLineOptions.mContexts, sizeof(STRun*)); + if(NULL == globals.mCategoryRoot.runs) + { + retval = __LINE__; + REPORT_ERROR(__LINE__, calloc); + } + /* ** Show help on usage if need be. */ @@ -6095,6 +6105,15 @@ int main(int aArgCount, char** aArgArray) ** All threads are joined/done by this line. */ + /* + ** Category root has a small modification to clear up. + */ + if(NULL != globals.mCategoryRoot.runs) + { + free(globals.mCategoryRoot.runs); + globals.mCategoryRoot.runs = NULL; + } + /* ** Blow away our caches. */ diff --git a/tools/trace-malloc/spacetrace.h b/tools/trace-malloc/spacetrace.h index c78cd8a9ec93..e3a192322fe6 100644 --- a/tools/trace-malloc/spacetrace.h +++ b/tools/trace-malloc/spacetrace.h @@ -375,9 +375,12 @@ struct __struct_STCategoryNode PRUint32 nchildren; /* - ** The Run. Valid for both leaf and parent nodes. + ** The Run(s). Valid for both leaf and parent nodes. + ** One run per --Context to handle multiple data sets. + ** The relevant index for the particular request will be + ** mIndex stored by the mContext of the request. */ - STRun *run; + STRun **runs; }; @@ -400,7 +403,6 @@ struct __struct_STCategoryRule ** The node this should be categorized into */ STCategoryNode* node; - }; @@ -688,7 +690,7 @@ typedef struct __struct_STGlobals extern STRun* createRun(PRUint32 aStamp); extern void freeRun(STRun* aRun); extern int initCategories(STGlobals* g); -extern int categorizeRun(STOptions* inOptions, const STRun* aRun, STGlobals* g); +extern int categorizeRun(STOptions* inOptions, STContext* inContext, const STRun* aRun, STGlobals* g); extern STCategoryNode* findCategoryNode(const char *catName, STGlobals *g); extern int freeCategories(STGlobals* g); extern int displayCategoryReport(STRequest* inRequest, STCategoryNode *root, int depth);