From 9adc6f1228e00feef494fe34bd2e5609b8d47b4c Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 25 Jan 2017 21:31:32 +0100 Subject: [PATCH] os: compile-time-defined parent-service registry The new utility at 'os/static_parent_services.h' allows the creation of a registry of parent services at compile time and thereby eliminates the need for dynamic memory allocations whenever the set of services is known at compile time as is the case for most uses of 'Slave::Policy'. The commit showcases the utility in the bomb test. --- repos/os/include/os/static_parent_services.h | 61 ++++++++++++++++++++ repos/os/src/test/bomb/main.cc | 9 +-- 2 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 repos/os/include/os/static_parent_services.h diff --git a/repos/os/include/os/static_parent_services.h b/repos/os/include/os/static_parent_services.h new file mode 100644 index 0000000000..f77325b6c3 --- /dev/null +++ b/repos/os/include/os/static_parent_services.h @@ -0,0 +1,61 @@ +/* + * \brief Compile-time-defined parent-service registry + * \author Norman Feske + * \date 2017-01-23 + * + * Child-management utilities such as 'Slave::Policy' take a registry of + * permitted parent services as construction argument. As a special form of + * such a registry, a 'Static_parent_services' object is statically defined at + * compile time instead of populated during runtime. It thereby allows the + * creation of a parent-service registry without the need for dynamic memory + * allocations if the types of the registered services are known at compile + * time. + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__OS__STATIC_PARENT_SERVICES_H_ +#define _INCLUDE__OS__STATIC_PARENT_SERVICES_H_ + +#include +#include + +namespace Genode { template class Static_parent_services; } + + +template +class Genode::Static_parent_services : public Registry > +{ + private: + + template + struct Service_recursive; + + template + struct Service_recursive + { + Registered service; + Service_recursive tail; + + Service_recursive(Registry > ®istry) + : service(registry, HEAD::service_name()), tail(registry) { } + }; + + template + struct Service_recursive + { + Registered service; + + Service_recursive(Registry > ®istry) + : service(registry, LAST::service_name()) { } + }; + + Service_recursive _service_recursive { *this }; +}; + +#endif /* _INCLUDE__OS__STATIC_PARENT_SERVICES_H_ */ diff --git a/repos/os/src/test/bomb/main.cc b/repos/os/src/test/bomb/main.cc index eede700520..10b3c114c5 100644 --- a/repos/os/src/test/bomb/main.cc +++ b/repos/os/src/test/bomb/main.cc @@ -20,6 +20,7 @@ #include #include #include +#include using namespace Genode; @@ -170,9 +171,8 @@ struct Bomb Children child_registry; - /* names of services provided by the parent */ - const char *names[6] = { "RAM", "PD", "CPU", "ROM", "LOG", 0}; - Registry > parent_services; + Static_parent_services parent_services; void construct_children() { @@ -233,9 +233,6 @@ struct Bomb Bomb(Genode::Env &env) : env(env) { - for (unsigned i = 0; names[i]; i++) - new (heap) Registered(parent_services, names[i]); - /* * Don't ask parent for further resources if we ran out of memory. * Prevent us to block for resource upgrades caused by clients