base: introduce Allocator::try_alloc

This patch changes the 'Allocator' interface to the use of 'Attempt'
return values instead of using exceptions for propagating errors.

To largely uphold compatibility with components using the original
exception-based interface - in particluar use cases where an 'Allocator'
is passed to the 'new' operator - the traditional 'alloc' is still
supported. But it existes merely as a wrapper around the new
'try_alloc'.

Issue #4324
This commit is contained in:
Norman Feske
2021-11-10 12:01:32 +01:00
committed by Christian Helmuth
parent 9591e6caee
commit dc39a8db62
102 changed files with 2128 additions and 1710 deletions

View File

@@ -128,37 +128,40 @@ namespace Allocator {
/**
* Allocate
*/
bool alloc(size_t size, void **out_addr)
Alloc_result try_alloc(size_t size) override
{
bool done = _range.alloc(size, out_addr);
Alloc_result result = _range.try_alloc(size);
if (result.ok())
return result;
if (done)
return done;
if (!_alloc_block())
return Alloc_error::DENIED;
done = _alloc_block();
if (!done)
return false;
return _range.alloc(size, out_addr);
return _range.try_alloc(size);
}
void *alloc_aligned(size_t size, unsigned align = 0)
{
void *addr;
if (!_range.alloc_aligned(size, &addr, align).error())
return addr;
Alloc_result result = _range.alloc_aligned(size, align);
if (result.ok())
return result.convert<void *>(
[&] (void *ptr) { return ptr; },
[&] (Alloc_error) -> void * { return nullptr; });
if (!_alloc_block())
return 0;
if (_range.alloc_aligned(size, &addr, align).error()) {
error("backend allocator: Unable to allocate memory "
"(size: ", size, " align: ", align, ")");
return 0;
}
return _range.alloc_aligned(size, align).convert<void *>(
return addr;
[&] (void *ptr) {
return ptr; },
[&] (Alloc_error e) -> void * {
error("backend allocator: Unable to allocate memory "
"(size: ", size, " align: ", align, ")");
return nullptr;
}
);
}
void free(void *addr, size_t size) override { _range.free(addr, size); }