Differentiate heap/quota exhausted in the return value of `mspace_dispatch`. The return value of `mspace_dispatch` currently maps two error types, 1) heap exhausted and 2) quota exhausted, to the same return error tag type `AllocationFailureDeallocationNeeded`. Since we need to distinguish between the two in `heap_allocate*`, create two new distinct tag types. While at it, clarify the documentation of `mspace_dispatch`. Signed-off-by: Hugo Lefeuvre <hugo.lefeuvre@scisemi.com>
diff --git a/sdk/core/allocator/alloc.h b/sdk/core/allocator/alloc.h index 9d63a74..20ba2da 100644 --- a/sdk/core/allocator/alloc.h +++ b/sdk/core/allocator/alloc.h
@@ -1099,9 +1099,17 @@ /** * Tag type indicating that the requested allocation cannot succeed until + * some objects have been freed in the passed quota. + */ + struct AllocationFailureQuotaExceeded + { + }; + + /** + * Tag type indicating that the requested allocation cannot succeed until * some objects have been freed. */ - struct AllocationFailureDeallocationNeeded + struct AllocationFailureHeapFull { }; @@ -1110,7 +1118,8 @@ */ using AllocationResult = std::variant<AllocationFailurePermanent, AllocationFailureRevocationNeeded, - AllocationFailureDeallocationNeeded, + AllocationFailureQuotaExceeded, + AllocationFailureHeapFull, CHERI::Capability<void>>; /** @@ -1126,7 +1135,8 @@ * object. This allows it to be skipped when freeing all objects allocated * with a given quota. * - * @return User pointer if request can be satisfied, nullptr otherwise. + * @return User pointer if request can be satisfied, or a tag type + * representing the error otherwise. */ AllocationResult mspace_dispatch(size_t bytes, size_t "a, @@ -1161,7 +1171,7 @@ "quota is {})", alignSize, quota); - return AllocationFailureDeallocationNeeded{}; + return AllocationFailureQuotaExceeded{}; } CHERI::Capability<void> ret{mspace_memalign( alignSize, -CHERI::representable_alignment_mask(bytes))}; @@ -1180,7 +1190,7 @@ { return AllocationFailurePermanent{}; } - return AllocationFailureDeallocationNeeded{}; + return AllocationFailureHeapFull{}; } auto header = MChunkHeader::from_body(ret); @@ -1194,7 +1204,7 @@ header->size_get(), quota); mspace_free_internal(header); - return AllocationFailureDeallocationNeeded{}; + return AllocationFailureQuotaExceeded{}; } if constexpr (DEBUG_ALLOCATOR)
diff --git a/sdk/core/allocator/main.cc b/sdk/core/allocator/main.cc index 7a47e82..bb8160c 100644 --- a/sdk/core/allocator/main.cc +++ b/sdk/core/allocator/main.cc
@@ -303,8 +303,10 @@ } // If the heap is full, wait for someone to free an allocation and // then retry. - if (std::holds_alternative< - MState::AllocationFailureDeallocationNeeded>(ret)) + if (std::holds_alternative<MState::AllocationFailureHeapFull>( + ret) || + std::holds_alternative<MState::AllocationFailureQuotaExceeded>( + ret)) { Debug::log("Not enough free space to handle {}-byte " "allocation, sleeping",