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

📄 heapman.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/**************************************************************************
 * Function Name  : HeapRemoveBlockToFreeList
 * Inputs         : psHostHeap - ptr to host heap this block belongs to
 *					psBlock - block to be removed to free list
 * Outputs        : None
 * Returns        : None
 * Globals Used   : None
 * Description    : Remove the block from the free list
 **************************************************************************/
__inline IMG_VOID HeapRemoveBlockToFreeList(HOST_HEAP *psHostHeap, PGLOB_HEAP psBlock)
{
	/* Remove block from free list */
	if (psBlock->psNextFree != NULL)
	{
		psBlock->psNextFree->psPrevFree=psBlock->psPrevFree;
	}
	if (psBlock->psPrevFree != NULL)
	{
		psBlock->psPrevFree->psNextFree=psBlock->psNextFree;
	}
	else
	{
		psHostHeap->psFreeHeapStart=psBlock->psNextFree;
	}
	psBlock->psNextFree=(PGLOB_HEAP)NULL;
	psBlock->psPrevFree=(PGLOB_HEAP)NULL;
}



/**************************************************************************
 * Function Name  : AddBlockAllocCallback
 * Inputs         : pfnFunc - ptr to callback function
 * Outputs        : None
 * Returns        : TRUE if installed ok, else FALSE
 * Globals Used   : None
 * Description    : Installs host heap block alloc callback
 **************************************************************************/
IMG_BOOL AddBlockAllocCallback(PFN_HEAPBLOCK_CALLBACK pfnFunc)
{
	IMG_UINT32	ui32Idx;

	for (ui32Idx=0; ui32Idx<MAX_ALLOC_CALLBACKS; ui32Idx++)
	{
		/* Only allow one instance of a callback routine */
		if (sfnBlockAllocCallbacks[ui32Idx] == pfnFunc)
		{
			return FALSE;
		}

		/* Check if free */
		if (sfnBlockAllocCallbacks[ui32Idx] == NULL)
		{
			sfnBlockAllocCallbacks[ui32Idx]=pfnFunc;
			return TRUE;
		}
	}

	return FALSE;
}



/**************************************************************************
 * Function Name  : RemoveBlockAllocCallback
 * Inputs         : pfnFunc - ptr to callback function
 * Outputs        : None
 * Returns        : TRUE if installed ok, else FALSE
 * Globals Used   : None
 * Description    : Removes host heap block alloc callback
 **************************************************************************/
IMG_VOID RemoveBlockAllocCallback(PFN_HEAPBLOCK_CALLBACK pfnFunc)
{
	IMG_UINT32	ui32Idx;

	for (ui32Idx=0; ui32Idx<MAX_ALLOC_CALLBACKS; ui32Idx++)
	{
		if (sfnBlockAllocCallbacks[ui32Idx] == pfnFunc)
		{
			sfnBlockAllocCallbacks[ui32Idx]=(PFN_HEAPBLOCK_CALLBACK)NULL;
			return;
		}
	}

	return;
}



/**************************************************************************
 * Function Name  : DoBlockCallbacksForHeap
 * Inputs         : psHeap - heap to process
 * Outputs        : None
 * Returns        : None
 * Globals Used   : None
 * Description    : Walks the heap and processes the host heap block callbacks
 *					for each block
 **************************************************************************/
IMG_VOID DoBlockCallbacksForHeap(PHOST_HEAP psHeap)
{
	PGLOB_HEAP	psCurHeapBlock;
	PGLOB_HEAP	psStartHeapBlock;	
	IMG_UINT32		ui32AccumBlockSize=0;

#ifdef DEBUG
	CheckSingleHeap(psHeap, FALSE);
#endif

	/*Start at begining of the heap*/
	psCurHeapBlock = psHeap->psHeapStart;
	psStartHeapBlock = psCurHeapBlock;
	
	/* Check each block */
	while (psCurHeapBlock != NULL)
	{
		/*Add size of this block to running total*/
		ui32AccumBlockSize+=psCurHeapBlock->ui32BlockSize;

		/* 	
			If this is end of this continuous linear address region of blocks
			then process the callbacks for it!!!
		*/
		if (psCurHeapBlock->psNext == NULL || (psCurHeapBlock->psNext->ui32Flags & GHEAP_BLOCK_HEAD) == GHEAP_BLOCK_HEAD)
		{
			ProcessAllocCallbacks(TRUE, psStartHeapBlock, ui32AccumBlockSize);
			ui32AccumBlockSize=0;
			psStartHeapBlock = psCurHeapBlock->psNext;
		}

		/*Move to next block*/
		psCurHeapBlock = psCurHeapBlock->psNext;		
	}
			   
	return;
}



