⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpralloc.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *	Rallocate a block */void *mprReallocBlock(MPR_LOC_DEC(ctx, loc), void *ptr, uint size){	MprBlk	*bp, *newbp, *firstChild, *cp;	MprApp	*app;	void	*newPtr;	mprAssert(VALID_BLK(ctx));	mprAssert(size > 0);	if (ptr == 0) {		return mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);	}		mprAssert(VALID_BLK(ptr));	bp = GET_HDR(ptr);	mprAssert(bp);	mprAssert(VALID_HDR(bp));	CHECK_HDR(bp);	if (size < bp->size) {		return ptr;	}	newPtr = mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);	if (newPtr == 0) {		bp->flags &= ~ALLOC_FLAGS_FREE;		free(bp);		return 0;	}	newbp = GET_HDR(newPtr);	mprAssert(newbp->size >= size);	memcpy((char*) newbp + HDR_SIZE, (char*) bp + HDR_SIZE, bp->size);	mprAssert(newbp->size >= size);	/* 	 *	Fix the next / prev pointers 	 */	app = bp->app;	mprLock(app->allocLock);	newbp->next->prev = newbp;	newbp->prev->next = newbp;	/*	 *	Need to fix the parent pointer of all children 	 */	if ((firstChild = newbp->children) != 0) {		cp = firstChild;		do {			cp->parent = newbp;			cp = cp->next;		} while (cp != firstChild);	}	/*	 *	May need to set the children pointer of our parent 	 */	if (newbp->parent->children == bp) {		newbp->parent->children = newbp;	}	/* 	 *	Free the original block	 */	mprFree(ptr);	mprUnlock(app->allocLock);	return GET_PTR(newbp);}/******************************************************************************//* *	Allocate a block from a slab */void *mprSlabAllocBlock(MPR_LOC_DEC(ctx, loc), uint size, uint inc){#if NO_SLAB	return mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);#else	MprBlk			*parent, *bp;	MprSlabBlock	*sb;	MprApp			*app;	MprSlab			*slab;	int				slabIndex;	if (ctx == 0) {		mprAssert(ctx);		return 0;	}	mprAssert(size > 0);	mprAssert(VALID_BLK(ctx));	parent = GET_HDR(ctx);	mprAssert(VALID_HDR(parent));	CHECK_HDR(parent);	size = SLAB_ALIGN(size);	app = parent->app;	mprAssert(app);	slabIndex = GET_SLAB(size);	if (slabIndex < 0 || slabIndex >= MPR_MAX_SLAB) {		return mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);	}	/* 	 *	Dequeue a block from the slab. "sb" will point to the user data	 *	portion of the block (i.e. after the MprBlk header). Slabs must be 	 *	allocated off the "slabs" context to ensure they don't get freed 	 *	until after all other blocks are freed.	 */	mprLock(app->allocLock);	slab = &app->alloc.slabs[slabIndex];	if ((sb = slab->next) == 0) {		if (growSlab(MPR_LOC_ARGS(parent->app->alloc.slabs), 				slab, size, inc) < 0) {			mprUnlock(app->allocLock);			return 0;		}		sb = slab->next;	}	mprAssert(sb);	/* 	 *	Dequeue the block	 */	slab->next = sb->next;#if BLD_FEATURE_ALLOC_STATS{	MprSlabStats	*slabStats;	/*	 *	Update the slab stats	 */	slabStats = &slab->stats;	slabStats->totalAllocCount++;	slabStats->freeCount--;	slabStats->allocCount++;	if (slabStats->allocCount > slabStats->peakAllocCount) {		slabStats->peakAllocCount = slabStats->allocCount;	}}#endif /* BLD_FEATURE_ALLOC_STATS */	bp = GET_HDR(sb);#if BLD_DEBUG && !BREW	if (bp == stopAlloc) {		mprBreakpoint(MPR_LOC, "breakOnAddr");	}#endif	bp->size = size;	bp->flags = ALLOC_MAGIC | ALLOC_FLAGS_SLAB_BLOCK;	bp->destructor = 0;	bp->parent = parent;	if (parent->children == 0) {		parent->children = bp;		bp->next = bp->prev = bp;	} else {		/*		 *	Append to the end of the list. Preserve alloc order		 */		bp->next = parent->children;		bp->prev = parent->children->prev;		parent->children->prev->next = bp;		parent->children->prev = bp;	}	bp->children = 0;	bp->app = app;#if BLD_FEATURE_ALLOC_LEAK_TRACK	bp->location = loc;#endif	mprUnlock(app->allocLock);	return GET_PTR(bp);#endif}/******************************************************************************//* *	Return a block back to its slab */static void slabFree(MprBlk *bp){	MprSlab			*slab;	MprApp			*app;	void			*ptr;	int				slabIndex;	mprAssert(VALID_HDR(bp));	slabIndex = GET_SLAB(bp->size);	mprAssert(0 <= slabIndex && slabIndex < MPR_MAX_SLAB);	if (0 <= slabIndex && slabIndex < MPR_MAX_SLAB) {		mprLock(bp->app->allocLock);		slab = &bp->app->alloc.slabs[slabIndex];		app = bp->app;#if BLD_DEBUG		memset(bp, 0xfc, bp->size + HDR_SIZE);#endif		ptr = GET_PTR(bp);		((MprSlabBlock*) ptr)->next = slab->next;		slab->next = ((MprSlabBlock*) ptr);#if BLD_FEATURE_ALLOC_STATS{		MprSlabStats	*slabStats;		slabStats = &slab->stats;		slabStats->freeCount++;		slabStats->allocCount--;		if (slabStats->freeCount >= slabStats->peakFreeCount) {			slabStats->peakFreeCount = slabStats->freeCount;		}}#endif		mprUnlock(app->allocLock);	}}/******************************************************************************//* *	Grow the slab and return the next free block *	Must be called locked. */static int growSlab(MPR_LOC_DEC(ctx, loc), MprSlab *slab, uint size, uint inc){	MprBlk			*bp;	MprSlabBlock	*sb;	int				i, chunkSize, len;	mprAssert(VALID_BLK(ctx));	mprAssert(slab);	mprAssert(size > 0);	/* 	 *	Take the maximum requested by anyone	 */	slab->preAllocateIncr = max(slab->preAllocateIncr, inc);	/*	 *	We allocate an array of blocks each of user "size" bytes.	 */	chunkSize = HDR_SIZE + size;	len = chunkSize * slab->preAllocateIncr;	bp = mprAllocBlock(MPR_LOC_PASS(ctx, loc), len);#if BLD_DEBUG	memset(bp, 0xf1, len);#endif	if (bp == 0) {		mprAssert(0);		return MPR_ERR_MEMORY;	}	bp->flags |= ALLOC_FLAGS_IS_SLAB;	/* 	 *	We store the slab information in the user data portion	 */	sb = (MprSlabBlock*) GET_PTR(bp);	sb = (MprSlabBlock*) ((char*) sb + len - chunkSize);	for (i = slab->preAllocateIncr - 1; i >= 0; i--) {		sb->next = slab->next;		slab->next = sb;		sb = (MprSlabBlock*) ((char*) sb - chunkSize);	}#if BLD_FEATURE_ALLOC_STATS{	MprSlabStats	*stats;	stats = &slab->stats;	stats->freeCount += slab->preAllocateIncr;	if (stats->freeCount > stats->peakFreeCount) {		stats->peakFreeCount = stats->freeCount;	}}#endif	return 0;}/******************************************************************************//* *	Set the pre-allocate amount */int mprSetSlabPreAllocate(MprCtx ctx, int slabIndex, int preAllocateIncr){	MprApp		*app;	MprSlab		*slab;	mprAssert(VALID_BLK(ctx));	mprAssert(0 <= slabIndex && slabIndex < MPR_MAX_SLAB);	mprAssert(preAllocateIncr > 0);	if (0 <= slabIndex && slabIndex < MPR_MAX_SLAB) {		app = mprGetApp(ctx);		slab = &app->alloc.slabs[slabIndex];		slab->preAllocateIncr = preAllocateIncr;	} else {		return MPR_ERR_BAD_ARGS;	}	return 0;}/******************************************************************************/void *mprSlabAllocZeroedBlock(MPR_LOC_DEC(ctx, loc), uint size, uint inc){	void	*newBlock;	mprAssert(VALID_BLK(ctx));	mprAssert(size > 0);	newBlock = mprSlabAllocBlock(MPR_LOC_PASS(ctx, loc), size, inc);	if (newBlock) {		memset(newBlock, 0, size);	}	return newBlock;}/******************************************************************************//* *	Internal strdup function. Will use the slab allocator for small strings */char *mprStrdupInternal(MPR_LOC_DEC(ctx, loc), const char *str){	char	*newp;	int		len;	mprAssert(VALID_BLK(ctx));	if (str == 0) {		str = "";	}	len = strlen(str) + 1;	if (len < MPR_SLAB_STR_MAX) {		newp = mprSlabAllocBlock(MPR_LOC_PASS(ctx, loc), MPR_SLAB_STR_MAX,			MPR_SLAB_STR_INC);	} else {		newp = mprAllocBlock(MPR_LOC_PASS(ctx, loc), len);	}	if (newp) {		memcpy(newp, str, len);	}	return newp;}/******************************************************************************//* *	Internal strndup function. Will use the slab allocator for small strings */char *mprStrndupInternal(MPR_LOC_DEC(ctx, loc), const char *str, uint size){	char	*newp;	uint	len;	mprAssert(VALID_BLK(ctx));	if (str == 0) {		str = "";	}	len = strlen(str) + 1;	len = min(len, size);	if (len < MPR_SLAB_STR_MAX) {		newp = mprSlabAllocBlock(MPR_LOC_PASS(ctx, loc), MPR_SLAB_STR_MAX,			MPR_SLAB_STR_INC);	} else {		newp = mprAllocBlock(MPR_LOC_PASS(ctx, loc), len);	}	if (newp) {		memcpy(newp, str, len);	}	return newp;}/******************************************************************************//* *	Internal memcpy function. Will use the slab allocator for small strings */void *mprMemdupInternal(MPR_LOC_DEC(ctx, loc), const void *ptr, uint size){	char	*newp;	mprAssert(VALID_BLK(ctx));	if (size < MPR_SLAB_STR_MAX) {		newp = mprSlabAllocBlock(MPR_LOC_PASS(ctx, loc), MPR_SLAB_STR_MAX,			MPR_SLAB_STR_INC);	} else {		newp = mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);	}	if (newp) {		memcpy(newp, ptr, size);	}	return newp;}/******************************************************************************//* *	Steal a block from one context and insert in another */int mprStealAllocBlock(MPR_LOC_DEC(ctx, loc), const void *ptr){	MprBlk		*bp, *parent;	if (ptr == 0) {		return 0;	}	mprAssert(VALID_BLK(ctx));	mprAssert(VALID_BLK(ptr));	bp = GET_HDR(ptr);#if BLD_DEBUG && !BREW	if (bp == stopAlloc) {		mprBreakpoint(MPR_LOC, "breakOnAddr");	}#endif	mprAssert(bp);	mprAssert(VALID_HDR(bp));	mprAssert(ptr != mprGetAllocParent(ptr));	CHECK_HDR(bp);	mprAssert(bp->prev);	mprAssert(bp->prev->next);	mprAssert(bp->next);	mprAssert(bp->next->prev);	parent = bp->parent;	mprAssert(VALID_HDR(parent));	mprLock(bp->app->allocLock);	if (parent->children == bp) {		if (bp->next == bp) {			parent->children = 0;		} else {			parent->children = bp->next;		}	}	bp->prev->next = bp->next;	bp->next->prev = bp->prev;	parent = GET_HDR(ctx);	mprAssert(VALID_HDR(parent));	bp->parent = parent;	if (parent->children == 0) {		parent->children = bp;		bp->next = bp->prev = bp;	} else {		bp->next = parent->children;		bp->prev = parent->children->prev;		parent->children->prev->next = bp;		parent->children->prev = bp;	}#if BLD_FEATURE_ALLOC_LEAK_TRACK	bp->location = loc;#endif	VALIDATE_BLOCK(GET_PTR(bp));	mprUnlock(bp->app->allocLock);	return 0;}/******************************************************************************/void mprSetRequiredAlloc(MprCtx ptr, bool recurse){	MprBlk	*bp, *firstChild, *cp;	bp = GET_HDR(ptr);	bp->flags |= ALLOC_FLAGS_REQUIRED;	if (recurse && (firstChild = bp->children) != 0) {		cp = firstChild;		do {			mprSetRequiredAlloc(GET_PTR(cp), recurse);			cp = cp->next;		} while (cp != firstChild);	}}/******************************************************************************//* *	Monitor stack usage. Return true if the stack has grown */int mprStackCheck(MprCtx ptr){	MprApp *app;	int 	size;	mprAssert(VALID_BLK(ptr));	app = mprGetApp(ptr);	size = (int) app->stackStart - (int) &app;	if (size < 0) {		app->maxStack -= size;		app->stackStart = (void*) &app;		size = 0;	}	if ((uint) size > app->maxStack) {		app->maxStack = size;		return 1;	}	return 0;}/******************************************************************************//* *	Return the stack size */int mprStackSize(MprCtx ptr){	MprApp *app;	mprAssert(VALID_BLK(ptr));	app = mprGetApp(ptr);	return app->maxStack;}/******************************************************************************/static int mprAllocException(MPR_LOC_DEC(ctx, loc), uint size, bool granted){	MprApp		*app;	MprAlloc	*alloc;	int			rc;	mprAssert(VALID_BLK(ctx));	app = mprGetApp(ctx);	alloc = &app->alloc;	if (alloc->cback == 0) {		return 0;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -