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
21 changes: 11 additions & 10 deletions src/gpgmm/common/BuddyMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ namespace gpgmm {
&mBuddyBlockAllocator, allocationSize, request.Alignment, request.NeverAllocate,
[&](const auto& block) -> ResultOrError<MemoryBase*> {
const uint64_t memoryIndex = GetMemoryIndex(block->Offset);
MemoryAllocationBase memoryAllocation = mUsedPool.AcquireFromPool(memoryIndex);
std::unique_ptr<MemoryAllocationBase> memoryAllocation =
mUsedPool.AcquireFromPool(memoryIndex);

// No existing, allocate new memory for the block.
if (memoryAllocation == GPGMM_INVALID_ALLOCATION) {
if (memoryAllocation == nullptr) {
MemoryAllocationRequest newRequest = request;
newRequest.SizeInBytes = mMemorySize;
newRequest.Alignment = mMemoryAlignment;
Expand All @@ -79,11 +80,11 @@ namespace gpgmm {
return memoryAllocationResult.GetErrorCode();
}

memoryAllocation = *memoryAllocationResult.AcquireResult();
memoryAllocation = memoryAllocationResult.AcquireResult();
}

MemoryBase* memory = memoryAllocation.GetMemory();
mUsedPool.ReturnToPool(memoryAllocation, memoryIndex);
MemoryBase* memory = memoryAllocation->GetMemory();
mUsedPool.ReturnToPool(std::move(memoryAllocation), memoryIndex);

return memory;
}),
Expand Down Expand Up @@ -117,16 +118,16 @@ namespace gpgmm {

mBuddyBlockAllocator.DeallocateBlock(subAllocation->GetBlock());

MemoryAllocationBase memoryAllocation = mUsedPool.AcquireFromPool(memoryIndex);
std::unique_ptr<MemoryAllocationBase> memoryAllocation =
mUsedPool.AcquireFromPool(memoryIndex);

MemoryBase* memory = memoryAllocation.GetMemory();
MemoryBase* memory = memoryAllocation->GetMemory();
ASSERT(memory != nullptr);

if (memory->Unref()) {
GetNextInChain()->DeallocateMemory(
std::make_unique<MemoryAllocationBase>(memoryAllocation));
GetNextInChain()->DeallocateMemory(std::move(memoryAllocation));
} else {
mUsedPool.ReturnToPool(memoryAllocation, memoryIndex);
mUsedPool.ReturnToPool(std::move(memoryAllocation), memoryIndex);
}
}

Expand Down
12 changes: 5 additions & 7 deletions src/gpgmm/common/IndexedMemoryPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,16 @@ namespace gpgmm {
IndexedMemoryPool::IndexedMemoryPool(uint64_t memorySize) : MemoryPoolBase(memorySize) {
}

MemoryAllocationBase IndexedMemoryPool::AcquireFromPool(uint64_t indexInPool) {
std::unique_ptr<MemoryAllocationBase> IndexedMemoryPool::AcquireFromPool(uint64_t indexInPool) {
if (indexInPool >= mPool.size()) {
mPool.resize(indexInPool + 1);
}
MemoryAllocationBase tmp = mPool[indexInPool];
mPool[indexInPool] = {}; // invalidate it
return tmp;
return std::unique_ptr<MemoryAllocationBase>(mPool[indexInPool].release());
}

void IndexedMemoryPool::ReturnToPool(MemoryAllocationBase allocation, uint64_t indexInPool) {
void IndexedMemoryPool::ReturnToPool(std::unique_ptr<MemoryAllocationBase> allocation,
uint64_t indexInPool) {
ASSERT(indexInPool < mPool.size());
ASSERT(allocation.GetSize() == GetMemorySize());
mPool[indexInPool] = std::move(allocation);
}

Expand All @@ -44,7 +42,7 @@ namespace gpgmm {
uint64_t IndexedMemoryPool::GetPoolSize() const {
uint64_t count = 0;
for (auto& allocation : mPool) {
if (allocation != GPGMM_INVALID_ALLOCATION) {
if (allocation != nullptr) {
count++;
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/gpgmm/common/IndexedMemoryPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ namespace gpgmm {
~IndexedMemoryPool() override = default;

// MemoryPoolBase interface
MemoryAllocationBase AcquireFromPool(uint64_t indexInPool) override;
void ReturnToPool(MemoryAllocationBase allocation, uint64_t indexInPool) override;
std::unique_ptr<MemoryAllocationBase> AcquireFromPool(uint64_t indexInPool) override;
void ReturnToPool(std::unique_ptr<MemoryAllocationBase> allocation,
uint64_t indexInPool) override;
uint64_t ReleasePool(uint64_t bytesToRelease) override;

uint64_t GetPoolSize() const override;

private:
std::vector<MemoryAllocationBase> mPool;
std::vector<std::unique_ptr<MemoryAllocationBase>> mPool;
};

} // namespace gpgmm
Expand Down
9 changes: 4 additions & 5 deletions src/gpgmm/common/LIFOMemoryPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,20 @@ namespace gpgmm {
LIFOMemoryPool::LIFOMemoryPool(uint64_t memorySize) : MemoryPoolBase(memorySize) {
}

MemoryAllocationBase LIFOMemoryPool::AcquireFromPool(uint64_t indexInPool) {
std::unique_ptr<MemoryAllocationBase> LIFOMemoryPool::AcquireFromPool(uint64_t indexInPool) {
ASSERT(indexInPool == kInvalidIndex);

MemoryAllocationBase allocation = {};
std::unique_ptr<MemoryAllocationBase> allocation;
if (!mPool.empty()) {
allocation = std::move(mPool.front());
mPool.pop_front();
}
return allocation;
}

void LIFOMemoryPool::ReturnToPool(MemoryAllocationBase allocation, uint64_t indexInPool) {
void LIFOMemoryPool::ReturnToPool(std::unique_ptr<MemoryAllocationBase> allocation,
uint64_t indexInPool) {
ASSERT(indexInPool == kInvalidIndex);
ASSERT(allocation.GetSize() == GetMemorySize());

mPool.push_front(std::move(allocation));
}

Expand Down
7 changes: 4 additions & 3 deletions src/gpgmm/common/LIFOMemoryPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ namespace gpgmm {
~LIFOMemoryPool() override = default;

// MemoryPoolBase interface
MemoryAllocationBase AcquireFromPool(uint64_t indexInPool = kInvalidIndex) override;
void ReturnToPool(MemoryAllocationBase allocation,
std::unique_ptr<MemoryAllocationBase> AcquireFromPool(
uint64_t indexInPool = kInvalidIndex) override;
void ReturnToPool(std::unique_ptr<MemoryAllocationBase> allocation,
uint64_t indexInPool = kInvalidIndex) override;
uint64_t ReleasePool(uint64_t bytesToFree = kInvalidSize) override;

uint64_t GetPoolSize() const override;

private:
std::deque<MemoryAllocationBase> mPool;
std::deque<std::unique_ptr<MemoryAllocationBase>> mPool;
};

} // namespace gpgmm
Expand Down
4 changes: 0 additions & 4 deletions src/gpgmm/common/MemoryAllocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@
#include "gpgmm/common/Object.h"
#include "gpgmm/utils/Limits.h"

#define GPGMM_INVALID_ALLOCATION \
MemoryAllocationBase { \
}

namespace gpgmm {

// Represents how memory was allocated.
Expand Down
10 changes: 5 additions & 5 deletions src/gpgmm/common/MemoryPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ namespace gpgmm {

// Retrieves a memory allocation from the pool using an optional index.
// Use kInvalidIndex to specify |this| pool is not indexed.
virtual MemoryAllocationBase AcquireFromPool(uint64_t indexInPool) = 0;
virtual std::unique_ptr<MemoryAllocationBase> AcquireFromPool(uint64_t indexInPool) = 0;

// Returns a memory allocation back to the pool using an optional index.
// Use kInvalidIndex to specify |this| pool is not indexed.
virtual void ReturnToPool(MemoryAllocationBase allocation, uint64_t indexInPool) = 0;
virtual void ReturnToPool(std::unique_ptr<MemoryAllocationBase> allocation,
uint64_t indexInPool) = 0;

// Deallocate or shrink the pool.
virtual uint64_t ReleasePool(uint64_t bytesToRelease) = 0;
Expand All @@ -53,9 +54,8 @@ namespace gpgmm {
uint64_t totalBytesReleased = 0;
uint64_t lastIndex = 0;
for (auto& allocation : pool) {
totalBytesReleased += allocation.GetSize();
allocation.GetAllocator()->DeallocateMemory(
std::make_unique<MemoryAllocationBase>(allocation));
totalBytesReleased += allocation->GetSize();
allocation->GetAllocator()->DeallocateMemory(std::move(allocation));
lastIndex++;
if (totalBytesReleased >= bytesToRelease) {
break;
Expand Down
20 changes: 10 additions & 10 deletions src/gpgmm/common/PooledMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,26 @@ namespace gpgmm {

GPGMM_RETURN_IF_ERROR(ValidateRequest(request));

MemoryAllocationBase allocation = mPool->AcquireFromPool(kInvalidIndex);
if (allocation == GPGMM_INVALID_ALLOCATION) {
std::unique_ptr<MemoryAllocationBase> allocation = mPool->AcquireFromPool(kInvalidIndex);
if (allocation == nullptr) {
MemoryAllocationRequest memoryRequest = request;
memoryRequest.Alignment = mMemoryAlignment;
memoryRequest.SizeInBytes = AlignTo(request.SizeInBytes, mMemoryAlignment);

std::unique_ptr<MemoryAllocationBase> allocationPtr;
GPGMM_TRY_ASSIGN(GetNextInChain()->TryAllocateMemory(memoryRequest), allocationPtr);
allocation = *allocationPtr;
allocation.reset(allocationPtr.release());
} else {
mStats.FreeMemoryUsage -= allocation.GetSize();
mStats.FreeMemoryUsage -= allocation->GetSize();
}

mStats.UsedMemoryCount++;
mStats.UsedMemoryUsage += allocation.GetSize();
mStats.UsedMemoryUsage += allocation->GetSize();

MemoryBase* memory = allocation.GetMemory();
MemoryBase* memory = allocation->GetMemory();
ASSERT(memory != nullptr);

return std::make_unique<MemoryAllocationBase>(this, memory, allocation.GetRequestSize());
return std::make_unique<MemoryAllocationBase>(this, memory, allocation->GetRequestSize());
}

void PooledMemoryAllocator::DeallocateMemory(std::unique_ptr<MemoryAllocationBase> allocation) {
Expand All @@ -80,9 +80,9 @@ namespace gpgmm {
MemoryBase* memory = allocation->GetMemory();
ASSERT(memory != nullptr);

mPool->ReturnToPool(
MemoryAllocationBase(GetNextInChain(), memory, allocation->GetRequestSize()),
kInvalidIndex);
mPool->ReturnToPool(std::make_unique<MemoryAllocationBase>(GetNextInChain(), memory,
allocation->GetRequestSize()),
kInvalidIndex);
}

uint64_t PooledMemoryAllocator::ReleaseMemory(uint64_t bytesToRelease) {
Expand Down
16 changes: 8 additions & 8 deletions src/gpgmm/common/SegmentedMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,23 +132,23 @@ namespace gpgmm {
MemorySegment* segment = GetOrCreateFreeSegment(memorySize);
ASSERT(segment != nullptr);

MemoryAllocationBase allocation = segment->AcquireFromPool();
if (allocation == GPGMM_INVALID_ALLOCATION) {
std::unique_ptr<MemoryAllocationBase> allocation = segment->AcquireFromPool();
if (allocation == nullptr) {
MemoryAllocationRequest memoryRequest = request;
memoryRequest.Alignment = mMemoryAlignment;
memoryRequest.SizeInBytes = AlignTo(request.SizeInBytes, mMemoryAlignment);

std::unique_ptr<MemoryAllocationBase> allocationPtr;
GPGMM_TRY_ASSIGN(GetNextInChain()->TryAllocateMemory(memoryRequest), allocationPtr);
allocation = *allocationPtr;
allocation.reset(allocationPtr.release());
} else {
mStats.FreeMemoryUsage -= allocation.GetSize();
mStats.FreeMemoryUsage -= allocation->GetSize();
}

mStats.UsedMemoryCount++;
mStats.UsedMemoryUsage += allocation.GetSize();
mStats.UsedMemoryUsage += allocation->GetSize();

MemoryBase* memory = allocation.GetMemory();
MemoryBase* memory = allocation->GetMemory();
ASSERT(memory != nullptr);
memory->SetPool(segment);

Expand All @@ -175,8 +175,8 @@ namespace gpgmm {
MemoryPoolBase* pool = memory->GetPool();
ASSERT(pool != nullptr);

static_cast<MemorySegment*>(pool)->ReturnToPool(
MemoryAllocationBase(GetNextInChain(), memory, allocation->GetRequestSize()));
static_cast<MemorySegment*>(pool)->ReturnToPool(std::make_unique<MemoryAllocationBase>(
GetNextInChain(), memory, allocation->GetRequestSize()));
}

uint64_t SegmentedMemoryAllocator::ReleaseMemory(uint64_t bytesToRelease) {
Expand Down
4 changes: 2 additions & 2 deletions src/tests/unittests/MemoryPoolTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ TEST_F(LIFOMemoryPoolTests, SingleAllocation) {
EXPECT_EQ(pool.GetPoolSize() * pool.GetMemorySize(), 0u);

pool.ReturnToPool(
*allocator.TryAllocateMemoryForTesting(CreateBasicRequest(kDefaultMemorySize)));
allocator.TryAllocateMemoryForTesting(CreateBasicRequest(kDefaultMemorySize)));
EXPECT_EQ(pool.GetPoolSize() * pool.GetMemorySize(), kDefaultMemorySize);
EXPECT_EQ(pool.GetPoolSize(), 1u);

Expand All @@ -68,7 +68,7 @@ TEST_F(LIFOMemoryPoolTests, MultipleAllocations) {
constexpr uint64_t kPoolSize = 64;
while (pool.GetPoolSize() < kPoolSize) {
pool.ReturnToPool(
*allocator.TryAllocateMemoryForTesting(CreateBasicRequest(kDefaultMemorySize)));
allocator.TryAllocateMemoryForTesting(CreateBasicRequest(kDefaultMemorySize)));
}

EXPECT_EQ(pool.GetPoolSize() * pool.GetMemorySize(), kDefaultMemorySize * kPoolSize);
Expand Down