/**************************************************************************
 * Function Name  : DoBlockCallbacksForHeap
 * Inputs         : psHeap - heap to process
 * Outputs        : None
 * Returns        : None
 * Globals Used   : None
 * Description    : Walks the heap and processes the host heap block callbacks
 *					for each block
 **************************************************************************/
IMG_VOID ProcessAllocCallbacks(IMG_BOOL bAlloc, IMG_PVOID pvAddr, IMG_UINT32 ui32Size)
{
	IMG_UINT32	ui32Idx;

	for (ui32Idx=0; ui32Idx<MAX_ALLOC_CALLBACKS; ui32Idx++)
	{
		if (sfnBlockAllocCallbacks[ui32Idx] != NULL)
		{
			////don't need ExitKM((PPVRSRV_DEV_INFO)NULL);
			(sfnBlockAllocCallbacks[ui32Idx])(bAlloc, pvAddr, ui32Size);
			////don't need EnterKM((PPVRSRV_DEV_INFO)NULL);
		}
	}

	return;
}

/**************************************************************************
 * Function Name  : CheckHeapFreeBlock
 * Inputs         : pvStart - pointer to start of free block of memory to check
 *					ui32Size - size of block in bytes	
 * Outputs        : None
 * Returns        : Zero if memory has not been corrupted else the addr of the
 *					memory that has been corrupted.
 * Globals Used   : None
 * Description    : Check the given free block of memory has been corrupted
 *					This is done by checking that evey byte of the buffer is
 *					0xe2
 **************************************************************************/
IMG_UINT32 CheckHeapFreeBlock(IMG_PVOID pvStart, IMG_UINT32 ui32Size)
{
	IMG_UINT32	ui32Ret;
	IMG_UINT32	ui32DWORDCo=ui32Size/4;
	IMG_UINT32	ui32Count;
	IMG_UINT32	*pui32Temp;

	if (ui32Size == 0)
	{
		return 0;
	}

	pui32Temp = (IMG_UINT32 *)pvStart;
	
	for (ui32Count = 0; ui32Count < ui32DWORDCo; ui32Count++)
	{
		if ( pui32Temp[ui32Count] != (DBG_MEMORY_DEALLOC_INITIALIZER + (DBG_MEMORY_DEALLOC_INITIALIZER << 8) + (DBG_MEMORY_DEALLOC_INITIALIZER << 16) + (DBG_MEMORY_DEALLOC_INITIALIZER << 24)) )
		{
			ui32Ret = ((IMG_UINT32)pvStart) + ui32Count;
			break;
		}
	}

	return ui32Ret;
}

#define READ_GLOB_HEAP(addr, ptr, strct) ptr=(PGLOB_HEAP)addr;
#define READ_HOST_HEAP(addr, ptr, strct) ptr=(PHOST_HEAP)addr;
#define READ_DWORD(addr, var) var=*(PDWORD)addr;

/**************************************************************************
 * Function Name  : FindBlockAllocSize
 * Inputs         : psBlock - ptr to block
 * Outputs        : None
 * Returns        : Num bytes alloced by caller
 * Globals Used   : None
 * Description    : 
 **************************************************************************/
IMG_UINT32 FindBlockAllocSize(PGLOB_HEAP psBlock)
{
	PDWORD	pui32Ptr;
	IMG_UINT32	ui32Val;
	PDWORD	pui32EndOfBlock;
	IMG_UINT32	ui32BlockSize;

	READ_DWORD(&psBlock->ui32BlockSize, ui32BlockSize);
	pui32EndOfBlock=(PDWORD)((IMG_UINT32)psBlock + ui32BlockSize);

	/* Start at end of header */
	pui32Ptr=(PDWORD)(psBlock+1);

	/* Check for the link ptr */
	while (pui32Ptr < pui32EndOfBlock)
	{
		READ_DWORD(pui32Ptr, ui32Val);
		if (ui32Val == (IMG_UINT32)psBlock)
		{
			return ui32BlockSize - ((IMG_UINT32)pui32Ptr - (IMG_UINT32)psBlock) - 4;
		}
		pui32Ptr++;
	}

	return 0;
}


/**************************************************************************
 * Function Name  : CheckSingleHeap
 * Inputs         : psHeap - pointer to heap to test
 * Outputs        : None
 * Returns        : None
 * Globals Used   : sGlbDbgAllocs
 * Description    : Walks through given heap checking for corruptions
 **************************************************************************/
