// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Returns the specified object to the pool. void ReturnObject(void* address) { // Acquire the lock. Will be automatically released by the destructor. SpinLock lock(&lock_); BlockHeader* block; unsigned int objectOffset; // It's not needed to search for the corresponding block, // because it can be obtained from the address by mapping // some of the first bits (depending on blockSize_). #ifdef PLATFORM_32 objectOffset = (unsigned int)address % blockSize_; block = reinterpret_cast<BlockHeader*>((unsigned int)address - objectOffset); #else objectOffset = (unsigned int)((unsigned __int64)address % blockSize_); block = reinterpret_cast<BlockHeader*>((unsigned __int64)address - objectOffset); #endif ReturnObjectToBlock(block, objectOffset); if(block != First()) { // Keep at least 'cacheSize_' blocks in the list. if((block->FreeObjects == MaxObjectNumber()) && (Count() > cacheSize_) && (static_cast<BlockHeader*>(First())->FreeObjects > 0)) { // This block can be returned to the OS. Remove(block); DeallocateBlock(block); } else { // Bring the block to the front of the list. This preserves // the property that if the first block has no free objects, // all the other ones don't have free objects either. MakeBlockActive(block); } } }
~ObjectPool() { // Acquire the lock. Will be automatically released by the destructor. SpinLock lock(&lock_); while(Count() > 0) { RemoveFirst(); DeallocateBlock(static_cast<BlockHeader*>(First())); } }
void FIndirectLightingCache::ReleasePrimitive(FPrimitiveComponentId PrimitiveId) { FIndirectLightingCacheAllocation* PrimitiveAllocation; if (PrimitiveAllocations.RemoveAndCopyValue(PrimitiveId, PrimitiveAllocation)) { check(PrimitiveAllocation); if (PrimitiveAllocation->IsValid()) { DeallocateBlock(PrimitiveAllocation->MinTexel, PrimitiveAllocation->AllocationTexelSize); } delete PrimitiveAllocation; } }
void FD3D12BuddyAllocator::DeallocateBlock(uint32 offset, uint32 order) { // See if the buddy block is free uint32 size = OrderToUnitSize(order); uint32 buddy = GetBuddyOffset(offset, size); uint32* it = FreeBlocks[order].Find(buddy); if (it != nullptr) { // Deallocate merged blocks DeallocateBlock(FMath::Min(offset, buddy), order + 1); // Remove the buddy from the free list FreeBlocks[order].Remove(*it); } else { // Add the block to the free list FreeBlocks[order].Add(offset); } }