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
4 changes: 2 additions & 2 deletions src/gpgmm/common/BuddyMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ namespace gpgmm {

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

GPGMM_RETURN_ERROR_IF(!ValidateRequest(request));
GPGMM_RETURN_IF_ERROR(ValidateRequest(request));

// Round allocation size to nearest power-of-two.
const uint64_t allocationSize = UpperPowerOfTwo(request.SizeInBytes);

// Request cannot exceed memory size.
GPGMM_RETURN_ERROR_IF(allocationSize > mMemorySize);
GPGMM_INVALID_IF(allocationSize > mMemorySize);

// Attempt to sub-allocate a block of the requested size.
std::unique_ptr<MemoryAllocationBase> subAllocation;
Expand Down
2 changes: 1 addition & 1 deletion src/gpgmm/common/DedicatedMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace gpgmm {

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

GPGMM_RETURN_ERROR_IF(!ValidateRequest(request));
GPGMM_RETURN_IF_ERROR(ValidateRequest(request));

MemoryAllocationRequest memoryRequest = request;
memoryRequest.Alignment = mMemoryAlignment;
Expand Down
50 changes: 45 additions & 5 deletions src/gpgmm/common/Error.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,21 @@
for (;;) \
break

#define GPGMM_RETURN_ERROR_IF(expr) \
if (GPGMM_UNLIKELY(expr)) { \
return {}; \
} \
for (;;) \
#define GPGMM_RETURN_IF_ERROR(expr) \
{ \
auto result = expr; \
if (GPGMM_UNLIKELY(!result.IsSuccess())) { \
return {}; \
} \
} \
for (;;) \
break

#define GPGMM_INVALID_IF(expr) \
if (GPGMM_UNLIKELY(expr)) { \
return {}; \
} \
for (;;) \
break

namespace gpgmm {
Expand Down Expand Up @@ -96,6 +106,36 @@ namespace gpgmm {
ResultT mResult;
};

// Specialization of Result<ErrorT, ResultT> where the ResultT is void.
// Used when a void function must return a Result with only error code.
template <typename ErrorT>
class Result<ErrorT, void> {
public:
Result() : mErrorCode(kInternalSuccessResult) {
}

Result(ErrorT&& error) : mErrorCode(std::move(error)) {
}

Result(Result<ErrorT, void>&& other) : mErrorCode(std::move(other.mErrorCode)) {
}

Result<ErrorT, void>& operator=(Result<ErrorT, void>&& other) {
mErrorCode = std::move(other.mErrorCode);
return *this;
}

bool IsSuccess() const {
return mErrorCode == kInternalSuccessResult;
}

private:
ErrorT mErrorCode;
};

// Result with only an error code.
using MaybeError = Result<ErrorCodeType, void>;

// Alias of Result + error code to avoid having to always specify error type.
template <typename ResultT>
using ResultOrError = Result<ErrorCodeType, ResultT>;
Expand Down
10 changes: 5 additions & 5 deletions src/gpgmm/common/MemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,15 @@ namespace gpgmm {
return mStats;
}

bool MemoryAllocatorBase::ValidateRequest(const MemoryAllocationRequest& request) const {
MaybeError MemoryAllocatorBase::ValidateRequest(const MemoryAllocationRequest& request) const {
ASSERT(request.SizeInBytes > 0 && request.Alignment > 0);

// Check request size cannot overflow.
if (request.SizeInBytes > std::numeric_limits<uint64_t>::max() - (request.Alignment - 1)) {
DebugLog(MessageId::kSizeExceeded, false, GetTypename(), this)
<< "Requested size rejected due to overflow: " + std::to_string(request.SizeInBytes)
<< " bytes.";
return false;
return std::move(ErrorCodeType(kInternalFailureResult));
}

// Check request size cannot overflow |this| memory allocator.
Expand All @@ -173,7 +173,7 @@ namespace gpgmm {
DebugLog(MessageId::kSizeExceeded, false, GetTypename(), this)
<< "Requested size exceeds memory size (" + std::to_string(alignedSize) + " vs " +
std::to_string(GetMemorySize()) + " bytes).";
return false;
return std::move(ErrorCodeType(kInternalFailureResult));
}

// Check request size has compatible alignment with |this| memory allocator.
Expand All @@ -184,10 +184,10 @@ namespace gpgmm {
<< "Requested alignment exceeds memory alignment (" +
std::to_string(request.Alignment) + " vs " +
std::to_string(GetMemoryAlignment()) + " bytes).";
return false;
return std::move(ErrorCodeType(kInternalFailureResult));
}

return true;
return {};
}

MemoryAllocatorBase* MemoryAllocatorBase::GetNextInChain() const {
Expand Down
2 changes: 1 addition & 1 deletion src/gpgmm/common/MemoryAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ namespace gpgmm {
virtual MemoryAllocatorStats GetStats() const;

// Checks if the request is valid.
bool ValidateRequest(const MemoryAllocationRequest& request) const;
MaybeError ValidateRequest(const MemoryAllocationRequest& request) const;

// Return the next MemoryAllocatorBase.
MemoryAllocatorBase* GetNextInChain() const;
Expand Down
2 changes: 1 addition & 1 deletion src/gpgmm/common/PooledMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace gpgmm {

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

GPGMM_RETURN_ERROR_IF(!ValidateRequest(request));
GPGMM_RETURN_IF_ERROR(ValidateRequest(request));

MemoryAllocationBase allocation = mPool->AcquireFromPool();
if (allocation == GPGMM_INVALID_ALLOCATION) {
Expand Down
2 changes: 1 addition & 1 deletion src/gpgmm/common/SegmentedMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ namespace gpgmm {

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

GPGMM_RETURN_ERROR_IF(!ValidateRequest(request));
GPGMM_RETURN_IF_ERROR(ValidateRequest(request));

const uint64_t memorySize = AlignTo(request.SizeInBytes, mMemoryAlignment);
MemorySegment* segment = GetOrCreateFreeSegment(memorySize);
Expand Down
8 changes: 4 additions & 4 deletions src/gpgmm/common/SlabMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ namespace gpgmm {

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

GPGMM_RETURN_ERROR_IF(request.SizeInBytes > mBlockSize);
GPGMM_INVALID_IF(request.SizeInBytes > mBlockSize);

uint64_t slabSize =
ComputeSlabSize(request.SizeInBytes, std::max(mMinSlabSize, mLastUsedSlabSize),
Expand All @@ -229,7 +229,7 @@ namespace gpgmm {
uint64_t newSlabSize = ComputeSlabSize(
request.SizeInBytes, static_cast<uint64_t>(slabSize * mSlabGrowthFactor),
request.AvailableForAllocation);
GPGMM_RETURN_ERROR_IF(newSlabSize == kInvalidSize);
GPGMM_INVALID_IF(newSlabSize == kInvalidSize);

// If the new slab size exceeds the limit, then re-use the previous, smaller size.
if (newSlabSize > mMaxSlabSize) {
Expand Down Expand Up @@ -515,10 +515,10 @@ namespace gpgmm {

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

GPGMM_RETURN_ERROR_IF(!ValidateRequest(request));
GPGMM_RETURN_IF_ERROR(ValidateRequest(request));

const uint64_t blockSize = AlignTo(request.SizeInBytes, request.Alignment);
GPGMM_RETURN_ERROR_IF(blockSize > mMaxSlabSize);
GPGMM_INVALID_IF(blockSize > mMaxSlabSize);

// Create a slab allocator for the new entry.
auto entry =
Expand Down
2 changes: 1 addition & 1 deletion src/gpgmm/vk/DeviceMemoryAllocatorVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ namespace gpgmm::vk {
return {};
}

GPGMM_RETURN_ERROR_IF(!ValidateRequest(request));
GPGMM_RETURN_IF_ERROR(ValidateRequest(request));

VkMemoryAllocateInfo allocateInfo = {};
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
Expand Down