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

@ -34,14 +34,18 @@ addr_t Io_mem_session_component::_map_local(addr_t base, size_t size)
: get_page_size_log2();
/* find appropriate region for mapping */
void *local_base = 0;
if (platform().region_alloc().alloc_aligned(size, &local_base, alignment).error())
return 0;
return platform().region_alloc().alloc_aligned(size, alignment).convert<addr_t>(
if (!map_local_io(base, (addr_t)local_base, size >> get_page_size_log2())) {
error("map_local_io failed");
return 0;
}
[&] (void *local_base) {
if (!map_local_io(base, (addr_t)local_base, size >> get_page_size_log2())) {
error("map_local_io failed");
platform().region_alloc().free(local_base, base);
return 0UL;
}
return (addr_t)local_base;
},
return (addr_t)local_base;
[&] (Range_allocator::Alloc_error) {
error("allocation of virtual memory for local I/O mapping failed");
return 0UL; });
}

View File

@ -196,7 +196,7 @@ Irq_session_component::Irq_session_component(Range_allocator &irq_alloc,
}
msi_alloc.set(_irq_number, 1);
} else {
if (irq_alloc.alloc_addr(1, _irq_number).error()) {
if (irq_alloc.alloc_addr(1, _irq_number).failed()) {
error("unavailable IRQ ", _irq_number, " requested");
throw Service_denied();
}

View File

@ -467,75 +467,68 @@ Platform::Platform()
core_thread.pager(_sigma0);
_core_pd->bind_thread(core_thread);
/* export x86 platform specific infos */
auto export_page_as_rom_module = [&] (auto rom_name, auto content_fn)
{
void * core_local_ptr = nullptr;
void * phys_ptr = nullptr;
unsigned const pages = 1;
size_t const align = get_page_size_log2();
size_t const size = pages << get_page_size_log2();
size_t const pages = 1;
size_t const align = get_page_size_log2();
size_t const bytes = pages << get_page_size_log2();
ram_alloc().alloc_aligned(bytes, align).with_result(
if (ram_alloc().alloc_aligned(size, &phys_ptr, align).error())
return;
[&] (void *phys_ptr) {
if (region_alloc().alloc_aligned(size, &core_local_ptr, align).error())
return;
addr_t const phys_addr = reinterpret_cast<addr_t>(phys_ptr);
addr_t const phys_addr = reinterpret_cast<addr_t>(phys_ptr);
addr_t const core_local_addr = reinterpret_cast<addr_t>(core_local_ptr);
region_alloc().alloc_aligned(bytes, align).with_result(
[&] (void *core_local_ptr) {
if (!map_local(phys_addr, core_local_addr, pages))
return;
if (!map_local(phys_addr, (addr_t)core_local_ptr, pages)) {
warning("map_local failed while exporting ",
rom_name, " as ROM module");
ram_alloc().free(phys_ptr, bytes);
region_alloc().free(core_local_ptr, bytes);
return;
}
memset(core_local_ptr, 0, size);
memset(core_local_ptr, 0, bytes);
content_fn((char *)core_local_ptr, bytes);
Xml_generator xml(reinterpret_cast<char *>(core_local_addr),
pages << get_page_size_log2(),
"platform_info", [&] ()
{
xml.node("kernel", [&] () {
xml.attribute("name", "foc");
xml.attribute("acpi", true);
xml.attribute("msi" , true);
_rom_fs.insert(new (core_mem_alloc())
Rom_module(phys_addr, bytes, rom_name));
},
[&] (Range_allocator::Alloc_error) {
warning("failed allocate virtual memory to export ",
rom_name, " as ROM module");
ram_alloc().free(phys_ptr, bytes);
}
);
},
[&] (Range_allocator::Alloc_error) {
warning("failed to export ", rom_name, " as ROM module"); }
);
};
export_page_as_rom_module("platform_info",
[&] (char *core_local_ptr, size_t size) {
Xml_generator xml(core_local_ptr, size, "platform_info", [&] ()
{
xml.node("kernel", [&] () {
xml.attribute("name", "foc");
xml.attribute("acpi", true);
xml.attribute("msi" , true);
});
xml.node("hardware", [&] () {
_setup_platform_info(xml, sigma0_map_kip()); });
xml.node("affinity-space", [&] () {
xml.attribute("width", affinity_space().width());
xml.attribute("height", affinity_space().height()); });
});
xml.node("hardware", [&] () {
_setup_platform_info(xml, sigma0_map_kip()); });
}
);
xml.node("affinity-space", [&] () {
xml.attribute("width", affinity_space().width());
xml.attribute("height", affinity_space().height()); });
});
_rom_fs.insert(new (core_mem_alloc()) Rom_module(phys_addr, size,
"platform_info"));
}
/* core log as ROM module */
{
void * core_local_ptr = nullptr;
void * phys_ptr = nullptr;
unsigned const pages = 1;
size_t const align = get_page_size_log2();
size_t const size = pages << get_page_size_log2();
if (ram_alloc().alloc_aligned(size, &phys_ptr, align).error())
return;
if (region_alloc().alloc_aligned(size, &core_local_ptr, align).error())
return;
addr_t const phys_addr = reinterpret_cast<addr_t>(phys_ptr);
addr_t const core_local_addr = reinterpret_cast<addr_t>(core_local_ptr);
if (!map_local(phys_addr, core_local_addr, pages))
return;
memset(core_local_ptr, 0, size);
_rom_fs.insert(new (core_mem_alloc()) Rom_module(phys_addr, size,
"core_log"));
init_core_log(Core_log_range { core_local_addr, size } );
}
export_page_as_rom_module("core_log",
[&] (char *core_local_ptr, size_t size) {
init_core_log(Core_log_range { (addr_t)core_local_ptr, size } ); });
Affinity::Space const cpus = affinity_space();

View File

@ -198,11 +198,9 @@ unsigned long Cap_id_allocator::alloc()
{
Mutex::Guard lock_guard(_mutex);
void *id = nullptr;
if (_id_alloc.alloc(CAP_ID_OFFSET, &id))
return (unsigned long) id;
throw Out_of_ids();
return _id_alloc.try_alloc(CAP_ID_OFFSET).convert<unsigned long>(
[&] (void *id) { return (unsigned long)id; },
[&] (Range_allocator::Alloc_error) -> unsigned long { throw Out_of_ids(); });
}