void RA_Free(struct RA_ARENA *pArena, u32 base, IMG_BOOL bFreeBackingStore) { struct BT *pBT; PVR_ASSERT(pArena != NULL); if (pArena == NULL) { PVR_DPF(PVR_DBG_ERROR, "RA_Free: invalid parameter - pArena"); return; } PVR_DPF(PVR_DBG_MESSAGE, "RA_Free: name='%s', base=0x%x", pArena->name, base); pBT = (struct BT *)HASH_Remove(pArena->pSegmentHash, base); PVR_ASSERT(pBT != NULL); if (pBT) { PVR_ASSERT(pBT->base == base); #ifdef RA_STATS pArena->sStatistics.uCumulativeFrees++; #endif _FreeBT(pArena, pBT, bFreeBackingStore); } }
IMG_VOID RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore) { BT *pBT; PVR_ASSERT (pArena != IMG_NULL); if (pArena == IMG_NULL) { PVR_DPF ((PVR_DBG_ERROR,"RA_Free: invalid parameter - pArena")); return; } #ifdef USE_BM_FREESPACE_CHECK CheckBMFreespace(); #endif PVR_DPF ((PVR_DBG_MESSAGE, "RA_Free: name='%s', base=0x%x", 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 #ifdef USE_BM_FREESPACE_CHECK { IMG_BYTE* p; IMG_BYTE* endp; p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(); endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize)); while ((IMG_UINT32)p & 3) { *p++ = 0xAA; } while (p < (IMG_BYTE*)((IMG_UINT32)endp & 0xfffffffc)) { *(IMG_UINT32*)p = 0xAAAAAAAA; p += sizeof(IMG_UINT32); } while (p < endp) { *p++ = 0xAA; } PVR_DPF((PVR_DBG_MESSAGE,"BM_FREESPACE_CHECK: RA_Free Cleared %08X to %08X (size=0x%x)",(IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(),endp-1,pBT->uSize)); } #endif _FreeBT (pArena, pBT, bFreeBackingStore); } }
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; }
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; }