Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/gpgmm/MemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ namespace gpgmm {
AppendChild(std::move(child));
}

MemoryAllocator::~MemoryAllocator() {
// If memory cannot be reused by a (parent) allocator, ensure no used memory leaked.
if (GetParent() == nullptr) {
ASSERT(mInfo.UsedBlockUsage == 0u);
ASSERT(mInfo.UsedBlockCount == 0u);
ASSERT(mInfo.UsedMemoryCount == 0u);
ASSERT(mInfo.UsedMemoryUsage == 0u);
}
}

std::unique_ptr<MemoryAllocation> MemoryAllocator::TryAllocateMemory(uint64_t requestSize,
uint64_t alignment,
bool neverAllocate,
Expand Down
2 changes: 1 addition & 1 deletion src/gpgmm/MemoryAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ namespace gpgmm {
// Constructs a MemoryAllocator that owns a single child allocator.
explicit MemoryAllocator(std::unique_ptr<MemoryAllocator> child);

virtual ~MemoryAllocator() override = default;
virtual ~MemoryAllocator() override;

// Attempts to allocate memory and return an allocation that has at-least
// |requestedSize| allocated space whose value is a multiple of |alignment|. If it cannot,
Expand Down
5 changes: 4 additions & 1 deletion src/gpgmm/PooledMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ namespace gpgmm {
mInfo.UsedMemoryCount--;
mInfo.UsedMemoryUsage -= allocationSize;

mPool->ReturnToPool(std::move(allocation));
MemoryBase* memory = allocation->GetMemory();
ASSERT(memory != nullptr);

mPool->ReturnToPool(std::make_unique<MemoryAllocation>(GetFirstChild(), memory));
}

uint64_t PooledMemoryAllocator::GetMemorySize() const {
Expand Down
12 changes: 7 additions & 5 deletions src/gpgmm/StandaloneMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,17 @@ namespace gpgmm {
new MemoryBlock{0, requestSize});
}

void StandaloneMemoryAllocator::DeallocateMemory(
std::unique_ptr<MemoryAllocation> subAllocation) {
void StandaloneMemoryAllocator::DeallocateMemory(std::unique_ptr<MemoryAllocation> allocation) {
TRACE_EVENT0(TraceEventCategory::Default, "StandaloneMemoryAllocator.DeallocateMemory");

std::lock_guard<std::mutex> lock(mMutex);

MemoryBlock* block = allocation->GetBlock();
mInfo.UsedBlockCount--;
mInfo.UsedBlockUsage -= subAllocation->GetSize();
SafeDelete(subAllocation->GetBlock());
GetFirstChild()->DeallocateMemory(std::move(subAllocation));
mInfo.UsedBlockUsage -= block->Size;

SafeDelete(block);
GetFirstChild()->DeallocateMemory(std::move(allocation));
}

MEMORY_ALLOCATOR_INFO StandaloneMemoryAllocator::GetInfo() const {
Expand Down
6 changes: 6 additions & 0 deletions src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,8 @@ namespace gpgmm { namespace d3d12 {

HRESULT ResourceAllocator::CreateResource(ComPtr<ID3D12Resource> resource,
ResourceAllocation** resourceAllocationOut) {
std::lock_guard<std::mutex> lock(mMutex);

if (!resourceAllocationOut) {
return E_POINTER;
}
Expand All @@ -865,6 +867,10 @@ namespace gpgmm { namespace d3d12 {
resource, GetPreferredMemorySegmentGroup(mDevice.Get(), mIsUMA, heapProperties.Type),
resourceInfo.SizeInBytes);

mInfo.UsedMemoryUsage += resourceInfo.SizeInBytes;
mInfo.UsedMemoryCount++;
mInfo.UsedBlockUsage += resourceInfo.SizeInBytes;

*resourceAllocationOut = new ResourceAllocation{/*residencyManager*/ nullptr,
/*allocator*/ this,
/*offsetFromHeap*/ kInvalidOffset,
Expand Down
8 changes: 8 additions & 0 deletions src/tests/unittests/SlabMemoryAllocatorTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ TEST(SlabMemoryAllocatorTests, SingleSlab) {
EXPECT_EQ(allocation->GetOffset(), 0u);
EXPECT_EQ(allocation->GetMethod(), AllocationMethod::kSubAllocated);
EXPECT_GE(allocation->GetSize(), kBlockSize);

allocator.DeallocateMemory(std::move(allocation));
}

// Verify allocation cannot exceed the fragmentation threshold.
Expand All @@ -97,6 +99,8 @@ TEST(SlabMemoryAllocatorTests, SingleSlab) {
EXPECT_EQ(allocation->GetOffset(), 0u);
EXPECT_EQ(allocation->GetMethod(), AllocationMethod::kSubAllocated);
EXPECT_GE(allocation->GetSize(), kBlockSize);

allocator.DeallocateMemory(std::move(allocation));
}

// Verify allocation succeeds when specifying a slab size.
Expand All @@ -113,6 +117,8 @@ TEST(SlabMemoryAllocatorTests, SingleSlab) {
ASSERT_NE(allocation, nullptr);
EXPECT_GE(allocation->GetSize(), kBlockSize);
EXPECT_GE(allocation->GetMemory()->GetSize(), kSlabSize);

allocator.DeallocateMemory(std::move(allocation));
}

// Verify allocation succeeds when specifying a NPOT slab size.
Expand All @@ -129,6 +135,8 @@ TEST(SlabMemoryAllocatorTests, SingleSlab) {
ASSERT_NE(allocation, nullptr);
EXPECT_GE(allocation->GetSize(), kBlockSize);
EXPECT_GE(allocation->GetMemory()->GetSize(), kSlabSize);

allocator.DeallocateMemory(std::move(allocation));
}

// Verify requesting an allocation without memory will not return a valid allocation.
Expand Down