📄 mpralloc.c
字号:
mprLock(app->allocLock); if (alloc->inAllocException == 0) { alloc->inAllocException = 1; mprUnlock(app->allocLock); rc = (alloc->cback)(app, size, alloc->stats.bytesAllocated, granted); mprLock(app->allocLock); app->alloc.inAllocException = 0; mprUnlock(app->allocLock); return rc; } return 0;}/******************************************************************************/void mprSetAllocLimits(MprApp *app, uint redLine, uint maxMemory){ app->alloc.stats.redLine = redLine; app->alloc.stats.maxMemory = maxMemory;}/******************************************************************************/MprAllocCback mprSetAllocCallback(MprApp *app, MprAllocCback cback){ MprAllocCback old; mprAssert(app); mprAssert(VALID_BLK(app)); old = app->alloc.cback; app->alloc.cback = cback; return old;}/******************************************************************************/uint mprGetAllocBlockSize(MprCtx ptr){ MprBlk *bp; mprAssert(VALID_BLK(ptr)); if (ptr == 0) { return 0; } bp = GET_HDR(ptr); mprAssert(VALID_HDR(bp)); CHECK_HDR(bp); return bp->size;}/******************************************************************************//* * Return the total block count used by a block including all children */uint mprGetAllocBlockCount(MprCtx ptr){ MprBlk *bp, *firstChild, *cp; uint count; mprAssert(VALID_BLK(ptr)); if (ptr == 0) { return 0; } bp = GET_HDR(ptr); mprAssert(VALID_HDR(bp)); /* * Add one for itself */ count = 1; if ((firstChild = bp->children) != 0) { cp = firstChild; do { count += mprGetAllocBlockCount(GET_PTR(cp)); cp = cp->next; } while (cp != firstChild); } return count;}/******************************************************************************//* * Return the total of all memory allocated including slabs */uint mprGetAllocBlockMemory(MprCtx ptr){ MprBlk *bp, *firstChild, *cp; uint count; mprAssert(VALID_BLK(ptr)); if (ptr == 0) { return 0; } bp = GET_HDR(ptr); mprAssert(VALID_HDR(bp)); count = bp->size + HDR_SIZE; if ((firstChild = bp->children) != 0) { cp = firstChild; do { count += mprGetAllocBlockMemory(GET_PTR(cp)); cp = cp->next; } while (cp != firstChild); } return count;}/******************************************************************************/#if BLD_FEATURE_ALLOC_LEAK_TRACKconst char *mprGetAllocLocation(MprCtx ptr){ MprBlk *bp; if (ptr == 0) { return 0; } mprAssert(VALID_BLK(ptr)); bp = GET_HDR(ptr); mprAssert(VALID_HDR(bp)); return bp->location;}#endif/******************************************************************************/void *mprGetAllocParent(MprCtx ptr){ MprBlk *bp; mprAssert(VALID_BLK(ptr)); if (ptr == 0) { return 0; } bp = GET_HDR(ptr); mprAssert(VALID_HDR(bp)); CHECK_HDR(bp); return GET_PTR(bp->parent);}/******************************************************************************/MprAllocStats *mprGetAllocStats(MprApp *app){ mprAssert(VALID_BLK(app)); return &app->alloc.stats;}/******************************************************************************/#if BLD_FEATURE_ALLOC_STATSMprSlabStats *mprGetSlabAllocStats(MprApp *app, int slabIndex){ MprSlab *slab; mprAssert(VALID_BLK(app)); if (0 <= slabIndex && slabIndex < MPR_MAX_SLAB) { slab = &app->alloc.slabs[slabIndex]; return &slab->stats; } mprAssert(0 <= slabIndex && slabIndex < MPR_MAX_SLAB); return 0;}#endif /* BLD_FEATURE_ALLOC_STATS *//******************************************************************************/#if BLD_DEBUGint mprPrintAllocBlocks(MprCtx ptr, int indent){ MprBlk *bp, *firstChild, *cp; const char *location; int subTotal, size, indentSpaces, code; subTotal = 0; bp = GET_HDR(ptr); if (! (bp->flags & ALLOC_FLAGS_REQUIRED)) { size = bp->size + HDR_SIZE; /* * Take one level off because we don't trace app */ indentSpaces = indent; if (bp->flags & ALLOC_FLAGS_REQUIRED) { code = 'R'; } else if (bp->flags & ALLOC_FLAGS_IS_SLAB) { code = 'S'; } else { code = ' '; }#if BLD_FEATURE_ALLOC_LEAK_TRACK location = bp->location;#else location = "";#endif mprLog(bp->app, 0, "%c %.*s %-16s %.*s size %5d has %3d deps, total %6d", code, indentSpaces, " ", mprGetBaseName(location), 8 - indent, " ", size, mprGetAllocBlockCount(GET_PTR(bp)), mprGetAllocBlockMemory(GET_PTR(bp)) /* (uint) bp */ ); subTotal += size; } if ((firstChild = bp->children) != 0) { cp = firstChild; do { subTotal += mprPrintAllocBlocks(GET_PTR(cp), indent + 2); cp = cp->next; } while (cp != firstChild); } return subTotal;}#endif/******************************************************************************/#if BLD_FEATURE_ALLOC_STATS/* * Print a memory allocation report that includes a list of allocated blocks * and a statistics summary */void mprPrintAllocReport(MprApp *app, bool printBlocks, const char *msg){ MprSlabStats *stats; uint total; int i, size; mprAssert(VALID_BLK(app)); if (msg) { mprLog(app, 0, " "); mprLog(app, 0, "%s", msg); }#if BLD_DEBUG /* * Do block stats */ if (printBlocks) { int sum; mprLog(app, 0, " "); sum = mprPrintAllocBlocks(app, 0); if (sum) { mprLog(app, 0, " Sum of blocks %d", sum); } else { mprLog(app, 0, " None"); } }#endif /* * Do Slab stats */ mprLog(app, 0, " "); mprLog(app, 0, "MPR Slab Memory Stats"); mprLog(app, 0, " "); mprLog(app, 0, " Index Size Total Allocated Free PeakAlloc PeakFree TotalAlloc"); total = 0; for (i = 0; i < MPR_MAX_SLAB; i++) { stats = &app->alloc.slabs[i].stats; size = 1 << (i + 5); if (stats->totalAllocCount > 0) { mprLog(app, 0, " %2d %6d %8d %9d %6d %9d %8d %10d", i, size, size * (stats->allocCount + stats->freeCount), stats->allocCount, stats->freeCount, stats->peakAllocCount, stats->peakFreeCount, stats->totalAllocCount); total += size * (stats->allocCount + stats->freeCount); } } mprLog(app, 0, " "); mprLog(app, 0, "MPR Total Allocated Slab RAM: %10d", total); mprLog(app, 0, "MPR Total Allocated RAM: %10d", mprGetAllocatedMemory(app)); mprLog(app, 0, "MPR Peak Allocated RAM: %10d", mprGetPeakAllocatedMemory(app)); mprLog(app, 0, " ");}/******************************************************************************//* * Return the total memory allocated. */uint mprGetAllocatedMemory(MprCtx ctx){ MprApp *app; app = mprGetApp(ctx); return app->alloc.stats.bytesAllocated;}/******************************************************************************//* * Return the peak memory allocated. */uint mprGetPeakAllocatedMemory(MprCtx ctx){ MprApp *app; app = mprGetApp(ctx); return app->alloc.stats.peakAllocated;}/******************************************************************************//* * Return memory in the MPR slab. This excludes the EJS slabs */uint mprGetAllocatedSlabMemory(MprCtx ctx){ MprApp *app; MprSlabStats *stats; uint total; int i, size; app = mprGetApp(ctx); total = 0; for (i = 0; i < MPR_MAX_SLAB; i++) { stats = &app->alloc.slabs[i].stats; size = 1 << (i + 5); if (stats->totalAllocCount > 0) { total += size * (stats->allocCount + stats->freeCount); } } return total;}#endif /* BLD_FEATURE_ALLOC_STATS *//******************************************************************************/MprDestructor mprSetDestructor(MprCtx ptr, MprDestructor destructor){ MprDestructor old; MprBlk *bp; mprAssert(VALID_BLK(ptr)); if (ptr == 0) { return 0; } bp = GET_HDR(ptr); mprAssert(bp); mprAssert(VALID_HDR(bp)); mprAssert(ptr != mprGetAllocParent(ptr)); CHECK_HDR(bp); old = bp->destructor; bp->destructor = destructor; return old;}/******************************************************************************/int mprIsAllocBlockValid(MprCtx ptr){ MprBlk *bp; bp = GET_HDR(ptr); return (bp && VALID_HDR(bp));}/******************************************************************************/#if VALIDATE_ALLOC/* * Exhaustive validation of the block and its children. Does not go recursive * as it would be too slow. */int mprValidateBlock(MprCtx ptr){ MprBlk *bp, *parent, *cp, *firstChild; int count; mprAssert(ptr); mprAssert(VALID_BLK(ptr)); bp = GET_HDR(ptr); mprAssert(bp); mprAssert(VALID_HDR(bp)); mprAssert(VALID_HDR(bp->parent)); if (ptr != bp->app) { mprAssert(bp != bp->parent); } mprAssert(! (bp->flags & ALLOC_FLAGS_FREE)); mprAssert(! (bp->flags & ALLOC_FLAGS_FREEING)); /* * */ count = 0; parent = bp->parent; if ((firstChild = bp->children) != 0) { cp = firstChild; mprAssert((int) cp != 0xfeefee); do { mprAssert(bp->next->prev == bp); mprAssert(bp->prev->next == bp); mprAssert(bp->prev->parent == parent); mprAssert(bp->next->parent == parent); count++; cp = cp->next; if (bp->next == bp) { mprAssert(bp->prev == bp); if (ptr != bp->app) { mprAssert(parent->children == bp); } } if (bp->prev == bp) { mprAssert(bp->next == bp); if (ptr != bp->app) { mprAssert(parent->children == bp); } } } while (cp != firstChild); } return 0;}#endif/******************************************************************************//* * Validate a block and all children */int mprValidateAllocTree(MprCtx ptr){#if VALIDATE_ALLOC MprBlk *bp, *cp, *firstChild; mprAssert(ptr); mprAssert(VALID_BLK(ptr)); bp = GET_HDR(ptr); mprValidateBlock(GET_PTR(bp)); if ((firstChild = bp->children) != 0) { cp = firstChild; do { mprValidateAllocTree(GET_PTR(cp)); cp = cp->next; } while (cp != firstChild); }#endif return 0;}/******************************************************************************/#if UNUSED && FUTURE/* * Exhaustive validation of the block and its children. Does not go recursive * as it would be too slow. */int mprValidateSlabs(MprApp *app){ MprSlab *slab; MprSlabStats *slabStats; MprSlabBlock *sp; int count, i; for (i = 0; i < MPR_MAX_SLAB; i++) { slab = &app->alloc.slabs[i]; slabStats = &slab->stats; count = 0; for (sp = slab->next; sp; sp = sp->next) { count++; } mprAssert(count == (int) slabStats->freeCount); } return 0;}#endif/******************************************************************************/void mprAllocAbort(){#if BREW printf("Bad block header");#else exit(255);#endif}/******************************************************************************/#undef mprGetApp/* * Get the root parent from any block (which is the MprApp structure) */MprApp *mprGetApp(MprCtx ptr){ MprBlk *bp; mprAssert(ptr); bp = GET_HDR(ptr); mprAssert(VALID_HDR(bp)); CHECK_HDR(bp); mprAssert(bp->app->magic == APP_MAGIC); return bp->app;}/******************************************************************************/int mprGetAllocErrors(MprCtx ctx){ MprApp *app; app = mprGetApp(ctx); return app->alloc.stats.errors;}/******************************************************************************/void mprClearAllocErrors(MprCtx ctx){ MprApp *app; app = mprGetApp(ctx); app->alloc.stats.errors = 0;}/******************************************************************************//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim:tw=78 * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -