From b53601d01bf7afbb3e82e410563800e9b5c70fd7 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Tue, 15 Apr 2014 12:23:22 +0200 Subject: [PATCH] hw: cleanup signal-session component ref #1123 --- base-hw/src/core/include/signal_root.h | 16 -- .../core/include/signal_session_component.h | 264 ++++++++++-------- base-hw/src/core/signal_session_component.cc | 41 +-- 3 files changed, 159 insertions(+), 162 deletions(-) diff --git a/base-hw/src/core/include/signal_root.h b/base-hw/src/core/include/signal_root.h index 01be1e25a..871f1f5d5 100644 --- a/base-hw/src/core/include/signal_root.h +++ b/base-hw/src/core/include/signal_root.h @@ -78,22 +78,6 @@ namespace Genode { size_t ram_quota = Arg_string::find_arg(args, "ram_quota").long_value(0); - - /* - * FIXME - * We check these assertions because space for initial SLAB - * blocks can be scaled pragmatically only via - * RECEIVERS_SLAB_BLOCK_SIZE and CONTEXTS_SLAB_BLOCK_SIZE - * (array size can't come from a function) - */ - if (Signal_session_component::RECEIVERS_SB_SIZE < - 32 * Kernel::signal_receiver_size() || - Signal_session_component::CONTEXTS_SB_SIZE < - 32 * Kernel::signal_context_size()) - { - PERR("Undersized SLAB blocks"); - throw Root::Exception(); - } return new (md_alloc()) Signal_session_component(md_alloc(), ram_quota); } diff --git a/base-hw/src/core/include/signal_session_component.h b/base-hw/src/core/include/signal_session_component.h index 1ba9a4271..4911a6aec 100644 --- a/base-hw/src/core/include/signal_session_component.h +++ b/base-hw/src/core/include/signal_session_component.h @@ -1,5 +1,5 @@ /* - * \brief Signal service on the HW-core + * \brief Server-sided implementation of a signal session * \author Martin stein * \date 2012-05-05 */ @@ -21,162 +21,200 @@ #include #include +/* core includes */ +#include +#include + namespace Genode { /** - * Provides the signal service + * Combines kernel data and core data of an object a signal session manages + * + * \param T type of the kernel data */ - class Signal_session_component : public Rpc_object - { - public: + template + class Signal_session_object; - enum { - /** - * Lastly Receiver::slab_size() was 112. Additionally we - * have to take in account, that the backing store might add - * its metadata and round up to next page size. So we choose - * 35 * 112 which mostly is save to end up in one page only. - */ - RECEIVERS_SB_SIZE = 3920, + typedef Signal_session_object + Signal_session_receiver; - /** - * Lastly Context::slab_size() size was 124. Additionally we - * have to take in account, that the backing store might add - * its metadata and round up to next page size. So we choose - * 32 * 124 which mostly is save to end up in one page only. - */ - CONTEXTS_SB_SIZE = 3968, - }; + typedef Signal_session_object + Signal_session_context; - private: + /** + * Traits that are used in signal session components + * + * FIXME: This class is merely necessary because GCC 4.7.2 appears to have + * a problem with using a static-constexpr method for the + * dimensioning of a member array within the same class. + */ + class Signal_session_traits; - /** - * Maps a signal-receiver name to related core and kernel resources - */ - class Receiver; - - /** - * Maps a signal-context name to related core and kernel resources - */ - class Context; - - typedef Object_pool Receiver_pool; - typedef Object_pool Context_pool; - - Allocator_guard _md_alloc; - Slab _receivers_slab; - Receiver_pool _receivers; - Slab _contexts_slab; - Context_pool _contexts; - char _initial_receivers_sb [RECEIVERS_SB_SIZE]; - char _initial_contexts_sb [CONTEXTS_SB_SIZE]; - - /** - * Destruct receiver 'r' - */ - void _destruct_receiver(Receiver * const r); - - /** - * Destruct context 'c' - */ - void _destruct_context(Context * const c); - - public: - - /** - * Constructor - * - * \param md Metadata allocator - * \param ram_quota Amount of RAM quota donated to this session - */ - Signal_session_component(Allocator * const md, - size_t const ram_quota); - - /** - * Destructor - */ - ~Signal_session_component(); - - /** - * Raise the quota of this session by 'q' - */ - void upgrade_ram_quota(size_t const q) { _md_alloc.upgrade(q); } - - /****************************** - ** Signal_session interface ** - ******************************/ - - Signal_receiver_capability alloc_receiver(); - - Signal_context_capability - alloc_context(Signal_receiver_capability, unsigned const); - - void free_receiver(Signal_receiver_capability); - - void free_context(Signal_context_capability); - }; + /** + * Server-sided implementation of a signal session + */ + class Signal_session_component; } -class Genode::Signal_session_component::Receiver : public Receiver_pool::Entry +template +class Genode::Signal_session_object +: + public Object_pool >::Entry { public: + typedef Object_pool > Pool; + /** * Constructor */ - Receiver(Untyped_capability cap) : Entry(cap) { } + Signal_session_object(Untyped_capability cap) : Pool::Entry(cap) { } /** - * Name of signal receiver + * Kernel name of the object */ - unsigned id() const { return Receiver_pool::Entry::cap().dst(); } + unsigned id() const { return Pool::Entry::cap().dst(); } /** - * Size of SLAB block occupied by resources and this resource info + * Size of the data starting at the base of this object */ - static size_t slab_size() + static constexpr size_t size() { - return sizeof(Receiver) + Kernel::signal_receiver_size(); + return sizeof(Signal_session_object) + sizeof(T); } /** - * Base of region donated to the kernel + * Base of the kernel donation associated with a specific SLAB address + * + * \param slab_addr SLAB address */ - static addr_t kernel_donation(void * const slab_addr) + static constexpr addr_t kernel_donation(void * const slab_addr) { - return ((addr_t)slab_addr + sizeof(Receiver)); + return (addr_t)slab_addr + sizeof(Signal_session_object); } }; -class Genode::Signal_session_component::Context : public Context_pool::Entry +class Genode::Signal_session_traits { + private: + + /** + * Return the raw size of a slab + */ + static constexpr size_t _slab_raw() { return get_page_size(); } + + /** + * Return the size of the static buffer for meta data per slab + */ + static constexpr size_t _slab_buffer() { return 128; } + + /** + * Return the size available for allocations per slab + */ + static constexpr size_t _slab_avail() { return _slab_raw() - _slab_buffer(); } + + /** + * Return the amount of allocatable slots per slab + * + * \param T object type of the slab + */ + template + static constexpr size_t _slab_slots() { return _slab_avail() / T::size(); } + + protected: + + /** + * Return the size of allocatable space per slab + * + * \param T object type of the slab + */ + template + static constexpr size_t _slab_size() { return _slab_slots() * T::size(); } +}; + +class Genode::Signal_session_component +: + public Rpc_object, + public Signal_session_traits +{ + private: + + typedef Signal_session_receiver Receiver; + typedef Signal_session_context Context; + typedef Signal_session_traits Traits; + + Allocator_guard _allocator; + Slab _receivers_slab; + Receiver::Pool _receivers; + Slab _contexts_slab; + Context::Pool _contexts; + + char _first_receivers_slab [Traits::_slab_size()]; + char _first_contexts_slab [Traits::_slab_size()]; + + /** + * Destruct receiver 'r' + */ + void _destruct_receiver(Receiver * const r); + + /** + * Destruct context 'c' + */ + void _destruct_context(Context * const c); + public: /** * Constructor + * + * \param allocator RAM allocator for meta data + * \param quota amount of RAM quota donated to this session */ - Context(Untyped_capability cap) : Entry(cap) { } + Signal_session_component(Allocator * const allocator, + size_t const quota) + : + _allocator(allocator, quota), + _receivers_slab(Receiver::size(), Traits::_slab_size(), + (Slab_block *)&_first_receivers_slab, &_allocator), + _contexts_slab(Context::size(), Traits::_slab_size(), + (Slab_block *)&_first_contexts_slab, &_allocator) + { } /** - * Name of signal context + * Destructor */ - unsigned id() const { return Context_pool::Entry::cap().dst(); } - - /** - * Size of SLAB block occupied by resources and this resource info - */ - static size_t slab_size() + ~Signal_session_component() { - return sizeof(Context) + Kernel::signal_context_size(); + while (1) { + Context * const c = _contexts.first_locked(); + if (!c) { break; } + _destruct_context(c); + } + while (1) { + Receiver * const r = _receivers.first_locked(); + if (!r) { break; } + _destruct_receiver(r); + } } /** - * Base of region donated to the kernel + * Raise the quota of this session by 'q' */ - static addr_t kernel_donation(void * const slab_addr) - { - return ((addr_t)slab_addr + sizeof(Context)); - } + void upgrade_ram_quota(size_t const q) { _allocator.upgrade(q); } + + + /****************************** + ** Signal_session interface ** + ******************************/ + + Signal_receiver_capability alloc_receiver(); + + Signal_context_capability + alloc_context(Signal_receiver_capability, unsigned const); + + void free_receiver(Signal_receiver_capability); + + void free_context(Signal_context_capability); }; -#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */ +#endif /* _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_ */ diff --git a/base-hw/src/core/signal_session_component.cc b/base-hw/src/core/signal_session_component.cc index bf9ddd117..038e4b11e 100644 --- a/base-hw/src/core/signal_session_component.cc +++ b/base-hw/src/core/signal_session_component.cc @@ -24,36 +24,11 @@ using namespace Genode; -Signal_session_component::Signal_session_component(Allocator * const md, - size_t const ram_quota) : - _md_alloc(md, ram_quota), - _receivers_slab(Receiver::slab_size(), RECEIVERS_SB_SIZE, - (Slab_block *)&_initial_receivers_sb, &_md_alloc), - _contexts_slab(Context::slab_size(), CONTEXTS_SB_SIZE, - (Slab_block *)&_initial_contexts_sb, &_md_alloc) -{ } - - -Signal_session_component::~Signal_session_component() -{ - while (1) { - Context * const c = _contexts.first_locked(); - if (!c) { break; } - _destruct_context(c); - } - while (1) { - Receiver * const r = _receivers.first_locked(); - if (!r) { break; } - _destruct_receiver(r); - } -} - - Signal_receiver_capability Signal_session_component::alloc_receiver() { /* allocate resources for receiver */ void * p; - if (!_receivers_slab.alloc(Receiver::slab_size(), &p)) { + if (!_receivers_slab.alloc(Receiver::size(), &p)) { PERR("failed to allocate signal-receiver resources"); throw Out_of_metadata(); } @@ -63,7 +38,7 @@ Signal_receiver_capability Signal_session_component::alloc_receiver() if (!id) { /* clean up */ - _receivers_slab.free(p, Receiver::slab_size()); + _receivers_slab.free(p, Receiver::size()); PERR("failed to create signal receiver"); throw Create_receiver_failed(); } @@ -87,7 +62,7 @@ void Signal_session_component::free_receiver(Signal_receiver_capability cap) } /* release resources */ _destruct_receiver(r); - _receivers_slab.free(r, Receiver::slab_size()); + _receivers_slab.free(r, Receiver::size()); } @@ -97,7 +72,7 @@ Signal_session_component::alloc_context(Signal_receiver_capability r, { /* allocate resources for context */ void * p; - if (!_contexts_slab.alloc(Context::slab_size(), &p)) { + if (!_contexts_slab.alloc(Context::size(), &p)) { PERR("failed to allocate signal-context resources"); throw Out_of_metadata(); } @@ -107,7 +82,7 @@ Signal_session_component::alloc_context(Signal_receiver_capability r, if (!id) { /* clean up */ - _contexts_slab.free(p, Context::slab_size()); + _contexts_slab.free(p, Context::size()); PERR("failed to create signal context"); throw Create_context_failed(); } @@ -130,7 +105,7 @@ void Signal_session_component::free_context(Signal_context_capability cap) } /* release resources */ _destruct_context(c); - _contexts_slab.free(c, Context::slab_size()); + _contexts_slab.free(c, Context::size()); } @@ -146,7 +121,7 @@ void Signal_session_component::_destruct_context(Context * const c) } /* release core resources */ _contexts.remove_locked(c); - c->~Context(); + c->~Signal_session_context(); } @@ -162,5 +137,5 @@ void Signal_session_component::_destruct_receiver(Receiver * const r) } /* release core resources */ _receivers.remove_locked(r); - r->~Receiver(); + r->~Signal_session_receiver(); }