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

📄 ra.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    PVR_DPF ((PVR_DBG_MESSAGE, "RA_Finalise()"));

	PVR_ASSERT (pState!=IMG_NULL);

   	if (pState != IMG_NULL)
	{
		if (pState->pArenaPool!=IMG_NULL)
			POOL_Delete (pState->pArenaPool);
		if (pState->pBTPool!=IMG_NULL)
			POOL_Delete (pState->pBTPool);
		HostFreeMem (PVRSRV_HOST_PAGEABLE_HEAP, pState);
	}
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   RA_Create

	PURPOSE:    To create a resource arena.
	
	PARAMETERS:	In: pState - pointer to ra state created by RA_Initialise
	            In: name - the name of the arena for diagnostic purposes.
	            In: base - the base of an initial resource span or 0.
	            In: uSize - the size of an initial resource span or 0.
	            In: uQuantum - the arena allocation quantum.
	            In: alloc - a resource allocation callback or 0.
	            In: free - a resource de-allocation callback or 0.
	            In: pImportHandle - handle passed to alloc and free or 0.
	RETURNS:	arena handle, or IMG_NULL.
</function>
-----------------------------------------------------------------------------*/
RA_ARENA *
RA_Create (RA_STATE *pState,
		   IMG_CHAR *name,
		   IMG_UINTPTR_T base, 
		   IMG_SIZE_T uSize, 
		   IMG_SIZE_T uQuantum,
		   IMG_BOOL (*alloc)(IMG_VOID *, IMG_SIZE_T uSize, IMG_SIZE_T *pActualSize,
                             IMG_VOID **pRef, IMG_UINT32 _flags, IMG_UINTPTR_T *pBase),
		   IMG_VOID (*free) (IMG_VOID *, IMG_UINTPTR_T, IMG_VOID *pRef),
		   IMG_VOID *pImportHandle)
{
	RA_ARENA *pArena;
	int i;

	PVR_DPF ((PVR_DBG_MESSAGE,
              "RA_Create(name=%s, base=%x, uSize=%x, alloc=0x%x, free=0x%x)",
              name, base, uSize, alloc, free));

	PVR_ASSERT (pState!=IMG_NULL);
	pArena = POOL_Alloc (pState->pArenaPool);
	if (pArena==IMG_NULL) goto arena_fail;
	pArena->name = name;
	pArena->pImportAlloc = alloc!=IMG_NULL ? alloc : _RequestAllocFail;
	pArena->pImportFree = free;
	pArena->pImportHandle = pImportHandle;
	for (i=0; i<FREE_TABLE_LIMIT; i++)
		pArena->aHeadFree[i] = IMG_NULL;
	pArena->pHeadSegment = IMG_NULL;
	pArena->pTailSegment = IMG_NULL;
	pArena->uQuantum = uQuantum;
	pArena->pState = pState;

#ifdef RA_STATS
	pArena->sStatistics.uSpanCount = 0;
	pArena->sStatistics.uLiveSegmentCount = 0;
	pArena->sStatistics.uFreeSegmentCount = 0;
	pArena->sStatistics.uFreeResourceCount = 0;
	pArena->sStatistics.uTotalResourceCount = 0;
	pArena->sStatistics.uCumulativeAllocs = 0;
	pArena->sStatistics.uCumulativeFrees = 0;
	pArena->sStatistics.uImportCount = 0;
	pArena->sStatistics.uExportCount = 0;
#endif
  
	pArena->pSegmentHash = HASH_Create (pState->pHashState, MINIMUM_HASH_SIZE);
	if (pArena->pSegmentHash==IMG_NULL) goto hash_fail;
	if (uSize>0)
    {
		uSize = (uSize + uQuantum - 1) / uQuantum * uQuantum;
		if (!_InsertResource (pArena, base, uSize)) goto insert_fail;
    }
	return pArena;

  insert_fail:
	HASH_Delete (pArena->pSegmentHash);
  hash_fail:
	POOL_Free (pState->pArenaPool, pArena);
  arena_fail:
	return IMG_NULL;
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   RA_Delete

	PURPOSE:    To delete a resource arena. All resources allocated from
 	            the arena must be freed before deleting the arena.
	                	
	PARAMETERS:	In: pArena - the arena to delete.
	RETURNS:	None
</function>
-----------------------------------------------------------------------------*/
void
RA_Delete (RA_ARENA *pArena)
{
	if (pArena!=IMG_NULL)
    {
		IMG_UINT32 uIndex;

		PVR_DPF ((PVR_DBG_MESSAGE,
                  "RA_Delete: name=%s", pArena->name));

		PVR_ASSERT (pArena->pState!=IMG_NULL);
		for (uIndex=0; uIndex<FREE_TABLE_LIMIT; uIndex++)
			pArena->aHeadFree[uIndex] = IMG_NULL;

		while (pArena->pHeadSegment != IMG_NULL)
		{
			BT *pBT = pArena->pHeadSegment;
			PVR_ASSERT (pBT->type == btt_free);
			_SegmentListRemove (pArena, pBT);
			POOL_Free (pArena->pState->pBTPool, pBT);
#ifdef RA_STATS
			pArena->sStatistics.uSpanCount--;
#endif
		}
		HASH_Delete (pArena->pSegmentHash);
		POOL_Free (pArena->pState->pArenaPool, pArena);
    }
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   RA_Add

	PURPOSE:    To add a resource span to an arena. The span must not
 	            overlapp with any span previously added to the arena.
	
	PARAMETERS:	In: pArena - the arena to add a span into.
	            In: base - the base of the span.
	            In: uSize - the extent of the span.
	RETURNS:	IMG_TRUE - Success
                IMG_FALSE - failure
</function>
-----------------------------------------------------------------------------*/
IMG_BOOL
RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
{
	PVR_ASSERT (pArena != IMG_NULL);

	PVR_DPF ((PVR_DBG_MESSAGE,
              "RA_Add: name=%s, base=%x, size=%x", pArena->name, base, uSize));

	uSize = (uSize + pArena->uQuantum - 1) / pArena->uQuantum * pArena->uQuantum;
	return _InsertResource (pArena, base, uSize);
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   RA_Alloc

	PURPOSE:    To allocate resource from an arena.
	
	PARAMETERS:	In:  pArena - the arena
	            In:  uRequestSize - the size of resource segment requested.
	            Out: pActualSize - the actual size of resource segment
	                 allocated, typcially rounded up by quantum.
	            Out: pRef - the user reference associated with allocated resource span.
	            In:  uFlags - flags influencing allocation policy.
	            In:  uAlignment - the uAlignment constraint required for the
	                 allocated segment, use 0 if uAlignment not required.
	            In:  uAlignmentOffset
	            Out: base - allocated base resource
	RETURNS:	IMG_TRUE - success
	            IMG_FALSE - failure
</function>
-----------------------------------------------------------------------------*/
IMG_BOOL
RA_Alloc (RA_ARENA *pArena,
          IMG_SIZE_T uRequestSize,
          IMG_SIZE_T *pActualSize,
		  void **pRef,
          IMG_UINT32 uFlags,
          IMG_UINT32 uAlignment,
          IMG_UINT32 uAlignmentOffset,
          IMG_UINTPTR_T *base)
{
	IMG_BOOL bResult = IMG_FALSE;
	IMG_SIZE_T uSize = uRequestSize;

	PVR_ASSERT (pArena!=IMG_NULL);

	uSize = ((uSize + pArena->uQuantum - 1)/pArena->uQuantum)*pArena->uQuantum;
	if (pActualSize != IMG_NULL)
		*pActualSize = uSize;

	PVR_DPF ((PVR_DBG_MESSAGE,
              "RA_Alloc (arena='%s', size=0x%lx(0x%lx), uAlignment=0x%x, uAlignmentOffset=0x%x)...", 
		   pArena->name, uSize, uRequestSize, uAlignment, uAlignmentOffset));

	/* if allocation failed then we might have an import source which
	   can provide more resource, else we will have to fail the
	   allocation to the caller. */
	bResult = _AttemptAllocAligned (pArena, uSize, pRef, uFlags,
                                    uAlignment, uAlignmentOffset, base);
	if (!bResult)
    {
		void *pImportRef;
		IMG_UINTPTR_T import_base;
		IMG_SIZE_T uImportSize = uSize;

		/* ensure that we allocate sufficient space to meet the uAlignment
		   constraint */
		if (uAlignment>0)
			uImportSize += uAlignment;
		
		bResult = 
			pArena->pImportAlloc (pArena->pImportHandle, uImportSize, &uImportSize,
								 &pImportRef, uFlags, &import_base);
		if (bResult)
		{
			BT *pBT;
			pBT = _InsertResourceSpan (pArena, import_base, uImportSize);
			/* successfully import more resource, create a span to
			   represent it and retry the allocation attempt */
			if (pBT == IMG_NULL)
			{
				/* insufficient resources to insert the newly acquired span,
				   so free it back again */
				pArena->pImportFree (pArena->pImportHandle, import_base,
                                     pImportRef);
				PVR_DPF ((PVR_DBG_MESSAGE,
                          "...RA_Alloc (name='%s', size=0x%x) failed", 
                          pArena->name, uSize));
				/* RA_Dump (arena); */
				return IMG_FALSE;
			}
			pBT->pRef = pImportRef;
#ifdef RA_STATS
			pArena->sStatistics.uFreeSegmentCount++;
			pArena->sStatistics.uFreeResourceCount += uImportSize;
			pArena->sStatistics.uImportCount++;
			pArena->sStatistics.uSpanCount++;
#endif
			bResult = _AttemptAllocAligned (pArena, uSize, pRef, uFlags,
                                            uAlignment, uAlignmentOffset,
                                            base);
			if (!bResult)
			{
				PVR_DPF ((PVR_DBG_MESSAGE,
                          "...RA_Alloc(name='%s') failed (uAlignment)",
                          pArena->name));
			}
		}
    }
#ifdef RA_STATS
	if (bResult)
		pArena->sStatistics.uCumulativeAllocs++;
#endif    

	PVR_DPF ((PVR_DBG_MESSAGE,
              "  RA_Alloc (name=%s, size=0x%lx, *base=0x%lx) = %d",
            pArena->name, uSize, *base, bResult));
  
	/*  RA_Dump (pArena);
		ra_stats (pArena);
	*/

	return bResult;
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   RA_Free

	PURPOSE:    To free a resource segment.
	
	PARAMETERS:	In:  pArena - the arena the segment was originally allocated from.
	            In:  base - the base of the resource span to free.
	            In:  pRef - TODO check why we still need this.
	            
	RETURNS:	None
</function>
-----------------------------------------------------------------------------*/
void 
RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, void *pRef)
{
	BT *pBT;
	
	PVR_ASSERT (pArena != IMG_NULL);
	UNREFERENCED_PARAMETER (pRef);
	
	PVR_DPF ((PVR_DBG_MESSAGE,
              "RA_Free: name=%s base=0x%lx", pArena->name, base));
	
	pBT = (BT *) HASH_Remove (pArena->pSegmentHash, base);
	PVR_ASSERT (pBT != IMG_NULL);

	if (pBT)
	{
		PVR_ASSERT (pBT->base == base);

	#ifdef RA_STATS
		pArena->sStatistics.uCumulativeFrees++;
	#endif
	
		_FreeBT (pArena, pBT);
	}
}

#ifdef RA_STATS
/*----------------------------------------------------------------------------
<function>
	FUNCTION:   RA_Statistics

	PURPOSE:    To query an arena's statistics.
	
	PARAMETERS:	In:  pArena - the arena.
	            Out: ppStats - receives a pointer to the arena statistics.
	RETURNS:	None
</function>
-----------------------------------------------------------------------------*/
void 
RA_Statistics (RA_ARENA *pArena, RA_STATISTICS **ppStats)
{
	PVR_ASSERT (pArena != IMG_NULL);
	PVR_ASSERT (ppStats != IMG_NULL);
	*ppStats = &(pArena->sStatistics);
}
#endif

#ifdef NEVER

static char *
_BTType (enum _BTType eType)
{
	switch (eType)
    { 
    case btt_span: return "span";
    case btt_free: return "free";
    case btt_live: return "live";
    }
	return "junk";
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   RA_Dump

	PURPOSE:    To dump a readable description of an arena. Diagnostic only.
	
	PARAMETERS:	In:  pArena - the arena to dump.
	            
	RETURNS:	None
</function>
-----------------------------------------------------------------------------*/
void
RA_Dump (RA_ARENA *pArena)
{
	BT *pBT;
	PVR_ASSERT (pArena != IMG_NULL);
	PVR_DPF ((PVR_DBG_MESSAGE,"Arena %s", pArena->name));
	PVR_DPF ((PVR_DBG_MESSAGE,"  alloc=%p free=%p handle=%p quantum=%d", 
			 pArena->pImportAlloc, pArena->pImportFree, pArena->pImportHandle,
			 pArena->uQuantum));
	PVR_DPF ((PVR_DBG_MESSAGE,"  segment Chain:"));
	if (pArena->pHeadSegment != IMG_NULL &&
        pArena->pHeadSegment->pPrevSegment != IMG_NULL)
		PVR_DPF ((PVR_DBG_MESSAGE,"  error: head boundary tag has invalid pPrevSegment"));
	if (pArena->pTailSegment != IMG_NULL &&
        pArena->pTailSegment->pNextSegment != IMG_NULL)
		PVR_DPF ((PVR_DBG_MESSAGE,"  error: tail boundary tag has invalid pNextSegment"));
    
	for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
    {
		PVR_DPF ((PVR_DBG_MESSAGE,"\tbase=0x%lx size=%ld type=%s  ref=%p", 
				 (unsigned long) pBT->base, pBT->uSize, _BTType (pBT->type),
				 pBT->pRef));
    }

#ifdef HASH_TRACE
	HASH_Dump (pArena->pSegmentHash);
#endif
}
#endif

#if NEVER
/*----------------------------------------------------------------------------
<function>
	FUNCTION:   RA_Stats

	PURPOSE:    To dump the statistics associated with an arena.
	
	PARAMETERS:	In:  pArena - the arena to print statistics for.
	            
	RETURNS:	None
</function>
-----------------------------------------------------------------------------*/
void
RA_Stats (RA_ARENA *pArena)
{
	PVR_ASSERT (pArena!=IMG_NULL);
	PVR_DPF ((PVR_DBG_MESSAGE,"Arena %s",
			 pArena->name));
	PVR_DPF ((PVR_DBG_MESSAGE,"\tspan count = %d",
			 pArena->sStatistics.uSpanCount));
	PVR_DPF ((PVR_DBG_MESSAGE,"\tlive segment count = %d",
			 pArena->sStatistics.uLiveSegmentCount));
	PVR_DPF ((PVR_DBG_MESSAGE,"\tfree segment count = %d",
			 pArena->sStatistics.uFreeSegmentCount));
	PVR_DPF ((PVR_DBG_MESSAGE,"\tfree resource count = %d",
			 pArena->sStatistics.uFreeResourceCount));
	PVR_DPF ((PVR_DBG_MESSAGE,"\ttotal allocs = %d",
			 pArena->sStatistics.uCumulativeAllocs));
	PVR_DPF ((PVR_DBG_MESSAGE,"\ttotal frees = %d",
			 pArena->sStatistics.uCumulativeFrees));
	PVR_DPF ((PVR_DBG_MESSAGE,"\timport count = %d",
			 pArena->sStatistics.uImportCount));
	PVR_DPF ((PVR_DBG_MESSAGE,"\texport count = %d",
			 pArena->sStatistics.uExportCount));
	PVR_DPF ((PVR_DBG_MESSAGE,""));
}
#endif

⌨️ 快捷键说明

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