Exemple #1
0
static struct BT *_InsertResource(struct RA_ARENA *pArena, u32 base,
			   size_t uSize)
{
	struct BT *pBT;
	PVR_ASSERT(pArena != NULL);
	if (pArena == NULL) {
		PVR_DPF(PVR_DBG_ERROR,
			 "_InsertResource: invalid parameter - pArena");
		return NULL;
	}

	pBT = _BuildBT(base, uSize);
	if (pBT != NULL) {
		if (_SegmentListInsert(pArena, pBT) != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR,
			"_InsertResource: call to _SegmentListInsert failed");
			return NULL;
		}
		_FreeListInsert(pArena, pBT);
#ifdef RA_STATS
		pArena->sStatistics.uTotalResourceCount += uSize;
		pArena->sStatistics.uFreeResourceCount += uSize;
		pArena->sStatistics.uSpanCount++;
#endif
	}
	return pBT;
}
Exemple #2
0
static BT *
_InsertResource (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
{
	BT *pBT;
	PVR_ASSERT (pArena!=IMG_NULL);
	if (pArena == IMG_NULL)
	{
		PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: invalid parameter - pArena"));
		return IMG_NULL;
	}

	pBT = _BuildBT (base, uSize);
	if (pBT != IMG_NULL)
	{

#if defined(VALIDATE_ARENA_TEST)
		pBT->eResourceSpan = RESOURCE_SPAN_FREE;
		pBT->eResourceType = NON_IMPORTED_RESOURCE_TYPE;
#endif

		if (_SegmentListInsert (pArena, pBT) != PVRSRV_OK)
		{
			PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: call to _SegmentListInsert failed"));
			return IMG_NULL;
		}
		_FreeListInsert (pArena, pBT);
#ifdef RA_STATS
		pArena->sStatistics.uTotalResourceCount+=uSize;
		pArena->sStatistics.uFreeResourceCount+=uSize;
		pArena->sStatistics.uSpanCount++;
#endif
	}
	return pBT;
}
Exemple #3
0
static struct BT *_InsertResourceSpan(struct RA_ARENA *pArena, u32 base,
			       size_t uSize)
{
	enum PVRSRV_ERROR eError;
	struct BT *pSpanStart;
	struct BT *pSpanEnd;
	struct BT *pBT;

	PVR_ASSERT(pArena != NULL);
	if (pArena == NULL) {
		PVR_DPF(PVR_DBG_ERROR,
			 "_InsertResourceSpan: invalid parameter - pArena");
		return NULL;
	}

	PVR_DPF(PVR_DBG_MESSAGE,
		 "RA_InsertResourceSpan: arena='%s', base=0x%x, size=0x%x",
		 pArena->name, base, uSize);

	pSpanStart = _BuildSpanMarker(base, uSize);
	if (pSpanStart == NULL)
		goto fail_start;
	pSpanEnd = _BuildSpanMarker(base + uSize, 0);
	if (pSpanEnd == NULL)
		goto fail_end;

	pBT = _BuildBT(base, uSize);
	if (pBT == NULL)
		goto fail_bt;

	eError = _SegmentListInsert(pArena, pSpanStart);
	if (eError != PVRSRV_OK)
		goto fail_SegListInsert;

	eError = _SegmentListInsertAfter(pArena, pSpanStart, pBT);
	if (eError != PVRSRV_OK)
		goto fail_SegListInsert;

	_FreeListInsert(pArena, pBT);

	eError = _SegmentListInsertAfter(pArena, pBT, pSpanEnd);
	if (eError != PVRSRV_OK)
		goto fail_SegListInsert;

#ifdef RA_STATS
	pArena->sStatistics.uTotalResourceCount += uSize;
#endif
	return pBT;

fail_SegListInsert:
	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BT), pBT, NULL);
fail_bt:
	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BT), pSpanEnd, NULL);
fail_end:
	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BT), pSpanStart, NULL);
