uint32_t MEMGetAllocatableSizeForExpHeapEx(MEMHeapHandle handle, int32_t alignment) { auto heap = virt_cast<MEMExpHeap *>(handle); auto largestFree = 0u; internal::HeapLock lock { virt_addrof(heap->header) }; if (alignment > 0) { decaf_check((alignment & 0x3) == 0); for (auto block = heap->freeList.head; block; block = block->next) { auto alignedSize = getAlignedBlockSize(block, alignment, MEMExpHeapDirection::FromStart); if (alignedSize > largestFree) { largestFree = alignedSize; } } } else { alignment = -alignment; decaf_check((alignment & 0x3) == 0); for (auto block = heap->freeList.head; block; block = block->next) { auto alignedSize = getAlignedBlockSize(block, alignment, MEMExpHeapDirection::FromEnd); if (alignedSize > largestFree) { largestFree = alignedSize; } } } return largestFree; }
dp::rix::core::ContainerSharedHandle BufferManagerOffset::allocationGetBufferContainer( AllocationHandle allocation ) { AllocationImplHandle allocationImpl = dp::rix::core::handleCast<AllocationImpl>(allocation); dp::rix::core::ContainerSharedHandle container = getRenderer()->containerCreate( m_descriptor ); dp::rix::core::ContainerDataBuffer cdb( allocationImpl->m_chunk->m_buffer, allocationImpl->m_blockIndex * getAlignedBlockSize(), getBlockSize() ); getRenderer()->containerSetData( container, m_entry, cdb ); return container; }
virt_ptr<void> MEMAllocFromExpHeapEx(MEMHeapHandle handle, uint32_t size, int32_t alignment) { auto heap = virt_cast<MEMExpHeap *>(handle); decaf_check(heap->header.tag == MEMHeapTag::ExpandedHeap); auto expHeapFlags = heap->attribs.value(); if (size == 0) { size = 1; } decaf_check(alignment != 0); internal::HeapLock lock { virt_addrof(heap->header) }; virt_ptr<MEMExpHeapBlock> newBlock = nullptr; size = align_up(size, 4); if (alignment > 0) { auto foundBlock = virt_ptr<MEMExpHeapBlock> { nullptr }; auto bestAlignedSize = 0xFFFFFFFFu; alignment = std::max(4, alignment); decaf_check((alignment & 0x3) == 0); for (auto block = heap->freeList.head; block; block = block->next) { auto alignedSize = getAlignedBlockSize(block, alignment, MEMExpHeapDirection::FromStart); if (alignedSize >= size) { if (expHeapFlags.allocMode() == MEMExpHeapMode::FirstFree) { foundBlock = block; break; } else { if (alignedSize < bestAlignedSize) { foundBlock = block; bestAlignedSize = alignedSize; } } } } if (foundBlock) { newBlock = createUsedBlockFromFreeBlock(heap, foundBlock, size, alignment, MEMExpHeapDirection::FromStart); } } else { alignment = std::max(4, -alignment); decaf_check((alignment & 0x3) == 0); auto foundBlock = virt_ptr<MEMExpHeapBlock> { nullptr }; auto bestAlignedSize = 0xFFFFFFFFu; for (auto block = heap->freeList.head; block; block = block->next) { auto alignedSize = getAlignedBlockSize(block, alignment, MEMExpHeapDirection::FromEnd); if (alignedSize >= size) { if (expHeapFlags.allocMode() == MEMExpHeapMode::FirstFree) { foundBlock = block; break; } else { if (alignedSize < bestAlignedSize) { foundBlock = block; bestAlignedSize = alignedSize; } } } } if (foundBlock) { newBlock = createUsedBlockFromFreeBlock(heap, foundBlock, size, alignment, MEMExpHeapDirection::FromEnd); } } if (!newBlock) { MEMDumpHeap(virt_addrof(heap->header)); return nullptr; } return getBlockDataStart(newBlock); }
dp::rix::fx::SmartChunk BufferManagerIndexed::allocateChunk() { return new Chunk( this, getAlignedBlockSize(), getChunkSize() ); }