2011-12-22 15:19:25 +00:00
|
|
|
/*
|
|
|
|
* \brief Parent interface
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2006-05-10
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 12:23:52 +00:00
|
|
|
* Copyright (C) 2006-2017 Genode Labs GmbH
|
2011-12-22 15:19:25 +00:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 12:23:52 +00:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _INCLUDE__PARENT__PARENT_H_
|
|
|
|
#define _INCLUDE__PARENT__PARENT_H_
|
|
|
|
|
|
|
|
#include <base/exception.h>
|
|
|
|
#include <base/rpc.h>
|
|
|
|
#include <base/rpc_args.h>
|
2012-10-10 11:54:46 +00:00
|
|
|
#include <base/thread.h>
|
2016-11-06 13:26:34 +00:00
|
|
|
#include <base/id_space.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
#include <session/capability.h>
|
|
|
|
#include <root/capability.h>
|
|
|
|
|
2016-11-06 13:26:34 +00:00
|
|
|
namespace Genode {
|
|
|
|
|
|
|
|
class Session_state;
|
|
|
|
class Parent;
|
|
|
|
}
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Genode::Parent
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Recursively announce inherited service interfaces
|
|
|
|
*
|
|
|
|
* At compile time, the 'ROOT' type is inspected for the presence
|
|
|
|
* of the 'Rpc_inherited_interface' type in the corresponding
|
|
|
|
* session interface. If present, the session type gets announced.
|
|
|
|
* This works recursively.
|
|
|
|
*/
|
|
|
|
template <typename ROOT>
|
|
|
|
void _announce_base(Capability<ROOT> const &, Meta::Bool_to_type<false> *) { }
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This overload gets selected if the ROOT interface corresponds to
|
|
|
|
* an inherited session type.
|
|
|
|
*/
|
|
|
|
template <typename ROOT>
|
|
|
|
inline void _announce_base(Capability<ROOT> const &, Meta::Bool_to_type<true> *);
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef Rpc_in_buffer<64> Service_name;
|
|
|
|
typedef Rpc_in_buffer<160> Session_args;
|
|
|
|
typedef Rpc_in_buffer<160> Upgrade_args;
|
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
struct Client : Interface { typedef Id_space<Client>::Id Id; };
|
|
|
|
struct Server : Interface { typedef Id_space<Server>::Id Id; };
|
2016-11-06 13:26:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Predefined session IDs corresponding to the environment sessions
|
|
|
|
* created by the parent at the component-construction time
|
|
|
|
*/
|
|
|
|
struct Env
|
|
|
|
{
|
2017-05-11 18:03:28 +00:00
|
|
|
static Client::Id pd() { return { 1 }; }
|
2016-11-06 13:26:34 +00:00
|
|
|
static Client::Id cpu() { return { 2 }; }
|
2017-05-11 18:03:28 +00:00
|
|
|
static Client::Id log() { return { 3 }; }
|
|
|
|
static Client::Id binary() { return { 4 }; }
|
|
|
|
static Client::Id linker() { return { 5 }; }
|
|
|
|
static Client::Id last() { return { 5 }; }
|
2016-11-06 13:26:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* True if session ID refers to an environment session
|
|
|
|
*/
|
|
|
|
static bool session_id(Client::Id id) {
|
2017-05-11 18:03:28 +00:00
|
|
|
return id.value >= 1 && id.value <= last().value; }
|
2016-11-06 13:26:34 +00:00
|
|
|
};
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
/**
|
|
|
|
* Use 'String' instead of 'Rpc_in_buffer' because 'Resource_args'
|
|
|
|
* is used as both in and out parameter.
|
|
|
|
*/
|
|
|
|
typedef String<160> Resource_args;
|
|
|
|
|
|
|
|
virtual ~Parent() { }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tell parent to exit the program
|
|
|
|
*/
|
|
|
|
virtual void exit(int exit_value) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Announce service to the parent
|
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
virtual void announce(Service_name const &service_name) = 0;
|
2015-03-04 20:12:14 +00:00
|
|
|
|
2016-11-06 13:26:34 +00:00
|
|
|
/**
|
|
|
|
* Emulation of the original synchronous root interface
|
|
|
|
*
|
2019-05-22 13:37:45 +00:00
|
|
|
* This method transparently spawns a proxy "root" entrypoint that
|
2016-11-06 13:26:34 +00:00
|
|
|
* dispatches asynchronous session-management operations (as issued
|
|
|
|
* by the parent) to the local root interfaces via component-local
|
|
|
|
* RPC calls.
|
|
|
|
*
|
2019-05-22 13:37:45 +00:00
|
|
|
* The method solely exists for API compatibility.
|
2016-11-06 13:26:34 +00:00
|
|
|
*/
|
|
|
|
static void announce(Service_name const &service_name,
|
|
|
|
Root_capability service_root);
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Announce service to the parent
|
|
|
|
*
|
|
|
|
* \param service_root root capability
|
|
|
|
*
|
|
|
|
* The type of the specified 'service_root' capability match with
|
|
|
|
* an interface that provides a 'Session_type' type (i.e., a
|
|
|
|
* 'Typed_root' interface). This 'Session_type' is expected to
|
2015-03-20 16:50:41 +00:00
|
|
|
* host a class function called 'service_name' returning the
|
2015-03-04 20:12:14 +00:00
|
|
|
* name of the provided interface as null-terminated string.
|
|
|
|
*/
|
|
|
|
template <typename ROOT_INTERFACE>
|
|
|
|
void announce(Capability<ROOT_INTERFACE> const &service_root)
|
|
|
|
{
|
|
|
|
typedef typename ROOT_INTERFACE::Session_type Session;
|
|
|
|
announce(Session::service_name(), service_root);
|
2012-10-29 11:18:24 +00:00
|
|
|
|
|
|
|
/*
|
2015-03-04 20:12:14 +00:00
|
|
|
* Announce inherited session types
|
2012-10-29 11:18:24 +00:00
|
|
|
*
|
2015-03-04 20:12:14 +00:00
|
|
|
* Select the overload based on the presence of the type
|
|
|
|
* 'Rpc_inherited_interface' within the session type.
|
2013-09-19 18:39:35 +00:00
|
|
|
*/
|
2015-03-04 20:12:14 +00:00
|
|
|
_announce_base(service_root,
|
|
|
|
(Meta::Bool_to_type<Rpc_interface_is_inherited<Session>::VALUE> *)0);
|
|
|
|
}
|
|
|
|
|
2016-11-06 13:26:34 +00:00
|
|
|
/**
|
|
|
|
* Register signal handler for session notifications
|
|
|
|
*/
|
|
|
|
virtual void session_sigh(Signal_context_capability) = 0;
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
/**
|
|
|
|
* Create session to a service
|
|
|
|
*
|
2016-11-06 13:26:34 +00:00
|
|
|
* \param id client-side ID of new session
|
2015-03-04 20:12:14 +00:00
|
|
|
* \param service_name name of the requested interface
|
|
|
|
* \param args session constructor arguments
|
|
|
|
* \param affinity preferred CPU affinity for the session
|
|
|
|
*
|
2017-05-08 12:32:03 +00:00
|
|
|
* \throw Service_denied parent denies session request
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
* \throw Insufficient_cap_quota donated cap quota does not suffice
|
2017-05-08 12:32:03 +00:00
|
|
|
* \throw Insufficient_ram_quota donated RAM quota does not suffice
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
* \throw Out_of_caps session CAP quota exceeds our resources
|
2017-05-08 12:32:03 +00:00
|
|
|
* \throw Out_of_ram session RAM quota exceeds our resources
|
2015-03-04 20:12:14 +00:00
|
|
|
*
|
2017-05-24 12:41:19 +00:00
|
|
|
* \return session capability if the new session is immediately
|
2016-11-06 13:26:34 +00:00
|
|
|
* available, or an invalid capability
|
|
|
|
*
|
|
|
|
* If the returned capability is invalid, the request is pending at the
|
|
|
|
* server. The parent delivers a signal to the handler as registered
|
|
|
|
* via 'session_sigh' once the server responded to the request. Now the
|
|
|
|
* session capability can be picked up by calling 'session_cap'.
|
2015-03-04 20:12:14 +00:00
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
virtual Session_capability session(Client::Id id,
|
|
|
|
Service_name const &service_name,
|
2015-03-04 20:12:14 +00:00
|
|
|
Session_args const &args,
|
|
|
|
Affinity const &affinity = Affinity()) = 0;
|
|
|
|
|
|
|
|
/**
|
2016-11-06 13:26:34 +00:00
|
|
|
* Request session capability
|
2015-03-04 20:12:14 +00:00
|
|
|
*
|
2016-11-06 13:26:34 +00:00
|
|
|
* \throw Service_denied
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
* \throw Insufficient_cap_quota
|
2017-05-08 12:32:03 +00:00
|
|
|
* \throw Insufficient_ram_quota
|
2015-03-04 20:12:14 +00:00
|
|
|
*
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
* See 'session' for more documentation.
|
|
|
|
*
|
2016-11-06 13:26:34 +00:00
|
|
|
* In the exception case, the parent implicitly closes the session.
|
2015-03-04 20:12:14 +00:00
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
virtual Session_capability session_cap(Client::Id id) = 0;
|
|
|
|
|
|
|
|
enum Upgrade_result { UPGRADE_DONE, UPGRADE_PENDING };
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Transfer our quota to the server that provides the specified session
|
|
|
|
*
|
2016-11-06 13:26:34 +00:00
|
|
|
* \param id ID of recipient session
|
2015-03-04 20:12:14 +00:00
|
|
|
* \param args description of the amount of quota to transfer
|
|
|
|
*
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
* \throw Out_of_caps
|
2017-05-08 12:32:03 +00:00
|
|
|
* \throw Out_of_ram
|
2015-03-04 20:12:14 +00:00
|
|
|
*
|
|
|
|
* The 'args' argument has the same principle format as the 'args'
|
2015-03-20 16:50:41 +00:00
|
|
|
* argument of the 'session' operation.
|
2015-03-04 20:12:14 +00:00
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
virtual Upgrade_result upgrade(Client::Id to_session,
|
|
|
|
Upgrade_args const &args) = 0;
|
|
|
|
|
2020-01-02 19:23:03 +00:00
|
|
|
enum [[nodiscard]] Close_result { CLOSE_DONE, CLOSE_PENDING };
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Close session
|
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
virtual Close_result close(Client::Id) = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Interface for providing services
|
|
|
|
*/
|
|
|
|
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
enum Session_response { SESSION_OK, SESSION_CLOSED, SERVICE_DENIED,
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
INSUFFICIENT_RAM_QUOTA, INSUFFICIENT_CAP_QUOTA };
|
2016-11-06 13:26:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set state of a session provided by the child service
|
|
|
|
*/
|
|
|
|
virtual void session_response(Server::Id, Session_response) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Deliver capability for a new session provided by the child service
|
|
|
|
*/
|
|
|
|
virtual void deliver_session_cap(Server::Id, Session_capability) = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Dynamic resource balancing
|
|
|
|
*/
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Provide thread_cap of main thread
|
|
|
|
*/
|
|
|
|
virtual Thread_capability main_thread_cap() const = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Register signal handler for resource notifications
|
|
|
|
*/
|
|
|
|
virtual void resource_avail_sigh(Signal_context_capability sigh) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Request additional resources
|
|
|
|
*
|
2017-05-24 12:41:19 +00:00
|
|
|
* By invoking this method, a component is able to inform its
|
2015-03-04 20:12:14 +00:00
|
|
|
* parent about the need for additional resources. The argument
|
|
|
|
* string contains a resource description in the same format as
|
|
|
|
* used for session-construction arguments. In particular, for
|
|
|
|
* requesting additional RAM quota, the argument looks like
|
|
|
|
* "ram_quota=<amount>" where 'amount' is the amount of additional
|
|
|
|
* resources expected from the parent. If the parent complies with
|
|
|
|
* the request, it submits a resource-available signal to the
|
|
|
|
* handler registered via 'resource_avail_sigh()'. On the reception
|
2017-05-24 12:41:19 +00:00
|
|
|
* of such a signal, the component can re-evaluate its resource quota
|
2015-03-04 20:12:14 +00:00
|
|
|
* and resume execution.
|
|
|
|
*/
|
|
|
|
virtual void resource_request(Resource_args const &args) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Register signal handler for resource yield notifications
|
|
|
|
*
|
2017-05-24 12:41:19 +00:00
|
|
|
* Using the yield signal, the parent is able to inform the component
|
2015-03-04 20:12:14 +00:00
|
|
|
* about its wish to regain resources.
|
|
|
|
*/
|
|
|
|
virtual void yield_sigh(Signal_context_capability sigh) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Obtain information about the amount of resources to free
|
|
|
|
*
|
2015-03-20 16:50:41 +00:00
|
|
|
* The amount of resources returned by this method is the
|
2015-03-04 20:12:14 +00:00
|
|
|
* goal set by the parent. It is not commanded but merely meant
|
2017-05-24 12:41:19 +00:00
|
|
|
* as a friendly beg to cooperate. The component is not obligated
|
|
|
|
* to comply. If the component decides to take action to free
|
2015-03-04 20:12:14 +00:00
|
|
|
* resources, it can inform its parent about the availability
|
|
|
|
* of freed up resources by calling 'yield_response()'.
|
|
|
|
*/
|
|
|
|
virtual Resource_args yield_request() = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Notify the parent about a response to a yield request
|
|
|
|
*/
|
|
|
|
virtual void yield_response() = 0;
|
|
|
|
|
2018-11-14 15:19:30 +00:00
|
|
|
/*
|
|
|
|
* Health monitoring
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Register heartbeat handler
|
|
|
|
*
|
|
|
|
* The parent may issue heartbeat signals to the child at any time
|
|
|
|
* and expects a call of the 'heartbeat_response' RPC function as
|
|
|
|
* response. When oberving the RPC call, the parent infers that the
|
|
|
|
* child is still able to respond to external events.
|
|
|
|
*/
|
|
|
|
virtual void heartbeat_sigh(Signal_context_capability sigh) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Deliver response to a heartbeat signal
|
|
|
|
*/
|
|
|
|
virtual void heartbeat_response() = 0;
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/*********************
|
|
|
|
** RPC declaration **
|
|
|
|
*********************/
|
|
|
|
|
|
|
|
GENODE_RPC(Rpc_exit, void, exit, int);
|
|
|
|
GENODE_RPC(Rpc_announce, void, announce,
|
2016-11-06 13:26:34 +00:00
|
|
|
Service_name const &);
|
|
|
|
GENODE_RPC(Rpc_session_sigh, void, session_sigh, Signal_context_capability);
|
2015-03-04 20:12:14 +00:00
|
|
|
GENODE_RPC_THROW(Rpc_session, Session_capability, session,
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
GENODE_TYPE_LIST(Service_denied, Out_of_caps,
|
|
|
|
Out_of_ram, Insufficient_cap_quota,
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
Insufficient_ram_quota),
|
2016-11-06 13:26:34 +00:00
|
|
|
Client::Id, Service_name const &, Session_args const &,
|
|
|
|
Affinity const &);
|
|
|
|
GENODE_RPC_THROW(Rpc_session_cap, Session_capability, session_cap,
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
GENODE_TYPE_LIST(Service_denied, Insufficient_cap_quota,
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
Insufficient_ram_quota),
|
2016-11-06 13:26:34 +00:00
|
|
|
Client::Id);
|
|
|
|
GENODE_RPC_THROW(Rpc_upgrade, Upgrade_result, upgrade,
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
|
2016-11-06 13:26:34 +00:00
|
|
|
Client::Id, Upgrade_args const &);
|
|
|
|
GENODE_RPC(Rpc_close, Close_result, close, Client::Id);
|
|
|
|
GENODE_RPC(Rpc_session_response, void, session_response,
|
|
|
|
Server::Id, Session_response);
|
|
|
|
GENODE_RPC(Rpc_deliver_session_cap, void, deliver_session_cap,
|
|
|
|
Server::Id, Session_capability);
|
2015-03-04 20:12:14 +00:00
|
|
|
GENODE_RPC(Rpc_main_thread, Thread_capability, main_thread_cap);
|
|
|
|
GENODE_RPC(Rpc_resource_avail_sigh, void, resource_avail_sigh,
|
|
|
|
Signal_context_capability);
|
|
|
|
GENODE_RPC(Rpc_resource_request, void, resource_request,
|
|
|
|
Resource_args const &);
|
|
|
|
GENODE_RPC(Rpc_yield_sigh, void, yield_sigh, Signal_context_capability);
|
|
|
|
GENODE_RPC(Rpc_yield_request, Resource_args, yield_request);
|
|
|
|
GENODE_RPC(Rpc_yield_response, void, yield_response);
|
2018-11-14 15:19:30 +00:00
|
|
|
GENODE_RPC(Rpc_heartbeat_sigh, void, heartbeat_sigh, Signal_context_capability);
|
|
|
|
GENODE_RPC(Rpc_heartbeat_response, void, heartbeat_response);
|
2015-03-04 20:12:14 +00:00
|
|
|
|
2016-11-06 13:26:34 +00:00
|
|
|
GENODE_RPC_INTERFACE(Rpc_exit, Rpc_announce, Rpc_session_sigh,
|
|
|
|
Rpc_session, Rpc_session_cap, Rpc_upgrade,
|
|
|
|
Rpc_close, Rpc_session_response, Rpc_main_thread,
|
|
|
|
Rpc_deliver_session_cap, Rpc_resource_avail_sigh,
|
|
|
|
Rpc_resource_request, Rpc_yield_sigh,
|
2018-11-14 15:19:30 +00:00
|
|
|
Rpc_yield_request, Rpc_yield_response,
|
|
|
|
Rpc_heartbeat_sigh, Rpc_heartbeat_response);
|
2015-03-04 20:12:14 +00:00
|
|
|
};
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2012-10-29 11:18:24 +00:00
|
|
|
|
|
|
|
template <typename ROOT_INTERFACE>
|
|
|
|
void
|
|
|
|
Genode::Parent::_announce_base(Genode::Capability<ROOT_INTERFACE> const &service_root,
|
|
|
|
Genode::Meta::Bool_to_type<true> *)
|
|
|
|
{
|
|
|
|
/* shortcut for inherited session type */
|
|
|
|
typedef typename ROOT_INTERFACE::Session_type::Rpc_inherited_interface
|
|
|
|
Session_type_inherited;
|
|
|
|
|
|
|
|
/* shortcut for root interface type matching the inherited session type */
|
|
|
|
typedef Typed_root<Session_type_inherited> Root_inherited;
|
|
|
|
|
|
|
|
/* convert root capability to match the inherited session type */
|
|
|
|
Capability<Root> root = service_root;
|
|
|
|
Capability<Root_inherited> root_inherited = static_cap_cast<Root_inherited>(root);
|
|
|
|
|
|
|
|
/* announce inherited service type */
|
|
|
|
announce(Session_type_inherited::service_name(), root_inherited);
|
|
|
|
|
|
|
|
/* recursively announce further inherited session types */
|
|
|
|
_announce_base(root_inherited,
|
|
|
|
(Meta::Bool_to_type<Rpc_interface_is_inherited<Session_type_inherited>::VALUE> *)0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
#endif /* _INCLUDE__PARENT__PARENT_H_ */
|