fail_start:
	return NULL;
}
Exemple #4
0
static int alloc_from_bt(struct RA_ARENA *arena, struct BT *bt, u32 start,
			 size_t size, u32 align,
			 struct BM_MAPPING **new_mapping, u32 *new_base)
{
	_FreeListRemove(arena, bt);
	PVR_ASSERT(bt->type == btt_free);
#ifdef RA_STATS
	arena->sStatistics.uLiveSegmentCount++;
	arena->sStatistics.uFreeSegmentCount--;
	arena->sStatistics.uFreeResourceCount -= bt->uSize;
#endif
	if (start > bt->base) {
		struct BT *next_bt;

		next_bt = _SegmentSplit(arena, bt, start - bt->base);

		if (!next_bt) {
			PVR_DPF(PVR_DBG_ERROR, "_AttemptAllocAligned: "
					"Front split failed");

			_FreeListInsert(arena, bt);
			return -1;
		}

		_FreeListInsert(arena, bt);
#ifdef RA_STATS
		arena->sStatistics.uFreeSegmentCount++;
		arena->sStatistics.uFreeResourceCount += bt->uSize;
#endif
		bt = next_bt;
	}

	if (bt->uSize > size) {
		struct BT *next_bt;
		next_bt = _SegmentSplit(arena, bt, size);

		if (!next_bt) {
			PVR_DPF(PVR_DBG_ERROR, "_AttemptAllocAligned: "
					"Back split failed");

			_FreeListInsert(arena, bt);
			return -1;
		}

		_FreeListInsert(arena, next_bt);
#ifdef RA_STATS
		arena->sStatistics.uFreeSegmentCount++;
		arena->sStatistics.uFreeResourceCount += next_bt->uSize;
#endif
	}

	bt->type = btt_live;

	if (!HASH_Insert(arena->pSegmentHash, bt->base, (u32)bt)) {
		_FreeBT(arena, bt, IMG_FALSE);
		return -1;
	}

	if (new_mapping)
		*new_mapping = bt->psMapping;

	*new_base = bt->base;

	return 0;
}
Exemple #5
0
static void _FreeBT(struct RA_ARENA *pArena, struct BT *pBT,
		    IMG_BOOL bFreeBackingStore)
{
	struct BT *pNeighbour;
	u32 uOrigBase;
	size_t uOrigSize;

	PVR_ASSERT(pArena != NULL);
	PVR_ASSERT(pBT != NULL);

	if ((pArena == NULL) || (pBT == NULL)) {
		PVR_DPF(PVR_DBG_ERROR, "_FreeBT: invalid parameter");
		return;
	}
#ifdef RA_STATS
	pArena->sStatistics.uLiveSegmentCount--;
	pArena->sStatistics.uFreeSegmentCount++;
	pArena->sStatistics.uFreeResourceCount += pBT->uSize;
#endif

	uOrigBase = pBT->base;
	uOrigSize = pBT->uSize;

	pNeighbour = pBT->pPrevSegment;
	if (pNeighbour != NULL && pNeighbour->type == btt_free &&
	    pNeighbour->base + pNeighbour->uSize == pBT->base) {
		_FreeListRemove(pArena, pNeighbour);
		_SegmentListRemove(pArena, pNeighbour);
		pBT->base = pNeighbour->base;
		pBT->uSize += pNeighbour->uSize;
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BT),
			  pNeighbour, NULL);
#ifdef RA_STATS
		pArena->sStatistics.uFreeSegmentCount--;
#endif
	}

	pNeighbour = pBT->pNextSegment;
	if (pNeighbour != NULL && pNeighbour->type == btt_free &&
	    pBT->base + pBT->uSize == pNeighbour->base) {
		_FreeListRemove(pArena, pNeighbour);
		_SegmentListRemove(pArena, pNeighbour);
		pBT->uSize += pNeighbour->uSize;
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BT),
			  pNeighbour, NULL);
#ifdef RA_STATS
		pArena->sStatistics.uFreeSegmentCount--;
