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.
This commit is contained in:
Norman Feske 2017-01-25 21:31:32 +01:00
parent cd3a5852d6
commit 9adc6f1228
2 changed files with 64 additions and 6 deletions

View File

@ -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 <base/registry.h>
#include <base/service.h>
namespace Genode { template <typename...> class Static_parent_services; }
template <typename... SESSION_TYPES>
class Genode::Static_parent_services : public Registry<Registered<Parent_service> >
{
private:
template <typename...>
struct Service_recursive;
template <typename HEAD, typename... TAIL>
struct Service_recursive<HEAD, TAIL...>
{
Registered<Parent_service> service;
Service_recursive<TAIL...> tail;
Service_recursive(Registry<Registered<Parent_service> > &registry)
: service(registry, HEAD::service_name()), tail(registry) { }
};
template <typename LAST>
struct Service_recursive<LAST>
{
Registered<Parent_service> service;
Service_recursive(Registry<Registered<Parent_service> > &registry)
: service(registry, LAST::service_name()) { }
};
Service_recursive<SESSION_TYPES...> _service_recursive { *this };
};
#endif /* _INCLUDE__OS__STATIC_PARENT_SERVICES_H_ */

View File

@ -20,6 +20,7 @@
#include <init/child_policy.h>
#include <timer_session/connection.h>
#include <os/child_policy_dynamic_rom.h>
#include <os/static_parent_services.h>
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<Registered<Parent_service> > parent_services;
Static_parent_services<Ram_session, Pd_session, Cpu_session,
Rom_session, Log_session> 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_service>(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