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

📄 rmmmhomemade.c

📁 神龙解压卡Linux下的完整开发包,绝对是超值超值超值
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (pZone->pCSops!=NULL) pZone->pCSops->Leave(pZone->cs);#ifdef USE_LEAK_CHECKER	if (pZone->recordLeaks) {		RMRecordMallocLeakChecker (pZone->leakChecker, 					(void *)DataAddress(pCurrent,pZone->alignment),					submittedSize);	}#endif		return (void *)DataAddress(pCurrent,pZone->alignment);}void *RMCallocInZone(RMuint32 zid,RMuint32 nmemb,RMuint32 size){	RMuint8 *beginning=(RMuint8 *)RMMallocInZone(zid,size*nmemb);	RMMemset(beginning,0,size*nmemb);	return (void *)beginning;}void RMFreeInZone(RMuint32 zid,void *ptr){	RMmemoryZone *pZone=&zones[zid];	memoryBlockHeader *pX;	RMuint32 sizeOfX = 0;		memoryBlockHeader *pCurrent,*pPrevious;	memoryBlockHeader *pL=(memoryBlockHeader *)NULL,*pR=(memoryBlockHeader *)NULL;	memoryBlockHeader **ppFirstFree=(memoryBlockHeader **)(&(pZone->pFirstFree));	if (pZone->pCSops!=NULL) pZone->pCSops->Enter(pZone->cs);	if (!(	      (AmIBefore((memoryBlockHeader *)(pZone->beginning+HeaderSkip(pZone->alignment)-1),			 (memoryBlockHeader *)ptr)	       &&	       AmIBefore((memoryBlockHeader *)ptr,			 (memoryBlockHeader *)(pZone->beginning+pZone->totalSize)))	      )) goto bad;			// rewind to the memory block header.	pX=(memoryBlockHeader *)(((RMuint8 *)ptr)-HeaderSkip(pZone->alignment));	sizeOfX=pX->size;	// can we assume this is a valid block header? Let's check the hash.	if (Hash((RMuint32)ptr,pX->size)!=pX->hash) goto bad;	/**************************************************************         Let's make eight cases: the block we want to free is pX.	 EMPTYFREELIST: the free block has no blocks. Make pX part of it. Over.	 BEFOREFIRSTNEIGHBOR: pX is the left neighbor of the first free block.	 Gather them (one block disappears). Over.	 BEFOREFIRST: pX is not the left neighbor, but is before the first	 free block. Make pX the first free block and link to the free block list. Over.	 Now, let's go thru the free block list:	 while (pCurrent) { 	  pCurrent is a candidate to be left neighbor pL of pX	  and pCurrent->next a candidate to be the right neighbor pR of pX.	    	  MIDDLEBOTH: if we find both neighbors L and R, we gather pL, pX and pR (two blocks disappear). Over.	  MIDDLELEFT: if we find only the left neighbor L, we gather pL and pX (one block disappears). Over.	  MIDDLERIGHT: if we find only the right neighbor R, we gather pX and pR (one block disappears). Over.	  MIDDLENONE: if pCurrent->next exists and pCurrent < pX < pCurrent->next 	   we cannot gather anything, but we insert this lonely block in the free list. Over.	  pPrevious=pCurrent; 	  pCurrent=pCurrent->next; 	 }	 	 If the loop exits, it means pX is after the last free block (his name is pPrevious).	 pX cannot be the right neighbor of pPrevious, because this case has been treated by case MIDDLELEFT.	 Only solution left:	 AFTERLAST: pX is not the right neighbor, but is after pPrevious. Make a new link. Over.	 All cases have been treated.	 **************************************************************/	// EMPTYFREELIST	if (*ppFirstFree==NULL) {		RMDBGLOG((MEMDBG,"RMFreeInZone: EMPTYFREELIST\n"));				pX->hash=freeBlockHash;				*ppFirstFree=pX;		pX->next=(memoryBlockHeader *)NULL;		goto returnok;	}	// BEFOREFIRSTNEIGHBOR	if (AmILeftNeighbor(pX,*ppFirstFree,pZone->alignment)) {		RMDBGLOG((MEMDBG,"RMFreeInZone: BEFOREFIRSTNEIGHBOR\n"));				(*ppFirstFree)->hash=disappearedHash;		pX->hash=freeBlockHash;		pX->next=(*ppFirstFree)->next;		pX->size+=HeaderSkip(pZone->alignment)+(*ppFirstFree)->size;		*ppFirstFree=pX;				goto returnok;	}		// BEFOREFIRST	if (AmIBefore(pX,*ppFirstFree)) {		RMDBGLOG((MEMDBG,"RMFreeInZone: BEFOREFIRST\n"));				pX->hash=freeBlockHash;		pX->next=*ppFirstFree;		*ppFirstFree=pX;		goto returnok;	}		pPrevious=(memoryBlockHeader *)NULL;	pCurrent=*ppFirstFree;		while (pCurrent) {		/* notice that once one of pL or pR is not NULL we exit the while		   loop, so no need to reset them at each turn. */				// is pCurrent the left neighbor?		if (AmILeftNeighbor(pCurrent,pX,pZone->alignment)) pL=pCurrent;				// is pCurrent->next the right neighbor?		if (pCurrent->next) 			if (AmILeftNeighbor(pX,pCurrent->next,pZone->alignment)) pR=pCurrent->next;				// MIDDLEBOTH		if (pL&&pR) {			RMDBGLOG((MEMDBG,"RMFreeInZone: MIDDLEBOTH\n"));						pX->hash=disappearedHash;			pR->hash=disappearedHash;			pL->next=pR->next;			pL->size+=HeaderSkip(pZone->alignment)+pX->size				+HeaderSkip(pZone->alignment)+pR->size;						goto returnok;		}				// MIDDLELEFT		if (pL) {			RMDBGLOG((MEMDBG,"RMFreeInZone: MIDDLELEFT\n"));			pX->hash=disappearedHash;			pL->next=pCurrent->next;			pL->size+=HeaderSkip(pZone->alignment)+pX->size;						goto returnok;		}				// MIDDLERIGHT		if (pR) {			RMDBGLOG((MEMDBG,"RMFreeInZone: MIDDLERIGHT\n"));			// pPrevious cannot be NULL (treated by BEFOREFIRSTNEIGHBOR case).			pX->hash=freeBlockHash;			pR->hash=disappearedHash;			pCurrent->next=pX;			pX->next=pR->next;			pX->size+=HeaderSkip(pZone->alignment)+pR->size;						goto returnok;		}				// MIDDLENONE		if (pCurrent->next) 			if (AmIBefore(pCurrent,pX)&&AmIBefore(pX,pCurrent->next)) {				RMDBGLOG((MEMDBG,"RMFreeInZone: MIDDLENONE\n"));								pX->hash=freeBlockHash;								pX->next=pCurrent->next;				pCurrent->next=pX;								goto returnok;			}		pPrevious=pCurrent;		pCurrent=pCurrent->next;			//RMDBGLOG((MEMDBG,"(RMFreeInZone: hop to next free block)\n"));	}		// AFTERLAST	RMDBGLOG((MEMDBG,"RMFreeInZone: AFTERLAST\n"));		pX->hash=freeBlockHash;	// pPrevious->next cannot be NULL since there is at least one item in the free block list.	pPrevious->next=pX;	pX->next=(memoryBlockHeader *)NULL;	goto returnok;	 bad:	if (pZone->pCSops!=NULL) pZone->pCSops->Leave(pZone->cs);	RMDBGLOG((ENABLE,"RMFreeInZone: bad pointer %p\n",ptr));#ifdef USE_LEAK_CHECKER	RMPrintBackTrace ();	if (pZone->recordLeaks) {		RMRecordFreeLeakChecker (pZone->leakChecker, ptr);	}	#endif // USE_LEAK_CHECKER	RMPanic(RM_FATALINVALIDPOINTER); returnok:	pZone->successfulFrees++;	pZone->occupiedSize-=sizeOfX;#ifdef TRASH_MEM	trashMemory (ptr, sizeOfX);#endif	// this is extremely serious.	if (((pZone->successfulMallocs-pZone->successfulFrees)<0)||(pZone->occupiedSize<0)) {		if (pZone->pCSops!=NULL) pZone->pCSops->Leave(pZone->cs);#ifdef USE_LEAK_CHECKER		RMPrintBackTrace ();#endif		RMPanic(RM_FATALMEMORYCORRUPTED);	}#ifdef USE_LEAK_CHECKER	if (pZone->recordLeaks) {		RMRecordFreeLeakChecker (pZone->leakChecker, ptr);	}#endif		if (pZone->pCSops!=NULL) pZone->pCSops->Leave(pZone->cs);}void RMGetZoneStats(RMuint32 zid,		    RMuint32 *pSuccessfulMallocs,		    RMuint32 *pSuccessfulFrees,		    RMint32 *pOccupiedSize,		    RMint32 *pMaxSize){	RMmemoryZone *pZone=&zones[zid];	if (pSuccessfulMallocs!=NULL) *pSuccessfulMallocs=pZone->successfulMallocs;	if (pSuccessfulFrees!=NULL) *pSuccessfulFrees=pZone->successfulFrees;	if (pOccupiedSize!=NULL) *pOccupiedSize=pZone->occupiedSize;	if (pMaxSize!=NULL) *pMaxSize=pZone->maxSize;}void RMDumpMallocedBlocksInZone(RMuint32 zid){		RMmemoryZone *pZone=&zones[zid];	memoryBlockHeader *pX;	memoryBlockHeader *pCurrent;	// allow negative numbers to trap corruption	RMint32 computed_allocCount,computed_occupiedSize;	memoryBlockHeader **ppFirstFree;	computed_allocCount = 0;	computed_occupiedSize = 0;	ppFirstFree = (memoryBlockHeader **)(&(pZone->pFirstFree));	pX=(memoryBlockHeader *)(pZone->beginning);	pCurrent=*ppFirstFree;#ifdef USE_LEAK_CHECKER	RMPrintLeaksLeakChecker (pZone->leakChecker);#else // USE_LEAK_CHECKER	RMDBGLOG((MEMDBG,"RMDumpMallocedBlocksInZone: allocCount=%ld occupiedSize=%ld\n",		  (pZone->successfulMallocs-pZone->successfulFrees),		  pZone->occupiedSize));		/* DOUBLE LOOP. 	   pX goes thru candidates for occupied blocks (new pX is right neighbor of pX)	   pCurrent goes thru the linked list of free blocks as usual		   Focus attention on pX to understand the code.	   Let's start at the first possible pointer to an occupied block at the	   beginning of the zone 	*/	while ( pX != (memoryBlockHeader *)(pZone->beginning+pZone->totalSize) ) {		if (pX!=pCurrent) {			// this must be an occupied block.						// Let's check the hash.			if (Hash((RMuint32)DataAddress(pX,pZone->alignment),pX->size)!=pX->hash) goto bad;						RMDBGLOG((MEMDBG,"RMDumpMallocedBlocksInZone: occupied block #%3ld is (%p,%ld)\n",				  computed_allocCount,				  (void *)DataAddress(pX,pZone->alignment),				  pX->size));			computed_allocCount++;			computed_occupiedSize+=pX->size;		}		else {			RMDBGLOG((MEMDBG,"RMDumpMallocedBlocksInZone: skipping free block\n"));						// this is a free block.			pCurrent=pCurrent->next;			}				// compute right neighbor.		pX=(memoryBlockHeader *)(DataAddress(pX,pZone->alignment)+pX->size);	}		if (computed_allocCount!=(RMint32)(pZone->successfulMallocs-pZone->successfulFrees)) goto bad;	if (computed_occupiedSize!=pZone->occupiedSize) goto bad;	RMDBGLOG((MEMDBG,"RMDumpMallocedBlocksInZone: seems memory is not corrupted :-)\n"));	return; bad:	RMPanic(RM_FATALMEMORYCORRUPTED);#endif // USE_LEAK_CHECKER}void *RMMalloc(RMuint32 submittedSize){	return RMMallocInZone(DEFAULT_MEMORY_ZONE,submittedSize);}void *RMCalloc(RMuint32 nmemb,RMuint32 size){	return RMCallocInZone(DEFAULT_MEMORY_ZONE,nmemb,size);}void RMFree(void *ptr){	RMFreeInZone(DEFAULT_MEMORY_ZONE,ptr);}#ifdef USE_LEAK_CHECKERvoid RMStartLeakCheckingInZone(RMuint32 zid){	RMmemoryZone *pZone=&zones[zid];	pZone->recordLeaks = TRUE;}void RMEndLeakCheckingInZone(RMuint32 zid){	RMmemoryZone *pZone=&zones[zid];	pZone->recordLeaks = FALSE;}#endif //USE_LEAK_CHECKER

⌨️ 快捷键说明

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