core: RAM service based on 'Session_object'

This patch reworks the implementation of core's RAM service to make use
of the 'Session_object' and to remove the distinction between the
"metadata" quota and the managed RAM quota. With the new implementation,
the session implicitly allocates its metadata from its own account. So
there is not need to handle 'Out_of_metadata' and 'Quota_exceeded' via
different exceptions. Instead, the new version solely uses the
'Out_of_ram' exception.

Furthermore, the 'Allocator::Out_of_memory' exception has become an alias
for 'Out_of_ram', which simplifies the error handling.

Issue #2398
This commit is contained in:
Norman Feske
2017-05-08 19:55:54 +02:00
committed by Christian Helmuth
parent 028e633af4
commit e44f65f3b2
32 changed files with 486 additions and 366 deletions

View File

@ -87,6 +87,7 @@ void Child::session_sigh(Signal_context_capability sigh)
/**
* Create session-state object for a dynamically created session
*
* \throw Out_of_ram
* \throw Insufficient_ram_quota
* \throw Parent::Service_denied
*/
@ -648,7 +649,6 @@ void Child::_try_construct_env_dependent_members()
_parent_cap);
}
catch (Out_of_ram) { _error("out of RAM during ELF loading"); }
catch (Ram_session::Alloc_failed) { _error("RAM allocation failed during ELF loading"); }
catch (Cpu_session::Thread_creation_failed) { _error("unable to create initial thread"); }
catch (Cpu_session::Out_of_metadata) { _error("CPU session quota exhausted"); }
catch (Process::Missing_dynamic_linker) { _error("dynamic linker unavailable"); }

View File

@ -102,7 +102,7 @@ Child::Process::Loaded_executable::Loaded_executable(Dataspace_capability elf_ds
/* alloc dataspace */
Dataspace_capability ds_cap;
try { ds_cap = ram.alloc(size); }
catch (Ram_session::Alloc_failed) {
catch (Out_of_ram) {
error("allocation of read-write segment failed"); throw; };
/* attach dataspace */

View File

@ -89,9 +89,9 @@ Heap::Dataspace *Heap::_allocate_dataspace(size_t size, bool enforce_separate_me
try {
new_ds_cap = _ds_pool.ram_alloc->alloc(size);
ds_addr = _ds_pool.region_map->attach(new_ds_cap);
} catch (Ram_session::Alloc_failed) {
return 0;
} catch (Region_map::Attach_failed) {
}
catch (Out_of_ram) { return nullptr; }
catch (Region_map::Attach_failed) {
warning("could not attach dataspace");
_ds_pool.ram_alloc->free(new_ds_cap);
return 0;

View File

@ -49,11 +49,13 @@ bool Sliced_heap::alloc(size_t size, void **out_addr)
try {
ds_cap = _ram_alloc.alloc(size);
block = _region_map.attach(ds_cap);
} catch (Region_map::Attach_failed) {
}
catch (Region_map::Attach_failed) {
error("could not attach dataspace to local address space");
_ram_alloc.free(ds_cap);
return false;
} catch (Ram_allocator::Alloc_failed) {
}
catch (Out_of_ram) {
error("could not allocate dataspace with size ", size);
return false;
}

View File

@ -65,9 +65,7 @@ void Stack::size(size_t const size)
if (ds_addr != (addr_t)attach_addr)
throw Thread::Out_of_stack_space();
}
catch (Ram_session::Alloc_failed) {
throw Thread::Stack_alloc_failed();
}
catch (Out_of_ram) { throw Thread::Stack_alloc_failed(); }
/* update stack information */
_base -= ds_size;
@ -110,7 +108,7 @@ Thread::_alloc_stack(size_t stack_size, char const *name, bool main_thread)
if (attach_addr != (addr_t)env_stack_area_region_map->attach_at(ds_cap, attach_addr, ds_size))
throw Stack_alloc_failed();
}
catch (Ram_session::Alloc_failed) { throw Stack_alloc_failed(); }
catch (Out_of_ram) { throw Stack_alloc_failed(); }
/*
* Now the stack is backed by memory, so it is safe to access its members.