static IMG_BOOL _AttemptAllocAligned(struct RA_ARENA *pArena, size_t uSize, struct BM_MAPPING **ppsMapping, u32 uFlags, u32 uAlignment, u32 *base) { u32 uIndex; PVR_ASSERT(pArena != NULL); if (pArena == NULL) { PVR_DPF(PVR_DBG_ERROR, "_AttemptAllocAligned: invalid parameter - pArena"); return IMG_FALSE; } uIndex = pvr_log2(uSize); while (uIndex < FREE_TABLE_LIMIT && pArena->aHeadFree[uIndex] == NULL) uIndex++; for (; uIndex < FREE_TABLE_LIMIT; uIndex++) { struct BT *pBT; pBT = pArena->aHeadFree[uIndex]; if (!pBT) continue; for (; pBT != NULL; pBT = pBT->pNextFree) { u32 aligned_base; if (uAlignment > 1) aligned_base = (pBT->base + uAlignment - 1) / uAlignment * uAlignment; 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) continue; if (pBT->psMapping && pBT->psMapping->ui32Flags != uFlags) { PVR_DPF(PVR_DBG_MESSAGE, "AttemptAllocAligned: mismatch in " "flags. Import has %x, request was %x", pBT->psMapping->ui32Flags, uFlags); continue; } if (alloc_from_bt(pArena, pBT, aligned_base, uSize, uFlags, ppsMapping, base) < 0) return IMG_FALSE; return IMG_TRUE; } } return IMG_FALSE; }
static void _FreeListRemove(struct RA_ARENA *pArena, struct BT *pBT) { u32 uIndex; uIndex = pvr_log2(pBT->uSize); if (pBT->pNextFree != NULL) pBT->pNextFree->pPrevFree = pBT->pPrevFree; if (pBT->pPrevFree == NULL) pArena->aHeadFree[uIndex] = pBT->pNextFree; else pBT->pPrevFree->pNextFree = pBT->pNextFree; }
static void _FreeListInsert(struct RA_ARENA *pArena, struct BT *pBT) { u32 uIndex; uIndex = pvr_log2(pBT->uSize); pBT->type = btt_free; pBT->pNextFree = pArena->aHeadFree[uIndex]; pBT->pPrevFree = NULL; if (pArena->aHeadFree[uIndex] != NULL) pArena->aHeadFree[uIndex]->pPrevFree = pBT; pArena->aHeadFree[uIndex] = pBT; }
static IMG_VOID _FreeListRemove (RA_ARENA *pArena, BT *pBT) { IMG_UINT32 uIndex; uIndex = pvr_log2 (pBT->uSize); if (pBT->pNextFree != IMG_NULL) pBT->pNextFree->pPrevFree = pBT->pPrevFree; if (pBT->pPrevFree == IMG_NULL) pArena->aHeadFree[uIndex] = pBT->pNextFree; else pBT->pPrevFree->pNextFree = pBT->pNextFree; }
static IMG_VOID _FreeListInsert (RA_ARENA *pArena, BT *pBT) { IMG_UINT32 uIndex; uIndex = pvr_log2 (pBT->uSize); pBT->type = btt_free; pBT->pNextFree = pArena->aHeadFree [uIndex]; pBT->pPrevFree = IMG_NULL; if (pArena->aHeadFree[uIndex] != IMG_NULL) pArena->aHeadFree[uIndex]->pPrevFree = pBT; pArena->aHeadFree [uIndex] = pBT; }
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; }