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
2 changes: 1 addition & 1 deletion src/gpgmm/common/BuddyMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ namespace gpgmm {
const uint64_t allocationSize = UpperPowerOfTwo(request.SizeInBytes);

// Request cannot exceed memory size.
GPGMM_INVALID_IF(allocationSize > mMemorySize);
GPGMM_RETURN_ERROR_IF(allocationSize > mMemorySize, "Allocation size exceeds memory size");

// Attempt to sub-allocate a block of the requested size.
std::unique_ptr<MemoryAllocationBase> subAllocation;
Expand Down
21 changes: 15 additions & 6 deletions src/gpgmm/common/Error.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,18 @@
{ \
auto result = expr; \
if (GPGMM_UNLIKELY(!result.IsSuccess())) { \
return {}; \
return result.AcquireError(); \
} \
} \
for (;;) \
break

#define GPGMM_INVALID_IF(expr) \
if (GPGMM_UNLIKELY(expr)) { \
return {}; \
} \
for (;;) \
#define GPGMM_RETURN_ERROR_IF(expr, msg) \
if (GPGMM_UNLIKELY(expr)) { \
gpgmm::DebugLog() << msg; \
return std::move(::gpgmm::ErrorCodeType(kInternalFailureResult)); \
} \
for (;;) \
break

namespace gpgmm {
Expand Down Expand Up @@ -97,6 +98,10 @@ namespace gpgmm {
return std::move(mResult);
}

ErrorT&& AcquireError() {
return std::move(mErrorCode);
}

bool IsSuccess() const {
return mErrorCode == kInternalSuccessResult;
}
Expand Down Expand Up @@ -129,6 +134,10 @@ namespace gpgmm {
return mErrorCode == kInternalSuccessResult;
}

ErrorT&& AcquireError() {
return std::move(mErrorCode);
}

private:
ErrorT mErrorCode;
};
Expand Down
40 changes: 18 additions & 22 deletions src/gpgmm/common/MemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,35 +157,31 @@ namespace gpgmm {
}

MaybeError MemoryAllocatorBase::ValidateRequest(const MemoryAllocationRequest& request) const {
ASSERT(request.SizeInBytes > 0 && request.Alignment > 0);
// Check for non-zero size and alignment.
GPGMM_RETURN_ERROR_IF(request.SizeInBytes == 0, "Request cannot have zero size.");
GPGMM_RETURN_ERROR_IF(request.Alignment == 0, "Request cannot have zero alignment.");

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

// Check request size cannot overflow |this| memory allocator.
const uint64_t alignedSize = AlignTo(request.SizeInBytes, request.Alignment);
if (GetMemorySize() != kInvalidSize && alignedSize > GetMemorySize()) {
DebugLog(MessageId::kSizeExceeded, this)
<< "Requested size exceeds memory size (" + std::to_string(alignedSize) + " vs " +
std::to_string(GetMemorySize()) + " bytes).";
return std::move(ErrorCodeType(kInternalFailureResult));
}
const uint64_t requestedAlignedSize = AlignTo(request.SizeInBytes, request.Alignment);
GPGMM_RETURN_ERROR_IF(
GetMemorySize() != kInvalidSize && requestedAlignedSize > GetMemorySize(),
"Requested size, after alignment, exceeds memory size (" +
std::to_string(requestedAlignedSize) + " vs " + std::to_string(GetMemorySize()) +
" bytes).");

// Check request size has compatible alignment with |this| memory allocator.
// Alignment value of 1 means no alignment required.
if (GetMemoryAlignment() == 0 ||
(GetMemoryAlignment() > 1 && !IsAligned(GetMemoryAlignment(), request.Alignment))) {
DebugLog(MessageId::kAlignmentMismatch, this)
<< "Requested alignment exceeds memory alignment (" +
std::to_string(request.Alignment) + " vs " +
std::to_string(GetMemoryAlignment()) + " bytes).";
return std::move(ErrorCodeType(kInternalFailureResult));
}
GPGMM_RETURN_ERROR_IF(
GetMemoryAlignment() == 0 ||
(GetMemoryAlignment() > 1 && !IsAligned(GetMemoryAlignment(), request.Alignment)),
"Requested alignment exceeds memory alignment (" + std::to_string(request.Alignment) +
" vs " + std::to_string(GetMemoryAlignment()) + " bytes).");

return {};
}
Expand Down
9 changes: 6 additions & 3 deletions src/gpgmm/common/SlabMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ namespace gpgmm {

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

GPGMM_INVALID_IF(request.SizeInBytes > mBlockSize);
GPGMM_RETURN_ERROR_IF(request.SizeInBytes > mBlockSize,
"Allocation size exceeded block size.");

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

GPGMM_RETURN_ERROR_IF(newSlabSize == kInvalidSize, "Slab size was invalid.");

// If the new slab size exceeds the limit, then re-use the previous, smaller size.
if (newSlabSize > mMaxSlabSize) {
Expand Down Expand Up @@ -518,7 +520,8 @@ namespace gpgmm {
GPGMM_RETURN_IF_ERROR(ValidateRequest(request));

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

GPGMM_RETURN_ERROR_IF(blockSize > mMaxSlabSize, "Block size exceeded max slab size.");

// Create a slab allocator for the new entry.
auto entry =
Expand Down