IMG_VOID CheckSingleHeap(HOST_HEAP *psHeap, IMG_BOOL bPrintHeap)
{
	PGLOB_HEAP	psCurHeapBlock;
	IMG_PVOID		pvCurHeapBlock;
	GLOB_HEAP	sCurHeapBlock={0};
	IMG_PVOID		pvPrevHeapBlock=NULL;
	PGLOB_HEAP	psNextHeapBlock=(PGLOB_HEAP)NULL;
	GLOB_HEAP	sNextHeapBlock={0};
	IMG_UINT32		ui32AccumBlockSize=0;
	IMG_UINT32		ui32TotalBlocks=0;
	IMG_UINT32		ui32FreeBlocks=0;
	IMG_UINT32		ui32FreeHeapBlkCo=0;	
	HOST_HEAP	sHeap={0};
	IMG_PVOID		pvHeap=psHeap;

	if (ui32HeapCheckLevel == HOST_HEAP_DBGCHK_NONE && bPrintHeap == FALSE)
	{
		return;
	}

	/* Read heap structure */
	READ_HOST_HEAP(psHeap, psHeap, sHeap);

	if (bPrintHeap)
	{
		PVR_DPF((PVR_DBG_MESSAGE, "ChkHostHeap : Heap 0x%lx", pvHeap));
		DPF_NEWLINE;
		PVR_DPF((PVR_DBG_MESSAGE, "ChkHostHeap : Total allocs in heap %ld", psHeap->ui32AllocsInHeap));
		DPF_NEWLINE;
		PVR_DPF((PVR_DBG_MESSAGE, "ChkHostHeap : Total pages in heap %ld", psHeap->ui32CurHeapSizeInPages));
		DPF_NEWLINE;
		PVR_DPF((PVR_DBG_MESSAGE, "ChkHostHeap : Heap page alloc fn 0x%lx", psHeap->pfnHostAllocPage));
		DPF_NEWLINE;
		PVR_DPF((PVR_DBG_MESSAGE, "ChkHostHeap : Heap page free fn 0x%lx\n\n", psHeap->pfnHostFreePage));
		DPF_NEWLINE;
	}

	/*Start at begining of the heap*/
	pvCurHeapBlock = psHeap->psHeapStart;
	READ_GLOB_HEAP(pvCurHeapBlock, psCurHeapBlock, sCurHeapBlock);
	
	/*Check each block*/
	while( pvCurHeapBlock != NULL )
	{
		/*Add size of this block to running total*/
		ui32AccumBlockSize+=psCurHeapBlock->ui32BlockSize;
		ui32TotalBlocks++;

		/*Check signiture*/
		PVR_ASSERT(psCurHeapBlock->ui32Signiture == HOST_HEAP_SIGNITURE);
			
		/*Check flags*/
		PVR_ASSERT((psCurHeapBlock->ui32Flags & ~(GHEAP_BLOCK_ALLOCATED | GHEAP_BLOCK_HEAD)) == 0);

		/* Check block points to last block */
		PVR_ASSERT(psCurHeapBlock->psPrev == (PGLOB_HEAP)pvPrevHeapBlock);

		/* Check blocks points back to the heap */
		PVR_ASSERT(psCurHeapBlock->psHeap == pvHeap);

		if (psCurHeapBlock->ui32Flags & GHEAP_BLOCK_ALLOCATED)
		{
			PVR_ASSERT(psCurHeapBlock->psPrevFree == NULL);
			PVR_ASSERT(psCurHeapBlock->psNextFree == NULL);
		}
		else
		{
			ui32FreeBlocks++;
		}

		/*If next block is in same allocation then check the block size*/
		if (psCurHeapBlock->psNext != NULL)
		{
			READ_GLOB_HEAP(psCurHeapBlock->psNext, psNextHeapBlock, sNextHeapBlock);
			if ((psNextHeapBlock->ui32Flags & GHEAP_BLOCK_HEAD) != GHEAP_BLOCK_HEAD)
			{
				PVR_ASSERT(psCurHeapBlock->psNext == (PGLOB_HEAP)((BYTE *)pvCurHeapBlock + psCurHeapBlock->ui32BlockSize));
			}
		}

		/*If this is end of this continuous linear address region of blocks
		then check there combined size*/
		if (psCurHeapBlock->psNext == NULL || (psNextHeapBlock->ui32Flags & GHEAP_BLOCK_HEAD) == GHEAP_BLOCK_HEAD)
		{
			PVR_ASSERT(ui32AccumBlockSize == (psHeap->ui32ExpandSizeInPages * HOST_PAGESIZE()));
			ui32AccumBlockSize=0;
		}

		if (bPrintHeap)
		{
			if ((psCurHeapBlock->ui32Flags & GHEAP_BLOCK_HEAD) == GHEAP_BLOCK_HEAD)
			{
				PVR_DPF((PVR_DBG_MESSAGE, "ChkHostHeap : New Block"));
				DPF_NEWLINE;
			}

			if (psCurHeapBlock->ui32Flags & GHEAP_BLOCK_ALLOCATED)
			{
				IMG_UINT32	ui32AllocSize=FindBlockAllocSize((PGLOB_HEAP)pvCurHeapBlock);

				#ifdef DEBUG
				PVR_DPF((PVR_DBG_MESSAGE, "0x%lx - 0x%lx : Alloced 0x%lx (0x%lx) (%ldKb) Owner 0x%lx", pvCurHeapBlock, (IMG_UINT32)pvCurHeapBlock + psCurHeapBlock->ui32BlockSize, ui32AllocSize, psCurHeapBlock->ui32BlockSize, ui32AllocSize/1024, psCurHeapBlock->pfnOwner));
				#else
				PVR_DPF((PVR_DBG_MESSAGE, "0x%lx - 0x%lx : Alloced 0x%lx (0x%lx) (%ldKb)", pvCurHeapBlock, (IMG_UINT32)pvCurHeapBlock + psCurHeapBlock->ui32BlockSize, ui32AllocSize, psCurHeapBlock->ui32BlockSize, ui32AllocSize/1024));
				#endif
				DPF_NEWLINE;
			}
			else
			{
				PVR_DPF((PVR_DBG_MESSAGE, "0x%lx - 0x%lx : Free 0x%lx (%ldKb)", pvCurHeapBlock, (IMG_UINT32)pvCurHeapBlock + psCurHeapBlock->ui32BlockSize, psCurHeapBlock->ui32BlockSize, psCurHeapBlock->ui32BlockSize/1024));
				DPF_NEWLINE;
			}
		}

		/*Move to next block*/
		pvPrevHeapBlock=pvCurHeapBlock;
		pvCurHeapBlock = psCurHeapBlock->psNext;
		READ_GLOB_HEAP(pvCurHeapBlock, psCurHeapBlock, sCurHeapBlock);
	}
			   
	PVR_ASSERT(psHeap->ui32AllocsInHeap == ui32TotalBlocks - ui32FreeBlocks);
	if (bPrintHeap)
	{
		PVR_DPF((PVR_DBG_MESSAGE, "Total num blocks %ld", ui32TotalBlocks));
		DPF_NEWLINE;
		PVR_DPF((PVR_DBG_MESSAGE, "Total num alloced blocks %ld", psHeap->ui32AllocsInHeap));
		DPF_NEWLINE;
		PVR_DPF((PVR_DBG_MESSAGE, "Total num free blocks %ld", ui32FreeBlocks));
		DPF_NEWLINE;
	}

	/* Now check the free list */
	pvCurHeapBlock = psHeap->psFreeHeapStart;
	READ_GLOB_HEAP(pvCurHeapBlock, psCurHeapBlock, sCurHeapBlock);
	pvPrevHeapBlock=(PGLOB_HEAP)NULL;
	if (ui32HeapCheckLevel >= HOST_HEAP_DBGCHK_FREEHEAP)
	{
		while(pvCurHeapBlock != NULL)
		{
			IMG_UINT32	ui32Addr=0;

			/* Count number of blocks */
			ui32FreeHeapBlkCo++;

			/* Check block points to last block */
			PVR_ASSERT(psCurHeapBlock->psPrevFree == pvPrevHeapBlock);

			if (ui32HeapCheckLevel >= HOST_HEAP_DBGCHK_CORRUPTION)
			{				
				/* Check free space has not been corrupted */
				#if defined(DEBUG)
				if ((psCurHeapBlock->ui32Flags & GHEAP_BLOCK_HEAD) == 0)
				{
					PVR_ASSERT((ui32Addr=CheckHeapFreeBlock((IMG_PVOID)(psCurHeapBlock+1), psCurHeapBlock->ui32BlockSize-sizeof(GLOB_HEAP))) == 0);
				}
				else
				{
					PVR_ASSERT((ui32Addr=CheckHeapFreeBlock((IMG_PVOID)(((PGLOB_HEAP_HEAD)psCurHeapBlock)+1), psCurHeapBlock->ui32BlockSize-sizeof(GLOB_HEAP_HEAD))) == 0);
				}
				#endif
			}

			/*Move to next block*/
			pvPrevHeapBlock=pvCurHeapBlock;
			pvCurHeapBlock = psCurHeapBlock->psNextFree;
			READ_GLOB_HEAP(pvCurHeapBlock, psCurHeapBlock, sCurHeapBlock);
		}

		PVR_ASSERT(ui32FreeHeapBlkCo == ui32FreeBlocks); 
	}

	/* Call the heap specific checking function if given */
	if (psHeap->pfnDedicatedHeapCheck != NULL)
	{
		psHeap->pfnDedicatedHeapCheck(psHeap);
	}

	return;
}


/*****************************************************************************
 End of file (heapman.c)
*****************************************************************************/

⌨️ 快捷键说明

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