#endif
	}

	if (pArena->pBackingStoreFree != NULL && bFreeBackingStore) {
		u32 uRoundedStart, uRoundedEnd;

		uRoundedStart = (uOrigBase / pArena->uQuantum) *
							pArena->uQuantum;

		if (uRoundedStart < pBT->base)
			uRoundedStart += pArena->uQuantum;

		uRoundedEnd = ((uOrigBase + uOrigSize + pArena->uQuantum -
		      1) / pArena->uQuantum) * pArena->uQuantum;

		if (uRoundedEnd > (pBT->base + pBT->uSize))
			uRoundedEnd -= pArena->uQuantum;

		if (uRoundedStart < uRoundedEnd)
			pArena->pBackingStoreFree(pArena->pImportHandle,
						  uRoundedStart, uRoundedEnd,
						  (void *) 0);
	}

	if (pBT->pNextSegment != NULL && pBT->pNextSegment->type == btt_span &&
	    pBT->pPrevSegment != NULL && pBT->pPrevSegment->type == btt_span) {
		struct BT *next = pBT->pNextSegment;
		struct BT *prev = pBT->pPrevSegment;
		_SegmentListRemove(pArena, next);
		_SegmentListRemove(pArena, prev);
		_SegmentListRemove(pArena, pBT);
		pArena->pImportFree(pArena->pImportHandle, pBT->base,
				    pBT->psMapping);
#ifdef RA_STATS
		pArena->sStatistics.uSpanCount--;
		pArena->sStatistics.uExportCount++;
		pArena->sStatistics.uFreeSegmentCount--;
		pArena->sStatistics.uFreeResourceCount -= pBT->uSize;
		pArena->sStatistics.uTotalResourceCount -= pBT->uSize;
#endif
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BT), next,
			  NULL);
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BT), prev,
			  NULL);
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BT), pBT,
			  NULL);
	} else
		_FreeListInsert(pArena, pBT);
}
Exemple #6
0
static IMG_BOOL
_AttemptAllocAligned (RA_ARENA *pArena,
					  IMG_SIZE_T uSize,
					  BM_MAPPING **ppsMapping,
					  IMG_UINT32 uFlags,
					  IMG_UINT32 uAlignment,
					  IMG_UINT32 uAlignmentOffset,
					  IMG_UINTPTR_T *base)
{
	IMG_UINT32 uIndex;
	PVR_ASSERT (pArena!=IMG_NULL);
	if (pArena == IMG_NULL)
	{
		PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: invalid parameter - pArena"));
		return IMG_FALSE;
	}

	if (uAlignment>1)
		uAlignmentOffset %= uAlignment;

	

	uIndex = pvr_log2 (uSize);

#if 0
	
	if (1u<<uIndex < uSize)
		uIndex++;
#endif

	while (uIndex < FREE_TABLE_LIMIT && pArena->aHeadFree[uIndex]==IMG_NULL)
		uIndex++;

	while (uIndex < FREE_TABLE_LIMIT)
	{
		if (pArena->aHeadFree[uIndex]!=IMG_NULL)
		{
			
			BT *pBT;

			pBT = pArena->aHeadFree [uIndex];
			while (pBT!=IMG_NULL)
			{
				IMG_UINTPTR_T aligned_base;

				if (uAlignment>1)
					aligned_base = (pBT->base + uAlignmentOffset + uAlignment - 1) / uAlignment * uAlignment - uAlignmentOffset;
				else
					aligned_base = pBT->base;
				PVR_DPF ((PVR_DBG_MESSAGE,
						  "RA_AttemptAllocAligned: pBT-base=0x%x "
						  "pBT-size=0x%x alignedbase=0x%x size=0x%x",
						pBT->base, pBT->uSize, aligned_base, uSize));

				if (pBT->base + pBT->uSize >= aligned_base + uSize)
				{
					if(!pBT->psMapping || pBT->psMapping->ui32Flags == uFlags)
					{
						_FreeListRemove (pArena, pBT);

						PVR_ASSERT (pBT->type == btt_free);

#ifdef RA_STATS
						pArena->sStatistics.uLiveSegmentCount++;
						pArena->sStatistics.uFreeSegmentCount--;
						pArena->sStatistics.uFreeResourceCount-=pBT->uSize;
#endif

						
						if (aligned_base > pBT->base)
						{
							BT *pNeighbour;
							pNeighbour = _SegmentSplit (pArena, pBT, (IMG_SIZE_T)(aligned_base - pBT->base));
							
							if (pNeighbour==IMG_NULL)
							{
								PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Front split failed"));
								
								_FreeListInsert (pArena, pBT);
								return IMG_FALSE;
							}

							_FreeListInsert (pArena, pBT);
	#ifdef RA_STATS
							pArena->sStatistics.uFreeSegmentCount++;
							pArena->sStatistics.uFreeResourceCount+=pBT->uSize;
	#endif
							pBT = pNeighbour;
						}

						
						if (pBT->uSize > uSize)
						{
							BT *pNeighbour;
							pNeighbour = _SegmentSplit (pArena, pBT, uSize);
							
							if (pNeighbour==IMG_NULL)
							{
								PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Back split failed"));
								
								_FreeListInsert (pArena, pBT);
								return IMG_FALSE;
							}

							_FreeListInsert (pArena, pNeighbour);
	#ifdef RA_STATS
							pArena->sStatistics.uFreeSegmentCount++;
							pArena->sStatistics.uFreeResourceCount+=pNeighbour->uSize;
	#endif
						}

						pBT->type = btt_live;

#if defined(VALIDATE_ARENA_TEST)
						if (pBT->eResourceType == IMPORTED_RESOURCE_TYPE)
						{
							pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_LIVE;
						}
						else if (pBT->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
						{
							pBT->eResourceSpan = RESOURCE_SPAN_LIVE;
						}
						else
						{
							PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned ERROR: pBT->eResourceType unrecognized"));
							PVR_DBG_BREAK;
						}
#endif
						if (!HASH_Insert (pArena->pSegmentHash, pBT->base, (IMG_UINTPTR_T) pBT))
						{
							_FreeBT (pArena, pBT, IMG_FALSE);
							return IMG_FALSE;
						}

						if (ppsMapping!=IMG_NULL)
							*ppsMapping = pBT->psMapping;

						*base = pBT->base;

						return IMG_TRUE;
					}
					else
					{
						PVR_DPF ((PVR_DBG_MESSAGE,
								"AttemptAllocAligned: mismatch in flags. Import has %x, request was %x", pBT->psMapping->ui32Flags, uFlags));

					}
				}
				pBT = pBT->pNextFree;
			}

		}
		uIndex++;
	}

	return IMG_FALSE;
}
Exemple #7
0
static BT *
_InsertResourceSpan (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
{
	PVRSRV_ERROR eError;
	BT *pSpanStart;
	BT *pSpanEnd;
	BT *pBT;

	PVR_ASSERT (pArena != IMG_NULL);
	if (pArena == IMG_NULL)
	{
		PVR_DPF ((PVR_DBG_ERROR,"_InsertResourceSpan: invalid parameter - pArena"));
		return IMG_NULL;
	}

	PVR_DPF ((PVR_DBG_MESSAGE,
			  "RA_InsertResourceSpan: arena='%s', base=0x%x, size=0x%x",
			  pArena->name, base, uSize));

	pSpanStart = _BuildSpanMarker (base, uSize);
	if (pSpanStart == IMG_NULL)
	{
		goto fail_start;
	}

#if defined(VALIDATE_ARENA_TEST)
	pSpanStart->eResourceSpan = IMPORTED_RESOURCE_SPAN_START;
	pSpanStart->eResourceType = IMPORTED_RESOURCE_TYPE;
#endif

	pSpanEnd = _BuildSpanMarker (base + uSize, 0);
	if (pSpanEnd == IMG_NULL)
	{
		goto fail_end;
	}

#if defined(VALIDATE_ARENA_TEST)
	pSpanEnd->eResourceSpan = IMPORTED_RESOURCE_SPAN_END;
	pSpanEnd->eResourceType = IMPORTED_RESOURCE_TYPE;
#endif

	pBT = _BuildBT (base, uSize);
	if (pBT == IMG_NULL)
	{
		goto fail_bt;
	}

#if defined(VALIDATE_ARENA_TEST)
	pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE;
	pBT->eResourceType = IMPORTED_RESOURCE_TYPE;
#endif

	eError = _SegmentListInsert (pArena, pSpanStart);
	if (eError != PVRSRV_OK)
	{
		goto fail_SegListInsert;
	}

	eError = _SegmentListInsertAfter (pArena, pSpanStart, pBT);
	if (eError != PVRSRV_OK)
	{
		goto fail_SegListInsert;
	}

	_FreeListInsert (pArena, pBT);

	eError = _SegmentListInsertAfter (pArena, pBT, pSpanEnd);
	if (eError != PVRSRV_OK)
	{
		goto fail_SegListInsert;
	}

#ifdef RA_STATS
	pArena->sStatistics.uTotalResourceCount+=uSize;
#endif
	return pBT;

  fail_SegListInsert:
	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
	
  fail_bt:
	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanEnd, IMG_NULL);
	
  fail_end:
	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanStart, IMG_NULL);
	
  fail_start:
	return IMG_NULL;
}