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

@ -64,22 +64,21 @@ class Genode::Platform : public Platform_generic
struct Dummy_allocator : Range_allocator
{
void free(void *, size_t) override { ASSERT_NEVER_CALLED; }
bool need_size_for_free() const override { ASSERT_NEVER_CALLED; }
size_t consumed() const override { ASSERT_NEVER_CALLED; }
size_t overhead(size_t) const override { ASSERT_NEVER_CALLED; }
int add_range (addr_t, size_t ) override { ASSERT_NEVER_CALLED; }
int remove_range(addr_t, size_t ) override { ASSERT_NEVER_CALLED; }
void free(void *) override { ASSERT_NEVER_CALLED; }
size_t avail() const override { ASSERT_NEVER_CALLED; }
bool valid_addr(addr_t ) const override { ASSERT_NEVER_CALLED; }
bool alloc(size_t, void **) override { ASSERT_NEVER_CALLED; }
void free(void *, size_t) override { ASSERT_NEVER_CALLED; }
bool need_size_for_free() const override { ASSERT_NEVER_CALLED; }
size_t consumed() const override { ASSERT_NEVER_CALLED; }
size_t overhead(size_t) const override { ASSERT_NEVER_CALLED; }
Range_result add_range (addr_t, size_t ) override { ASSERT_NEVER_CALLED; }
Range_result remove_range(addr_t, size_t ) override { ASSERT_NEVER_CALLED; }
void free(void *) override { ASSERT_NEVER_CALLED; }
size_t avail() const override { ASSERT_NEVER_CALLED; }
bool valid_addr(addr_t ) const override { ASSERT_NEVER_CALLED; }
Alloc_result try_alloc(size_t) override { ASSERT_NEVER_CALLED; }
Alloc_result alloc_addr(size_t, addr_t) override { ASSERT_NEVER_CALLED; }
Alloc_return alloc_aligned(size_t, void **, unsigned, Range) override
Alloc_result alloc_aligned(size_t, unsigned, Range) override
{ ASSERT_NEVER_CALLED; }
Alloc_return alloc_addr(size_t, addr_t) override
{ ASSERT_NEVER_CALLED; }
} _dummy_alloc { };
@ -88,25 +87,31 @@ class Genode::Platform : public Platform_generic
*/
struct Pseudo_ram_allocator : Range_allocator
{
bool alloc(size_t, void **out_addr) override
Alloc_result try_alloc(size_t) override
{
*out_addr = 0;
return true;
return nullptr;
}
Alloc_return alloc_aligned(size_t, void **out, unsigned, Range) override
Alloc_result alloc_aligned(size_t, unsigned, Range) override
{
*out = 0;
return Alloc_return::OK;
return nullptr;
}
Alloc_return alloc_addr(size_t, addr_t) override
Alloc_result alloc_addr(size_t, addr_t) override
{
return Alloc_return::OK;
return nullptr;
}
Range_result add_range(addr_t, size_t) override
{
return Range_ok();
}
Range_result remove_range(addr_t, size_t) override
{
return Range_ok();
}
int add_range(addr_t, size_t) override { return 0; }
int remove_range(addr_t, size_t) override { return 0; }
void free(void *) override { }
void free(void *, size_t) override { }
size_t avail() const override { return ram_quota_from_env(); }

View File

@ -410,11 +410,7 @@ namespace {
{
typedef Genode::size_t size_t;
bool alloc(size_t size, void **out_addr) override
{
*out_addr = malloc(size);
return true;
}
Alloc_result try_alloc(size_t size) override { return malloc(size); }
void free(void *addr, size_t) override { ::free(addr); }

View File

@ -51,9 +51,9 @@ Main::Main(Env &env) : heap(env.ram(), env.rm())
/* induce initial heap expansion to remove RM noise */
if (1) {
void *addr;
heap.alloc(0x100000, &addr);
heap.free(addr, 0);
heap.try_alloc(0x100000).with_result(
[&] (void *ptr) { heap.free(ptr, 0); },
[&] (Allocator::Alloc_error) { });
}
addr_t beg((addr_t)&blob_beg);