diff --git a/base-codezero/src/core/irq_session_component.cc b/base-codezero/src/core/irq_session_component.cc index 8c799c103..266237333 100644 --- a/base-codezero/src/core/irq_session_component.cc +++ b/base-codezero/src/core/irq_session_component.cc @@ -56,7 +56,7 @@ Irq_session_component::Irq_session_component(Cap_session *cap_session, { long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1); if (!irq_alloc || (irq_number == -1)|| - irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) { + irq_alloc->alloc_addr(1, irq_number).is_error()) { PERR("unavailable IRQ %lx requested", irq_number); return; } diff --git a/base-fiasco/src/core/io_mem_session_support.cc b/base-fiasco/src/core/io_mem_session_support.cc index 21abe17ee..dcdfd1151 100644 --- a/base-fiasco/src/core/io_mem_session_support.cc +++ b/base-fiasco/src/core/io_mem_session_support.cc @@ -46,7 +46,7 @@ addr_t Io_mem_session_component::_map_local(addr_t base, size_t size) /* find appropriate region for mapping */ void *local_base = 0; - if (!platform()->region_alloc()->alloc_aligned(size, &local_base, alignment)) + if (platform()->region_alloc()->alloc_aligned(size, &local_base, alignment).is_error()) return 0; /* call sigma0 for I/O region */ diff --git a/base-fiasco/src/core/irq_session_component.cc b/base-fiasco/src/core/irq_session_component.cc index eb8c3fb26..2e467f7f0 100644 --- a/base-fiasco/src/core/irq_session_component.cc +++ b/base-fiasco/src/core/irq_session_component.cc @@ -99,7 +99,7 @@ Irq_session_component::Irq_session_component(Cap_session *cap_session, long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1); if (irq_number == -1 || !irq_alloc || - irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) { + irq_alloc->alloc_addr(1, irq_number).is_error()) { PERR("Unavailable IRQ %lx requested", irq_number); throw Root::Invalid_args(); } diff --git a/base-foc/src/core/io_mem_session_support.cc b/base-foc/src/core/io_mem_session_support.cc index 5024b9b03..8fae421ef 100644 --- a/base-foc/src/core/io_mem_session_support.cc +++ b/base-foc/src/core/io_mem_session_support.cc @@ -35,7 +35,7 @@ addr_t Io_mem_session_component::_map_local(addr_t base, size_t size) /* find appropriate region for mapping */ void *local_base = 0; - if (!platform()->region_alloc()->alloc_aligned(size, &local_base, alignment)) + if (platform()->region_alloc()->alloc_aligned(size, &local_base, alignment).is_error()) return 0; if (!map_local_io(base, (addr_t)local_base, size >> get_page_size_log2())) { diff --git a/base-hw/src/core/include/platform_pd.h b/base-hw/src/core/include/platform_pd.h index b2cde113a..7d3fa706e 100644 --- a/base-hw/src/core/include/platform_pd.h +++ b/base-hw/src/core/include/platform_pd.h @@ -52,7 +52,7 @@ namespace Genode void * kernel_pd; Range_allocator * ram = platform()->ram_alloc(); assert(ram->alloc_aligned(Kernel::pd_size(), &kernel_pd, - Kernel::pd_alignm_log2())); + Kernel::pd_alignm_log2()).is_ok()) /* create kernel object */ _id = Kernel::new_pd(kernel_pd); diff --git a/base-hw/src/core/include/vm_session_component.h b/base-hw/src/core/include/vm_session_component.h index dffa6fbc2..13d7ee2d0 100644 --- a/base-hw/src/core/include/vm_session_component.h +++ b/base-hw/src/core/include/vm_session_component.h @@ -45,8 +45,8 @@ namespace Genode { { addr_t addr; if (_ds_size() > *ram_quota || - !_ram_alloc->alloc_aligned(_ds_size(), (void**)&addr, - get_page_size_log2())) + _ram_alloc->alloc_aligned(_ds_size(), (void**)&addr, + get_page_size_log2()).is_error()) throw Root::Quota_exceeded(); *ram_quota -= _ds_size(); return addr; diff --git a/base-hw/src/core/irq_session_component.cc b/base-hw/src/core/irq_session_component.cc index 1f25f15eb..4b0de0869 100644 --- a/base-hw/src/core/irq_session_component.cc +++ b/base-hw/src/core/irq_session_component.cc @@ -53,7 +53,7 @@ Irq_session_component::Irq_session_component(Cap_session * cap_session, /* allocate IRQ */ long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1); if (irq_number == -1 || !irq_alloc || - irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) { + irq_alloc->alloc_addr(1, irq_number).is_error()) { PERR("Unavailable IRQ %lu requested", irq_number); throw Root::Invalid_args(); } diff --git a/base-hw/src/core/platform_thread.cc b/base-hw/src/core/platform_thread.cc index df4c27b59..7e8d0c0db 100644 --- a/base-hw/src/core/platform_thread.cc +++ b/base-hw/src/core/platform_thread.cc @@ -72,7 +72,7 @@ Platform_thread::Platform_thread(const char * name, /* create UTCB for a core thread */ Range_allocator * const ram = platform()->ram_alloc(); assert(ram->alloc_aligned(sizeof(Native_utcb), (void **)&_phys_utcb, - MIN_MAPPING_SIZE_LOG2)); + MIN_MAPPING_SIZE_LOG2).is_ok()); _virt_utcb = _phys_utcb; /* common constructor parts */ diff --git a/base-hw/src/core/rm_session_support.cc b/base-hw/src/core/rm_session_support.cc index e6a6b2a65..58ef79ef8 100644 --- a/base-hw/src/core/rm_session_support.cc +++ b/base-hw/src/core/rm_session_support.cc @@ -72,7 +72,7 @@ void Ipc_pager::resolve_and_wait_for_fault() { /* try to get some natural aligned space */ void * space; - assert(platform()->ram_alloc()->alloc_aligned(1<ram_alloc()->alloc_aligned(1<insert_translation(_mapping.virt_address, diff --git a/base-mb/src/core/context_area.cc b/base-mb/src/core/context_area.cc index 1415a4984..3c235c049 100644 --- a/base-mb/src/core/context_area.cc +++ b/base-mb/src/core/context_area.cc @@ -98,8 +98,8 @@ class Context_area_ram_session : public Ram_session /* allocate physical memory */ size = round_page(size); void *phys_base; - if (!platform_specific()->ram_alloc()->alloc_aligned(size, &phys_base, - get_page_size_log2())) { + if (platform_specific()->ram_alloc()->alloc_aligned(size, &phys_base, + get_page_size_log2()).is_error()) { PERR("could not allocate backing store for new context"); return Ram_dataspace_capability(); } diff --git a/base-mb/src/core/irq_session_component.cc b/base-mb/src/core/irq_session_component.cc index 401438d5f..88fd6ecf0 100644 --- a/base-mb/src/core/irq_session_component.cc +++ b/base-mb/src/core/irq_session_component.cc @@ -44,8 +44,8 @@ Irq_session_component::Irq_session_component(Cap_session *cap_session, _attached(false) { long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1); - if (!_irq_alloc || (irq_number == -1)|| - _irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) + if (!_irq_alloc || (irq_number == -1) || + _irq_alloc->alloc_addr(1, irq_number).is_error()) { PERR("unavailable IRQ %lx requested", irq_number); return; diff --git a/base-mb/src/core/platform.cc b/base-mb/src/core/platform.cc index 8d38fd617..da3e28998 100644 --- a/base-mb/src/core/platform.cc +++ b/base-mb/src/core/platform.cc @@ -60,11 +60,11 @@ Genode::Thread_base::Context * Roottask::physical_context(Genode::Native_thread_ if(!_context[tid]) { /* Allocate new context */ - if(!Genode::platform_specific()-> - core_mem_alloc()-> - alloc_aligned(aligned_size, - (void**)&_context[tid], - CONTEXT_PAGE_SIZE_LOG2)) + if (Genode::platform_specific() + ->core_mem_alloc() + ->alloc_aligned(aligned_size, + (void**)&_context[tid], + CONTEXT_PAGE_SIZE_LOG2).is_error()) { PERR("Allocate memory for a new stack- and misc-area failed"); return 0; @@ -185,7 +185,7 @@ void Genode::Platform::_optimize_init_img_rom(long int & base, size_t const & si /* Search for location where text-segment would be mapable * with pages of size INIT_TEXT_SEGM_ALIGN */ if (_core_mem_alloc.alloc_aligned(size + 2*INIT_TEXT_SEGM_ALIGN, - (void**)&base, INIT_TEXT_SEGM_ALIGN_LOG2)) + (void**)&base, INIT_TEXT_SEGM_ALIGN_LOG2).is_ok()) { /* Found better location so move */ base = base + INIT_TEXT_SEGM_ALIGN - ELF_HEADER_SIZE; diff --git a/base-mb/src/core/platform_thread.cc b/base-mb/src/core/platform_thread.cc index 8c4c3bb94..ec70fbcc5 100755 --- a/base-mb/src/core/platform_thread.cc +++ b/base-mb/src/core/platform_thread.cc @@ -64,11 +64,11 @@ Kernel::Utcb* Genode::physical_utcb(Native_thread_id tid) } if(!phys_utcb[tid]) { - if (!platform_specific()-> - core_mem_alloc()-> - alloc_aligned(sizeof(Kernel::Utcb), - (void**)&phys_utcb[tid], - Kernel::Utcb::ALIGNMENT_LOG2)) + if (platform_specific()-> + core_mem_alloc()-> + alloc_aligned(sizeof(Kernel::Utcb), + (void**)&phys_utcb[tid], + Kernel::Utcb::ALIGNMENT_LOG2).is_error()) { PERR("Allocate memory for a new UTCB failed"); return 0; diff --git a/base-mb/src/core/target.inc b/base-mb/src/core/target.inc index 3fe6e7244..75923ddd3 100755 --- a/base-mb/src/core/target.inc +++ b/base-mb/src/core/target.inc @@ -4,7 +4,7 @@ SPEC_BASE_DIR = $(REP_DIR)/src/base SRC_CC = \ - context_area.cc + context_area.cc \ core_rm_session.cc \ cpu_session_component.cc \ dataspace_component.cc \ diff --git a/base-nova/src/core/io_mem_session_support.cc b/base-nova/src/core/io_mem_session_support.cc index f3bec9de4..a49735e12 100644 --- a/base-nova/src/core/io_mem_session_support.cc +++ b/base-nova/src/core/io_mem_session_support.cc @@ -43,8 +43,8 @@ addr_t Io_mem_session_component::_map_local(addr_t base, size_t size) /* allocate range in core's virtual address space */ void *virt_addr; - if (!platform()->region_alloc()->alloc_aligned(page_rounded_size, - &virt_addr, alignment)) { + if (platform()->region_alloc()->alloc_aligned(page_rounded_size, + &virt_addr, alignment).is_error()) { PERR("Could not allocate virtual address range in core of size %zd\n", page_rounded_size); return 0; diff --git a/base-nova/src/core/ram_session_support.cc b/base-nova/src/core/ram_session_support.cc index 2f5bbc698..89c139d0b 100644 --- a/base-nova/src/core/ram_session_support.cc +++ b/base-nova/src/core/ram_session_support.cc @@ -63,7 +63,7 @@ void Ram_session_component::_clear_ds(Dataspace_component *ds) size_t align_log2 = log2(ds->size()); for (; align_log2 >= get_page_size_log2(); align_log2--) { if (platform()->region_alloc()->alloc_aligned(page_rounded_size, - &virt_addr, align_log2)) { + &virt_addr, align_log2).is_ok()) { virt_alloc_succeeded = true; break; } diff --git a/base-pistachio/src/core/io_mem_session_support.cc b/base-pistachio/src/core/io_mem_session_support.cc index 594acf013..90b373dc7 100644 --- a/base-pistachio/src/core/io_mem_session_support.cc +++ b/base-pistachio/src/core/io_mem_session_support.cc @@ -83,11 +83,10 @@ addr_t Io_mem_session_component::_map_local(addr_t base, size_t size) /* find appropriate region for mapping */ void *result = 0; - platform()->region_alloc()->alloc_aligned(size, &result, alignment); - local_base = (addr_t)result; - - if (!local_base) + if (platform()->region_alloc()->alloc_aligned(size, &result, alignment).is_error()) PERR("alloc_aligned failed!"); + + local_base = (addr_t)result; } if (verbose) diff --git a/base-pistachio/src/core/irq_session_component.cc b/base-pistachio/src/core/irq_session_component.cc index 3b4f0a742..db31b6082 100644 --- a/base-pistachio/src/core/irq_session_component.cc +++ b/base-pistachio/src/core/irq_session_component.cc @@ -110,7 +110,7 @@ Irq_session_component::Irq_session_component(Cap_session *cap_session, long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1); if (irq_number == -1 || !irq_alloc || - irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) { + irq_alloc->alloc_addr(1, irq_number).is_error()) { PERR("unavailable IRQ %lx requested", irq_number); /* FIXME error condition -> exception */ diff --git a/base/include/base/allocator.h b/base/include/base/allocator.h index 6f0f672b4..3c3c1cc99 100644 --- a/base/include/base/allocator.h +++ b/base/include/base/allocator.h @@ -132,6 +132,23 @@ namespace Genode { */ virtual int remove_range(addr_t base, size_t size) = 0; + /** + * Return value of allocation functons + * + * 'OK' on success, or + * 'OUT_OF_METADATA' if meta-data allocation failed, or + * 'RANGE_CONFLICT' if no fitting address range is found + */ + struct Alloc_return + { + enum Value { OK = 0, OUT_OF_METADATA = -1, RANGE_CONFLICT = -2 }; + Value const value; + Alloc_return(Value value) : value(value) { } + + bool is_ok() const { return value == OK; } + bool is_error() const { return !is_ok(); } + }; + /** * Allocate block * @@ -140,11 +157,8 @@ namespace Genode { * undefined in the error case * \param align alignment of new block specified * as the power of two - * \return true on success */ - virtual bool alloc_aligned(size_t size, void **out_addr, int align = 0) = 0; - - enum Alloc_return { ALLOC_OK = 0, OUT_OF_METADATA = -1, RANGE_CONFLICT = -2 }; + virtual Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0) = 0; /** * Allocate block at address diff --git a/base/include/base/allocator_avl.h b/base/include/base/allocator_avl.h index c7d06be09..0d445df1b 100644 --- a/base/include/base/allocator_avl.h +++ b/base/include/base/allocator_avl.h @@ -215,7 +215,7 @@ namespace Genode { int add_range(addr_t base, size_t size); int remove_range(addr_t base, size_t size); - bool alloc_aligned(size_t size, void **out_addr, int align = 0); + Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0); Alloc_return alloc_addr(size_t size, addr_t addr); void free(void *addr); size_t avail(); @@ -227,7 +227,7 @@ namespace Genode { *************************/ bool alloc(size_t size, void **out_addr) { - return Allocator_avl_base::alloc_aligned(size, out_addr); } + return (Allocator_avl_base::alloc_aligned(size, out_addr).is_ok()); } void free(void *addr, size_t) { free(addr); } diff --git a/base/include/base/platform_env.h b/base/include/base/platform_env.h index d45bfe097..ad1d2b188 100644 --- a/base/include/base/platform_env.h +++ b/base/include/base/platform_env.h @@ -71,6 +71,27 @@ namespace Genode { return (addr_t)0; } + + Pager_capability add_client(Thread_capability thread) + { + bool try_again = false; + do { + try { + return Rm_session_client::add_client(thread); + } catch (Rm_session::Out_of_metadata) { + + /* give up if the error occurred a second time */ + if (try_again) + break; + + PINF("upgrade quota donation for Env::RM session"); + env()->parent()->upgrade(_cap, "ram_quota=8K"); + try_again = true; + } + } while (try_again); + + return Pager_capability(); + } }; class Expanding_ram_session_client : public Ram_session_client diff --git a/base/include/base/sync_allocator.h b/base/include/base/sync_allocator.h index eb32deae1..2725c9230 100644 --- a/base/include/base/sync_allocator.h +++ b/base/include/base/sync_allocator.h @@ -208,7 +208,7 @@ namespace Genode { return _alloc.remove_range(base, size); } - bool alloc_aligned(size_t size, void **out_addr, int align = 0) + Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0) { Lock::Guard lock_guard(*_lock); return _alloc.alloc_aligned(size, out_addr, align); diff --git a/base/include/rm_session/rm_session.h b/base/include/rm_session/rm_session.h index 9f566a57f..207909bc8 100644 --- a/base/include/rm_session/rm_session.h +++ b/base/include/rm_session/rm_session.h @@ -100,7 +100,6 @@ namespace Genode { class Out_of_metadata : public Attach_failed { }; class Invalid_thread : public Exception { }; - class Out_of_memory : public Exception { }; /** * Destructor @@ -156,7 +155,7 @@ namespace Genode { * * \param thread thread that will be paged * \throw Invalid_thread - * \throw Out_of_memory + * \throw Out_of_metadata * \return capability to be used for handling page faults * * This method must be called at least once to establish a valid @@ -191,7 +190,7 @@ namespace Genode { Dataspace_capability, size_t, off_t, bool, Local_addr, bool); GENODE_RPC(Rpc_detach, void, detach, Local_addr); GENODE_RPC_THROW(Rpc_add_client, Pager_capability, add_client, - GENODE_TYPE_LIST(Invalid_thread, Out_of_memory), + GENODE_TYPE_LIST(Invalid_thread, Out_of_metadata), Thread_capability); GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability); GENODE_RPC(Rpc_state, State, state); diff --git a/base/src/base/allocator/allocator_avl.cc b/base/src/base/allocator/allocator_avl.cc index f46359f38..50b3289de 100644 --- a/base/src/base/allocator/allocator_avl.cc +++ b/base/src/base/allocator/allocator_avl.cc @@ -247,11 +247,11 @@ int Allocator_avl_base::remove_range(addr_t base, size_t size) } -bool Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, int align) +Range_allocator::Alloc_return Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, int align) { Block *dst1, *dst2; if (!_alloc_two_blocks_metadata(&dst1, &dst2)) - return false; + return Alloc_return(Alloc_return::OUT_OF_METADATA); /* find best fitting block */ Block *b = _addr_tree.first(); @@ -260,7 +260,7 @@ bool Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, int align) if (!b) { _md_alloc->free(dst1, sizeof(Block)); _md_alloc->free(dst2, sizeof(Block)); - return false; + return Alloc_return(Alloc_return::RANGE_CONFLICT); } /* calculate address of new (aligned) block */ @@ -273,12 +273,12 @@ bool Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, int align) Block *new_block = _alloc_block_metadata(); if (!new_block) { _md_alloc->free(new_block, sizeof(Block)); - return false; + return Alloc_return(Alloc_return::OUT_OF_METADATA); } _add_block(new_block, new_addr, size, Block::USED); *out_addr = reinterpret_cast(new_addr); - return true; + return Alloc_return(Alloc_return::OK); } @@ -286,11 +286,11 @@ Range_allocator::Alloc_return Allocator_avl_base::alloc_addr(size_t size, addr_t { /* sanity check */ if (!_sum_in_range(addr, size)) - return Range_allocator::RANGE_CONFLICT; + return Alloc_return(Alloc_return::RANGE_CONFLICT); Block *dst1, *dst2; if (!_alloc_two_blocks_metadata(&dst1, &dst2)) - return Range_allocator::OUT_OF_METADATA; + return Alloc_return(Alloc_return::OUT_OF_METADATA); /* find block at specified address */ Block *b = _addr_tree.first(); @@ -301,7 +301,7 @@ Range_allocator::Alloc_return Allocator_avl_base::alloc_addr(size_t size, addr_t { _md_alloc->free(dst1, sizeof(Block)); _md_alloc->free(dst2, sizeof(Block)); - return Range_allocator::RANGE_CONFLICT; + return Alloc_return(Alloc_return::RANGE_CONFLICT); } /* remove new block from containing block */ @@ -311,11 +311,11 @@ Range_allocator::Alloc_return Allocator_avl_base::alloc_addr(size_t size, addr_t Block *new_block = _alloc_block_metadata(); if (!new_block) { _md_alloc->free(new_block, sizeof(Block)); - return Range_allocator::OUT_OF_METADATA; + return Alloc_return(Alloc_return::OUT_OF_METADATA); } _add_block(new_block, addr, size, Block::USED); - return Range_allocator::ALLOC_OK; + return Alloc_return(Alloc_return::OK); } diff --git a/base/src/base/heap/heap.cc b/base/src/base/heap/heap.cc index 1f44ebe3b..c3f238033 100644 --- a/base/src/base/heap/heap.cc +++ b/base/src/base/heap/heap.cc @@ -61,7 +61,7 @@ int Heap::Dataspace_pool::expand(size_t size, Range_allocator *alloc) alloc->add_range((addr_t)local_addr, size); /* now that we have new backing store, allocate Dataspace structure */ - if (!alloc->alloc_aligned(sizeof(Dataspace), &ds_addr, 2)) { + if (alloc->alloc_aligned(sizeof(Dataspace), &ds_addr, 2).is_error()) { PWRN("could not allocate meta data - this should never happen"); return -1; } @@ -84,7 +84,7 @@ int Heap::quota_limit(size_t new_quota_limit) bool Heap::_try_local_alloc(size_t size, void **out_addr) { - if (!_alloc.alloc_aligned(size, out_addr, 2)) + if (_alloc.alloc_aligned(size, out_addr, 2).is_error()) return false; _quota_used += size; diff --git a/base/src/core/context_area.cc b/base/src/core/context_area.cc index 709d945b3..5b5cd4a3f 100644 --- a/base/src/core/context_area.cc +++ b/base/src/core/context_area.cc @@ -142,8 +142,8 @@ class Context_area_ram_session : public Ram_session /* allocate physical memory */ size = round_page(size); void *phys_base; - if (!platform_specific()->ram_alloc()->alloc_aligned(size, &phys_base, - get_page_size_log2())) { + if (platform_specific()->ram_alloc()->alloc_aligned(size, &phys_base, + get_page_size_log2()).is_error()) { PERR("could not allocate backing store for new context"); return Ram_dataspace_capability(); } diff --git a/base/src/core/include/irq_proxy.h b/base/src/core/include/irq_proxy.h index a20cb43a8..33792ea8e 100644 --- a/base/src/core/include/irq_proxy.h +++ b/base/src/core/include/irq_proxy.h @@ -208,7 +208,7 @@ class Genode::Irq_proxy : public THREAD, return static_cast(p); /* try to create proxy */ - if (!irq_alloc || irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) + if (!irq_alloc || irq_alloc->alloc_addr(1, irq_number).is_error()) return 0; PROXY *new_proxy = new (env()->heap()) PROXY(irq_number); diff --git a/base/src/core/io_mem_session_component.cc b/base/src/core/io_mem_session_component.cc index 182bafb64..facff03b2 100644 --- a/base/src/core/io_mem_session_component.cc +++ b/base/src/core/io_mem_session_component.cc @@ -51,16 +51,16 @@ Io_mem_session_component::_prepare_io_mem(const char *args, } /* allocate region */ - switch (_io_mem_alloc->alloc_addr(req_size, req_base)) { - case Range_allocator::RANGE_CONFLICT: + switch (_io_mem_alloc->alloc_addr(req_size, req_base).value) { + case Range_allocator::Alloc_return::RANGE_CONFLICT: PERR("I/O memory [%lx,%lx) not available", base, base + size); return Dataspace_attr(); - case Range_allocator::OUT_OF_METADATA: + case Range_allocator::Alloc_return::OUT_OF_METADATA: PERR("I/O memory allocator ran out of meta data"); return Dataspace_attr(); - case Range_allocator::ALLOC_OK: break; + case Range_allocator::Alloc_return::OK: break; } /* request local mapping */ diff --git a/base/src/core/ram_session_component.cc b/base/src/core/ram_session_component.cc index 93e89640b..3b692dab1 100644 --- a/base/src/core/ram_session_component.cc +++ b/base/src/core/ram_session_component.cc @@ -145,7 +145,7 @@ Ram_dataspace_capability Ram_session_component::alloc(size_t ds_size, bool cache void *ds_addr = 0; bool alloc_succeeded = false; for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { - if (_ram_alloc->alloc_aligned(ds_size, &ds_addr, align_log2)) { + if (_ram_alloc->alloc_aligned(ds_size, &ds_addr, align_log2).is_ok()) { alloc_succeeded = true; break; } diff --git a/base/src/core/rm_session_component.cc b/base/src/core/rm_session_component.cc index 6456779df..1c37969a1 100644 --- a/base/src/core/rm_session_component.cc +++ b/base/src/core/rm_session_component.cc @@ -350,15 +350,15 @@ Rm_session_component::attach(Dataspace_capability ds_cap, size_t size, /* allocate region for attachment */ void *r = 0; if (use_local_addr) { - switch (_map.alloc_addr(size, local_addr)) { + switch (_map.alloc_addr(size, local_addr).value) { - case Range_allocator::OUT_OF_METADATA: + case Range_allocator::Alloc_return::OUT_OF_METADATA: throw Out_of_metadata(); - case Range_allocator::RANGE_CONFLICT: + case Range_allocator::Alloc_return::RANGE_CONFLICT: throw Region_conflict(); - case Range_allocator::ALLOC_OK: + case Range_allocator::Alloc_return::OK: r = local_addr; break; } @@ -381,8 +381,15 @@ Rm_session_component::attach(Dataspace_capability ds_cap, size_t size, continue; /* try allocating the align region */ - if (_map.alloc_aligned(size, &r, align_log2)) + Range_allocator::Alloc_return alloc_return = + _map.alloc_aligned(size, &r, align_log2); + + if (alloc_return.is_ok()) break; + else if (alloc_return.value == Range_allocator::Alloc_return::OUT_OF_METADATA) { + _map.free(r); + throw Out_of_metadata(); + } } if (align_log2 < get_page_size_log2()) { @@ -569,7 +576,7 @@ Pager_capability Rm_session_component::add_client(Thread_capability thread) Rm_client *cl; try { cl = new(&_client_slab) Rm_client(this, badge); } - catch (Allocator::Out_of_memory) { throw Out_of_memory(); } + catch (Allocator::Out_of_memory) { throw Out_of_metadata(); } _clients.insert(cl); diff --git a/base/src/core/x86/io_port_session_component.cc b/base/src/core/x86/io_port_session_component.cc index bb755929d..3aa682829 100644 --- a/base/src/core/x86/io_port_session_component.cc +++ b/base/src/core/x86/io_port_session_component.cc @@ -102,13 +102,13 @@ Io_port_session_component::Io_port_session_component(Range_allocator *io_port_al unsigned size = Arg_string::find_arg(args, "io_port_size").ulong_value(0); /* allocate region (also checks out-of-bounds regions) */ - switch (io_port_alloc->alloc_addr(size, base)) { + switch (io_port_alloc->alloc_addr(size, base).value) { - case Range_allocator::RANGE_CONFLICT: + case Range_allocator::Alloc_return::RANGE_CONFLICT: PERR("I/O port [%x,%x) not available", base, base + size); throw Root::Invalid_args(); - case Range_allocator::OUT_OF_METADATA: + case Range_allocator::Alloc_return::OUT_OF_METADATA: PERR("I/O port allocator ran out of meta data"); /* @@ -117,7 +117,7 @@ Io_port_session_component::Io_port_session_component(Range_allocator *io_port_al */ throw Root::Invalid_args(); - case Range_allocator::ALLOC_OK: break; + case Range_allocator::Alloc_return::OK: break; } if (verbose) diff --git a/dde_ipxe/src/lib/dde_ipxe/dde_support.cc b/dde_ipxe/src/lib/dde_ipxe/dde_support.cc index 73475c829..33ccecc7d 100644 --- a/dde_ipxe/src/lib/dde_ipxe/dde_support.cc +++ b/dde_ipxe/src/lib/dde_ipxe/dde_support.cc @@ -59,7 +59,10 @@ void __attribute__((constructor)) init() extern "C" void *alloc_memblock(size_t size, size_t align) { void *ptr; - allocator()->alloc_aligned(size, &ptr, log2(align)); + if (allocator()->alloc_aligned(size, &ptr, log2(align)).is_error()) { + PERR("memory allocation failed in alloc_memblock"); + return 0; + }; return ptr; } diff --git a/dde_linux/src/drivers/usb/mem.h b/dde_linux/src/drivers/usb/mem.h index 3dc65f082..3d33574a5 100644 --- a/dde_linux/src/drivers/usb/mem.h +++ b/dde_linux/src/drivers/usb/mem.h @@ -172,7 +172,7 @@ namespace Genode { void *alloc(size_t size, int zone = -1, int align = 2) { void *addr; - if (!_range.alloc_aligned(size, &addr, align)) { + if (_range.alloc_aligned(size, &addr, align).is_error()) { PERR("Memory allocation of %zu bytes failed", size); return 0; } diff --git a/libports/src/lib/libc/fd_alloc.cc b/libports/src/lib/libc/fd_alloc.cc index 51d7aa88e..3502c61b9 100644 --- a/libports/src/lib/libc/fd_alloc.cc +++ b/libports/src/lib/libc/fd_alloc.cc @@ -52,7 +52,7 @@ File_descriptor *File_descriptor_allocator::alloc(Plugin *plugin, if (addr == ANY_FD) alloc_ok = Allocator_avl_base::alloc(1, reinterpret_cast(&addr)); else - alloc_ok = (Allocator_avl_base::alloc_addr(1, addr) == ALLOC_OK); + alloc_ok = (Allocator_avl_base::alloc_addr(1, addr).is_ok()); if (!alloc_ok) { PERR("could not allocate libc_fd %d%s", diff --git a/libports/src/lib/libc/libc_mem_alloc.cc b/libports/src/lib/libc/libc_mem_alloc.cc index 48a7fb20f..804b3fe7c 100644 --- a/libports/src/lib/libc/libc_mem_alloc.cc +++ b/libports/src/lib/libc/libc_mem_alloc.cc @@ -162,7 +162,7 @@ int Libc::Mem_alloc_impl::Dataspace_pool::expand(size_t size, Range_allocator *a alloc->add_range((addr_t)local_addr, size); /* now that we have new backing store, allocate Dataspace structure */ - if (!alloc->alloc_aligned(sizeof(Dataspace), &ds_addr, 2)) { + if (alloc->alloc_aligned(sizeof(Dataspace), &ds_addr, 2).is_error()) { PWRN("could not allocate meta data - this should never happen"); return -1; } @@ -182,7 +182,7 @@ void *Libc::Mem_alloc_impl::alloc(size_t size, size_t align_log2) /* try allocation at our local allocator */ void *out_addr = 0; - if (_alloc.alloc_aligned(size, &out_addr, align_log2)) + if (_alloc.alloc_aligned(size, &out_addr, align_log2).is_ok()) return out_addr; /* @@ -208,7 +208,7 @@ void *Libc::Mem_alloc_impl::alloc(size_t size, size_t align_log2) } /* allocate originally requested block */ - return _alloc.alloc_aligned(size, &out_addr, align_log2) ? out_addr : 0; + return _alloc.alloc_aligned(size, &out_addr, align_log2).is_ok() ? out_addr : 0; } diff --git a/os/include/nic/packet_allocator.h b/os/include/nic/packet_allocator.h index 33ebced17..8571502a9 100644 --- a/os/include/nic/packet_allocator.h +++ b/os/include/nic/packet_allocator.h @@ -72,8 +72,9 @@ namespace Nic { return 0; } - bool alloc_aligned(Genode::size_t size, void **out_addr, int) { - return alloc(size, out_addr); } + Alloc_return alloc_aligned(Genode::size_t size, void **out_addr, int) { + return alloc(size, out_addr) ? Alloc_return::OK + : Alloc_return::RANGE_CONFLICT; } bool alloc(Genode::size_t size, void **out_addr) { @@ -120,8 +121,8 @@ namespace Nic { int remove_range(Genode::addr_t, Genode::size_t) { return 0;} Genode::size_t avail() { return 0; } bool valid_addr(Genode::addr_t) { return 0; } - Genode::Range_allocator::Alloc_return alloc_addr(Genode::size_t, Genode::addr_t) { - return OUT_OF_METADATA; } + Alloc_return alloc_addr(Genode::size_t, Genode::addr_t) { + return Alloc_return(Alloc_return::OUT_OF_METADATA); } }; }; diff --git a/os/include/os/packet_stream.h b/os/include/os/packet_stream.h index 69d44d12d..6c8800b69 100644 --- a/os/include/os/packet_stream.h +++ b/os/include/os/packet_stream.h @@ -577,7 +577,7 @@ class Packet_stream_source : private Packet_stream_base Packet_descriptor alloc_packet(Genode::size_t size, int align = POLICY::Packet_descriptor::PACKET_ALIGNMENT) { void *base = 0; - if (!_packet_alloc->alloc_aligned(size, &base, align)) + if (_packet_alloc->alloc_aligned(size, &base, align).is_error()) throw Packet_alloc_failed(); return Packet_descriptor((Genode::off_t)base, size); diff --git a/os/src/lib/dde_kit/pgtab.cc b/os/src/lib/dde_kit/pgtab.cc index 066048fe0..1e2c302f4 100644 --- a/os/src/lib/dde_kit/pgtab.cc +++ b/os/src/lib/dde_kit/pgtab.cc @@ -115,7 +115,7 @@ extern "C" void dde_kit_pgtab_set_region_with_size(void *virt, dde_kit_addr_t ph map = virt_to_phys_map(); region = Mem_region(reinterpret_cast(virt), size, phys); - if (map->alloc_addr(size, reinterpret_cast(virt)) == Range_allocator::ALLOC_OK) + if (map->alloc_addr(size, reinterpret_cast(virt)).is_ok()) map->metadata(virt, region); else PWRN("virt->phys mapping for [%lx,%lx) failed", @@ -125,7 +125,7 @@ extern "C" void dde_kit_pgtab_set_region_with_size(void *virt, dde_kit_addr_t ph map = phys_to_virt_map(); region = Mem_region(phys, size, reinterpret_cast(virt)); - if (map->alloc_addr(size, phys) == Range_allocator::ALLOC_OK) + if (map->alloc_addr(size, phys).is_ok()) map->metadata(reinterpret_cast(phys), region); else PWRN("phys->virt mapping for [%lx,%lx) failed", phys, phys + size); diff --git a/os/src/lib/ldso/file.cc b/os/src/lib/ldso/file.cc index 941281dc7..9a7283ad2 100644 --- a/os/src/lib/ldso/file.cc +++ b/os/src/lib/ldso/file.cc @@ -61,9 +61,9 @@ namespace Genode { { addr_t addr = vaddr; - if (addr && (_range.alloc_addr(size, addr) != Range_allocator::ALLOC_OK)) + if (addr && (_range.alloc_addr(size, addr).is_error())) throw Region_conflict(); - else if (!addr && !_range.alloc_aligned(size, (void **)&addr, 12)) + else if (!addr && _range.alloc_aligned(size, (void **)&addr, 12).is_error()) throw Region_conflict(); return addr;