2011-12-22 15:19:25 +00:00
|
|
|
/*
|
|
|
|
* \brief Child creation framework
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2006-07-22
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
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__BASE__CHILD_H_
|
|
|
|
#define _INCLUDE__BASE__CHILD_H_
|
|
|
|
|
|
|
|
#include <base/rpc_server.h>
|
|
|
|
#include <base/heap.h>
|
|
|
|
#include <base/service.h>
|
|
|
|
#include <base/lock.h>
|
2016-11-06 13:26:34 +00:00
|
|
|
#include <base/local_connection.h>
|
2017-05-07 23:33:40 +00:00
|
|
|
#include <base/quota_guard.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
#include <util/arg_string.h>
|
2016-04-27 14:04:58 +00:00
|
|
|
#include <region_map/client.h>
|
2016-11-06 13:26:34 +00:00
|
|
|
#include <pd_session/connection.h>
|
|
|
|
#include <cpu_session/connection.h>
|
|
|
|
#include <log_session/connection.h>
|
|
|
|
#include <rom_session/connection.h>
|
2017-05-11 18:03:28 +00:00
|
|
|
#include <ram_session/capability.h>
|
2016-04-27 14:04:58 +00:00
|
|
|
#include <parent/capability.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
namespace Genode {
|
2015-03-04 20:12:14 +00:00
|
|
|
struct Child_policy;
|
|
|
|
struct Child;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Child policy interface
|
|
|
|
*
|
|
|
|
* A child-policy object is an argument to a 'Child'. It is responsible for
|
|
|
|
* taking policy decisions regarding the parent interface. Most importantly,
|
|
|
|
* it defines how session requests are resolved and how session arguments
|
|
|
|
* are passed to servers when creating sessions.
|
|
|
|
*/
|
|
|
|
struct Genode::Child_policy
|
|
|
|
{
|
2016-11-06 13:26:34 +00:00
|
|
|
typedef String<64> Name;
|
|
|
|
typedef String<64> Binary_name;
|
|
|
|
typedef String<64> Linker_name;
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
virtual ~Child_policy() { }
|
|
|
|
|
|
|
|
/**
|
2016-11-06 13:26:34 +00:00
|
|
|
* Name of the child used as the child's label prefix
|
|
|
|
*/
|
|
|
|
virtual Name name() const = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ROM module name of the binary to start
|
2015-03-04 20:12:14 +00:00
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
virtual Binary_name binary_name() const { return name(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ROM module name of the dynamic linker
|
|
|
|
*/
|
|
|
|
virtual Linker_name linker_name() const { return "ld.lib.so"; }
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine service to provide a session request
|
|
|
|
*
|
2016-11-06 13:26:34 +00:00
|
|
|
* \return service to be contacted for the new session
|
2017-02-14 16:38:09 +00:00
|
|
|
* \deprecated
|
2016-11-06 13:26:34 +00:00
|
|
|
*
|
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
|
|
|
* \throw Service_denied
|
2015-03-04 20:12:14 +00:00
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
virtual Service &resolve_session_request(Service::Name const &,
|
2017-02-14 16:38:09 +00:00
|
|
|
Session_state::Args const &)
|
|
|
|
{
|
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
|
|
|
throw Service_denied();
|
2017-02-14 16:38:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Routing destination of a session request
|
|
|
|
*/
|
|
|
|
struct Route
|
|
|
|
{
|
|
|
|
Service &service;
|
2017-05-08 17:45:47 +00:00
|
|
|
Session::Label const label;
|
|
|
|
Session::Diag const diag;
|
2017-02-14 16:38:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine service and server-side label for a given session request
|
|
|
|
*
|
|
|
|
* \return routing and policy-selection information for the session
|
|
|
|
*
|
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
|
|
|
* \throw Service_denied
|
2017-02-14 16:38:09 +00:00
|
|
|
*/
|
|
|
|
virtual Route resolve_session_request(Service::Name const &,
|
|
|
|
Session_label const &)
|
|
|
|
{
|
|
|
|
/* \deprecated make pure virtual once the old version is gone */
|
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
|
|
|
throw Service_denied();
|
2017-02-14 16:38:09 +00:00
|
|
|
}
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Apply transformations to session arguments
|
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
virtual void filter_session_args(Service::Name const &,
|
2015-03-04 20:12:14 +00:00
|
|
|
char * /*args*/, size_t /*args_len*/) { }
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
/**
|
2015-03-04 20:12:14 +00:00
|
|
|
* Register a service provided by the child
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
virtual void announce_service(Service::Name const &) { }
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Apply session affinity policy
|
|
|
|
*
|
|
|
|
* \param affinity affinity passed along with a session request
|
|
|
|
* \return affinity subordinated to the child policy
|
|
|
|
*/
|
|
|
|
virtual Affinity filter_session_affinity(Affinity const &affinity)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2015-03-04 20:12:14 +00:00
|
|
|
return affinity;
|
|
|
|
}
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
/**
|
|
|
|
* Exit child
|
|
|
|
*/
|
|
|
|
virtual void exit(int exit_value)
|
|
|
|
{
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
log("child \"", name(), "\" exited with exit value ", exit_value);
|
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
|
|
|
/**
|
|
|
|
* Reference PD session
|
|
|
|
*
|
|
|
|
* The PD session returned by this method is used for session cap-quota
|
2017-05-11 18:03:28 +00:00
|
|
|
* and RAM-quota transfers.
|
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
|
|
|
*/
|
|
|
|
virtual Pd_session &ref_pd() = 0;
|
|
|
|
virtual Pd_session_capability ref_pd_cap() const = 0;
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
/**
|
|
|
|
* Respond to the release of resources by the child
|
|
|
|
*
|
2015-03-20 16:50:41 +00:00
|
|
|
* This method is called when the child confirms the release of
|
2015-03-04 20:12:14 +00:00
|
|
|
* resources in response to a yield request.
|
|
|
|
*/
|
|
|
|
virtual void yield_response() { }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Take action on additional resource needs by the child
|
|
|
|
*/
|
|
|
|
virtual void resource_request(Parent::Resource_args const &) { }
|
2016-11-06 13:26:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize the child's CPU session
|
|
|
|
*
|
|
|
|
* The function may install an exception signal handler or assign CPU quota
|
|
|
|
* to the child.
|
|
|
|
*/
|
|
|
|
virtual void init(Cpu_session &, Capability<Cpu_session>) { }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize the child's PD session
|
|
|
|
*
|
2017-05-11 18:03:28 +00:00
|
|
|
* The function must define the child's reference account and transfer
|
|
|
|
* the child's initial RAM and capability quotas. It may also install a
|
|
|
|
* region-map fault handler for the child's address space
|
|
|
|
* ('Pd_session::address_space');.
|
2016-11-06 13:26:34 +00:00
|
|
|
*/
|
|
|
|
virtual void init(Pd_session &, Capability<Pd_session>) { }
|
|
|
|
|
|
|
|
class Nonexistent_id_space : Exception { };
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ID space for sessions provided by the child
|
|
|
|
*
|
|
|
|
* \throw Nonexistent_id_space
|
|
|
|
*/
|
|
|
|
virtual Id_space<Parent::Server> &server_id_space() { throw Nonexistent_id_space(); }
|
|
|
|
|
2017-02-17 14:25:52 +00:00
|
|
|
/**
|
|
|
|
* Notification hook invoked each time a session state is modified
|
|
|
|
*/
|
|
|
|
virtual void session_state_changed() { }
|
|
|
|
|
base: remove Child::heap
This patch improves the accounting for the backing store of
session-state meta data. Originally, the session state used to be
allocated by a child-local heap partition fed from the child's RAM
session. However, whereas this approach was somehow practical from a
runtime's (parent's) point of view, the child component could not count
on the quota in its own RAM session. I.e., if the Child::heap grew at
the parent side, the child's RAM session would magically diminish. This
caused two problems. First, it violates assumptions of components like
init that carefully manage their RAM resources (and giving most of them
away their children). Second, if a child transfers most of its RAM
session quota to another RAM session (like init does), the child's RAM
session may actually not allow the parent's heap to grow, which is a
very difficult error condition to deal with.
In the new version, there is no Child::heap anymore. Instead, session
states are allocated from the runtime's RAM session. In order to let
children pay for these costs, the parent withdraws the local session
costs from the session quota donated from the child when the child
initiates a new session. Hence, in principle, all components on the
route of the session request take a small bite from the session quota to
pay for their local book keeping
Consequently, the session quota that ends up at the server may become
depleted more or less, depending on the route. In the case where the
remaining quota is insufficient for the server, the server responds with
'QUOTA_EXCEEDED'. Since this behavior must generally be expected, this
patch equips the client-side 'Env::session' implementation with the
ability to re-issue session requests with successively growing quota
donations.
For several of core's services (ROM, IO_MEM, IRQ), the default session
quota has now increased by 2 KiB, which should suffice for session
requests to up to 3 hops as is the common case for most run scripts. For
longer routes, the retry mechanism as described above comes into effect.
For the time being, we give a warning whenever the server-side quota
check triggers the retry mechanism. The warning may eventually be
removed at a later stage.
2017-02-19 09:31:50 +00:00
|
|
|
/**
|
|
|
|
* Granularity of allocating the backing store for session meta data
|
|
|
|
*
|
2017-05-11 18:03:28 +00:00
|
|
|
* Session meta data is allocated from 'ref_pd'. The first batch of
|
base: remove Child::heap
This patch improves the accounting for the backing store of
session-state meta data. Originally, the session state used to be
allocated by a child-local heap partition fed from the child's RAM
session. However, whereas this approach was somehow practical from a
runtime's (parent's) point of view, the child component could not count
on the quota in its own RAM session. I.e., if the Child::heap grew at
the parent side, the child's RAM session would magically diminish. This
caused two problems. First, it violates assumptions of components like
init that carefully manage their RAM resources (and giving most of them
away their children). Second, if a child transfers most of its RAM
session quota to another RAM session (like init does), the child's RAM
session may actually not allow the parent's heap to grow, which is a
very difficult error condition to deal with.
In the new version, there is no Child::heap anymore. Instead, session
states are allocated from the runtime's RAM session. In order to let
children pay for these costs, the parent withdraws the local session
costs from the session quota donated from the child when the child
initiates a new session. Hence, in principle, all components on the
route of the session request take a small bite from the session quota to
pay for their local book keeping
Consequently, the session quota that ends up at the server may become
depleted more or less, depending on the route. In the case where the
remaining quota is insufficient for the server, the server responds with
'QUOTA_EXCEEDED'. Since this behavior must generally be expected, this
patch equips the client-side 'Env::session' implementation with the
ability to re-issue session requests with successively growing quota
donations.
For several of core's services (ROM, IO_MEM, IRQ), the default session
quota has now increased by 2 KiB, which should suffice for session
requests to up to 3 hops as is the common case for most run scripts. For
longer routes, the retry mechanism as described above comes into effect.
For the time being, we give a warning whenever the server-side quota
check triggers the retry mechanism. The warning may eventually be
removed at a later stage.
2017-02-19 09:31:50 +00:00
|
|
|
* session-state objects is allocated at child-construction time.
|
|
|
|
*/
|
|
|
|
virtual size_t session_alloc_batch_size() const { return 16; }
|
|
|
|
|
2017-02-19 20:40:52 +00:00
|
|
|
/**
|
|
|
|
* Return true to create the environment sessions at child construction
|
|
|
|
*
|
|
|
|
* By returning 'false', it is possible to create 'Child' objects without
|
|
|
|
* routing of their environment sessions at construction time. Once the
|
|
|
|
* routing information is available, the child's environment sessions
|
|
|
|
* must be manually initiated by calling 'Child::initiate_env_sessions()'.
|
|
|
|
*/
|
|
|
|
virtual bool initiate_env_sessions() const { return true; }
|
|
|
|
|
2016-11-06 13:26:34 +00:00
|
|
|
/**
|
|
|
|
* Return region map for the child's address space
|
|
|
|
*
|
|
|
|
* \param pd the child's PD session capability
|
|
|
|
*
|
|
|
|
* By default, the function returns a 'nullptr'. In this case, the 'Child'
|
|
|
|
* interacts with the address space of the child's PD session via RPC calls
|
|
|
|
* to the 'Pd_session::address_space'.
|
|
|
|
*
|
|
|
|
* By overriding the default, those RPC calls can be omitted, which is
|
|
|
|
* useful if the child's PD session (including the PD's address space) is
|
|
|
|
* virtualized by the parent. If the virtual PD session is served by the
|
|
|
|
* same entrypoint as the child's parent interface, an RPC call to 'pd'
|
|
|
|
* would otherwise produce a deadlock.
|
|
|
|
*/
|
|
|
|
virtual Region_map *address_space(Pd_session &) { return nullptr; }
|
2018-07-04 16:48:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if ELF loading should be inhibited
|
|
|
|
*/
|
|
|
|
virtual bool forked() const { return false; }
|
2015-03-04 20:12:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implementation of the parent interface that supports resource trading
|
|
|
|
*
|
|
|
|
* There are three possible cases of how a session can be provided to
|
2015-03-20 16:50:41 +00:00
|
|
|
* a child: The service is implemented locally, the session was obtained by
|
|
|
|
* asking our parent, or the session is provided by one of our children.
|
2015-03-04 20:12:14 +00:00
|
|
|
*
|
|
|
|
* These types must be differentiated for the quota management when a child
|
2015-03-20 16:50:41 +00:00
|
|
|
* issues the closing of a session or transfers quota via our parent
|
2015-03-04 20:12:14 +00:00
|
|
|
* interface.
|
|
|
|
*
|
|
|
|
* If we close a session to a local service, we transfer the session quota
|
|
|
|
* from our own account to the client.
|
|
|
|
*
|
|
|
|
* If we close a parent session, we receive the session quota on our own
|
|
|
|
* account and must transfer this amount to the session-closing child.
|
|
|
|
*
|
|
|
|
* If we close a session provided by a server child, we close the session
|
2015-03-20 16:50:41 +00:00
|
|
|
* at the server, transfer the session quota from the server's RAM session
|
2015-03-04 20:12:14 +00:00
|
|
|
* to our account, and subsequently transfer the same amount from our
|
|
|
|
* account to the client.
|
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
class Genode::Child : protected Rpc_object<Parent>,
|
|
|
|
Session_state::Ready_callback,
|
|
|
|
Session_state::Closed_callback
|
2015-03-04 20:12:14 +00:00
|
|
|
{
|
2016-11-06 13:26:34 +00:00
|
|
|
private:
|
2016-05-10 16:05:38 +00:00
|
|
|
|
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 Initial_thread_base : Interface
|
2016-05-10 16:05:38 +00:00
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Start execution at specified instruction pointer
|
|
|
|
*/
|
|
|
|
virtual void start(addr_t ip) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return capability of the initial thread
|
|
|
|
*/
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
virtual Capability<Cpu_thread> cap() const = 0;
|
2016-05-10 16:05:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Initial_thread : Initial_thread_base
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
|
|
|
Cpu_session &_cpu;
|
|
|
|
Thread_capability _cap;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef Cpu_session::Name Name;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
* \throw Cpu_session::Thread_creation_failed
|
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
|
|
|
* \throw Out_of_ram
|
|
|
|
* \throw Out_of_caps
|
2016-05-10 16:05:38 +00:00
|
|
|
*/
|
|
|
|
Initial_thread(Cpu_session &, Pd_session_capability, Name const &);
|
|
|
|
~Initial_thread();
|
|
|
|
|
|
|
|
void start(addr_t) override;
|
|
|
|
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
Capability<Cpu_thread> cap() const { return _cap; }
|
2016-05-10 16:05:38 +00:00
|
|
|
};
|
|
|
|
|
2016-11-06 13:26:34 +00:00
|
|
|
/* child policy */
|
|
|
|
Child_policy &_policy;
|
2015-03-04 20:12:14 +00:00
|
|
|
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
/* print error message with the child's name prepended */
|
|
|
|
template <typename... ARGS>
|
|
|
|
void _error(ARGS &&... args) { error(_policy.name(), ": ", args...); }
|
2016-11-06 13:26:34 +00:00
|
|
|
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
Region_map &_local_rm;
|
2016-11-06 13:26:34 +00:00
|
|
|
|
2017-05-12 23:03:59 +00:00
|
|
|
Capability_guard _parent_cap_guard;
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/* signal handlers registered by the child */
|
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
|
|
|
Signal_context_capability _resource_avail_sigh { };
|
|
|
|
Signal_context_capability _yield_sigh { };
|
|
|
|
Signal_context_capability _session_sigh { };
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/* arguments fetched by the child in response to a yield signal */
|
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
|
|
|
Lock _yield_request_lock { };
|
|
|
|
Resource_args _yield_request_args { };
|
2015-03-04 20:12:14 +00:00
|
|
|
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
/* sessions opened by the child */
|
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
|
|
|
Id_space<Client> _id_space { };
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
|
base: remove Child::heap
This patch improves the accounting for the backing store of
session-state meta data. Originally, the session state used to be
allocated by a child-local heap partition fed from the child's RAM
session. However, whereas this approach was somehow practical from a
runtime's (parent's) point of view, the child component could not count
on the quota in its own RAM session. I.e., if the Child::heap grew at
the parent side, the child's RAM session would magically diminish. This
caused two problems. First, it violates assumptions of components like
init that carefully manage their RAM resources (and giving most of them
away their children). Second, if a child transfers most of its RAM
session quota to another RAM session (like init does), the child's RAM
session may actually not allow the parent's heap to grow, which is a
very difficult error condition to deal with.
In the new version, there is no Child::heap anymore. Instead, session
states are allocated from the runtime's RAM session. In order to let
children pay for these costs, the parent withdraws the local session
costs from the session quota donated from the child when the child
initiates a new session. Hence, in principle, all components on the
route of the session request take a small bite from the session quota to
pay for their local book keeping
Consequently, the session quota that ends up at the server may become
depleted more or less, depending on the route. In the case where the
remaining quota is insufficient for the server, the server responds with
'QUOTA_EXCEEDED'. Since this behavior must generally be expected, this
patch equips the client-side 'Env::session' implementation with the
ability to re-issue session requests with successively growing quota
donations.
For several of core's services (ROM, IO_MEM, IRQ), the default session
quota has now increased by 2 KiB, which should suffice for session
requests to up to 3 hops as is the common case for most run scripts. For
longer routes, the retry mechanism as described above comes into effect.
For the time being, we give a warning whenever the server-side quota
check triggers the retry mechanism. The warning may eventually be
removed at a later stage.
2017-02-19 09:31:50 +00:00
|
|
|
/* allocator used for dynamically created session state objects */
|
2017-05-11 18:03:28 +00:00
|
|
|
Sliced_heap _session_md_alloc { _policy.ref_pd(), _local_rm };
|
base: remove Child::heap
This patch improves the accounting for the backing store of
session-state meta data. Originally, the session state used to be
allocated by a child-local heap partition fed from the child's RAM
session. However, whereas this approach was somehow practical from a
runtime's (parent's) point of view, the child component could not count
on the quota in its own RAM session. I.e., if the Child::heap grew at
the parent side, the child's RAM session would magically diminish. This
caused two problems. First, it violates assumptions of components like
init that carefully manage their RAM resources (and giving most of them
away their children). Second, if a child transfers most of its RAM
session quota to another RAM session (like init does), the child's RAM
session may actually not allow the parent's heap to grow, which is a
very difficult error condition to deal with.
In the new version, there is no Child::heap anymore. Instead, session
states are allocated from the runtime's RAM session. In order to let
children pay for these costs, the parent withdraws the local session
costs from the session quota donated from the child when the child
initiates a new session. Hence, in principle, all components on the
route of the session request take a small bite from the session quota to
pay for their local book keeping
Consequently, the session quota that ends up at the server may become
depleted more or less, depending on the route. In the case where the
remaining quota is insufficient for the server, the server responds with
'QUOTA_EXCEEDED'. Since this behavior must generally be expected, this
patch equips the client-side 'Env::session' implementation with the
ability to re-issue session requests with successively growing quota
donations.
For several of core's services (ROM, IO_MEM, IRQ), the default session
quota has now increased by 2 KiB, which should suffice for session
requests to up to 3 hops as is the common case for most run scripts. For
longer routes, the retry mechanism as described above comes into effect.
For the time being, we give a warning whenever the server-side quota
check triggers the retry mechanism. The warning may eventually be
removed at a later stage.
2017-02-19 09:31:50 +00:00
|
|
|
|
|
|
|
Session_state::Factory::Batch_size const
|
|
|
|
_session_batch_size { _policy.session_alloc_batch_size() };
|
|
|
|
|
|
|
|
/* factory for dynamically created session-state objects */
|
|
|
|
Session_state::Factory _session_factory { _session_md_alloc,
|
|
|
|
_session_batch_size };
|
|
|
|
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
typedef Session_state::Args Args;
|
|
|
|
|
2017-02-14 16:38:09 +00:00
|
|
|
static Child_policy::Route _resolve_session_request(Child_policy &,
|
|
|
|
Service::Name const &,
|
|
|
|
char const *);
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
/*
|
|
|
|
* Members that are initialized not before the child's environment is
|
|
|
|
* complete.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void _try_construct_env_dependent_members();
|
|
|
|
|
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
|
|
|
Constructible<Initial_thread> _initial_thread { };
|
2016-11-06 13:26:34 +00:00
|
|
|
|
2016-04-27 14:04:58 +00:00
|
|
|
struct Process
|
|
|
|
{
|
|
|
|
class Missing_dynamic_linker : Exception { };
|
|
|
|
class Invalid_executable : Exception { };
|
|
|
|
|
2018-07-04 16:48:04 +00:00
|
|
|
enum Type { TYPE_LOADED, TYPE_FORKED };
|
|
|
|
|
2016-04-27 14:04:58 +00:00
|
|
|
struct Loaded_executable
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Initial instruction pointer of the new process, as defined
|
|
|
|
* in the header of the executable.
|
|
|
|
*/
|
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
|
|
|
addr_t entry { 0 };
|
2016-04-27 14:04:58 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor parses the executable and sets up segment
|
|
|
|
* dataspaces
|
|
|
|
*
|
|
|
|
* \param local_rm local address space, needed to make the
|
|
|
|
* segment dataspaces temporarily visible in
|
|
|
|
* the local address space to initialize their
|
|
|
|
* content with the data from the 'elf_ds'
|
|
|
|
*
|
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
|
|
|
* \throw Region_map::Region_conflict
|
|
|
|
* \throw Region_map::Invalid_dataspace
|
2016-04-27 14:04:58 +00:00
|
|
|
* \throw Invalid_executable
|
|
|
|
* \throw Missing_dynamic_linker
|
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
|
|
|
* \throw Out_of_ram
|
|
|
|
* \throw Out_of_caps
|
2016-04-27 14:04:58 +00:00
|
|
|
*/
|
2018-07-04 16:48:04 +00:00
|
|
|
Loaded_executable(Type type,
|
2016-04-27 14:04:58 +00:00
|
|
|
Dataspace_capability ldso_ds,
|
|
|
|
Ram_session &ram,
|
|
|
|
Region_map &local_rm,
|
|
|
|
Region_map &remote_rm,
|
|
|
|
Parent_capability parent_cap);
|
|
|
|
} loaded_executable;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
* \throw Missing_dynamic_linker
|
|
|
|
* \throw Invalid_executable
|
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
|
|
|
* \throw Region_map::Region_conflict
|
|
|
|
* \throw Region_map::Invalid_dataspace
|
2017-05-08 17:55:54 +00:00
|
|
|
* \throw Out_of_ram
|
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
|
2016-04-27 14:04:58 +00:00
|
|
|
*
|
|
|
|
* On construction of a protection domain, the initial thread is
|
|
|
|
* started immediately.
|
|
|
|
*
|
2018-07-04 16:48:04 +00:00
|
|
|
* The 'type' 'TYPE_FORKED' creates an empty process. In this case,
|
|
|
|
* all process initialization steps except for the creation of the
|
|
|
|
* initial thread must be done manually, i.e., as done for
|
|
|
|
* implementing fork.
|
2016-04-27 14:04:58 +00:00
|
|
|
*/
|
2018-07-04 16:48:04 +00:00
|
|
|
Process(Type type,
|
|
|
|
Dataspace_capability ldso_ds,
|
|
|
|
Pd_session &pd,
|
|
|
|
Initial_thread_base &initial_thread,
|
|
|
|
Region_map &local_rm,
|
|
|
|
Region_map &remote_rm,
|
|
|
|
Parent_capability parent);
|
2016-04-27 14:04:58 +00:00
|
|
|
|
|
|
|
~Process();
|
|
|
|
};
|
|
|
|
|
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
|
|
|
Constructible<Process> _process { };
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The child's environment sessions
|
|
|
|
*/
|
|
|
|
|
|
|
|
template <typename CONNECTION>
|
|
|
|
struct Env_connection
|
|
|
|
{
|
2017-02-19 20:40:52 +00:00
|
|
|
Child &_child;
|
|
|
|
|
|
|
|
Id_space<Parent::Client>::Id const _client_id;
|
|
|
|
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
typedef String<64> Label;
|
|
|
|
|
|
|
|
Args const _args;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The 'Env_service' monitors session responses in order to attempt
|
|
|
|
* to 'Child::_try_construct_env_dependent_members()' on the
|
|
|
|
* arrival of environment sessions.
|
|
|
|
*/
|
|
|
|
struct Env_service : Service, Session_state::Ready_callback
|
|
|
|
{
|
|
|
|
Child &_child;
|
|
|
|
Service &_service;
|
|
|
|
|
|
|
|
Env_service(Child &child, Service &service)
|
|
|
|
:
|
2017-05-08 14:49:00 +00:00
|
|
|
Genode::Service(CONNECTION::service_name()),
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
_child(child), _service(service)
|
|
|
|
{ }
|
|
|
|
|
2018-06-07 15:24:00 +00:00
|
|
|
/*
|
|
|
|
* The 'Local_connection' may call 'initial_request' multiple
|
|
|
|
* times. We use 'initial_request' as a hook to transfer the
|
|
|
|
* session quota to an async service but we want to transfer
|
|
|
|
* the session quota only once. The '_first_request' allows
|
|
|
|
* us to distinguish the first from subsequent calls.
|
|
|
|
*/
|
|
|
|
bool _first_request = true;
|
|
|
|
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
void initiate_request(Session_state &session) override
|
|
|
|
{
|
|
|
|
session.ready_callback = this;
|
|
|
|
session.async_client_notify = true;
|
2018-05-22 09:32:36 +00:00
|
|
|
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
_service.initiate_request(session);
|
2017-01-06 10:25:56 +00:00
|
|
|
|
2018-06-07 15:24:00 +00:00
|
|
|
/*
|
|
|
|
* If the env session is provided by an async service,
|
|
|
|
* transfer the session resources.
|
|
|
|
*/
|
|
|
|
bool const async_service =
|
|
|
|
session.phase == Session_state::CREATE_REQUESTED;
|
|
|
|
|
|
|
|
if (_first_request && async_service
|
|
|
|
&& _service.name() != Pd_session::service_name()) {
|
|
|
|
|
|
|
|
Ram_quota const ram_quota { CONNECTION::RAM_QUOTA };
|
|
|
|
Cap_quota const cap_quota { CONNECTION::CAP_QUOTA };
|
2018-07-12 14:34:55 +00:00
|
|
|
|
|
|
|
if (cap(ram_quota).valid())
|
|
|
|
_child._policy.ref_pd().transfer_quota(cap(ram_quota), ram_quota);
|
|
|
|
|
|
|
|
if (cap(cap_quota).valid())
|
|
|
|
_child._policy.ref_pd().transfer_quota(cap(cap_quota), cap_quota);
|
|
|
|
|
2018-06-07 15:24:00 +00:00
|
|
|
_first_request = false;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
if (session.phase == Session_state::SERVICE_DENIED)
|
2017-01-06 10:25:56 +00:00
|
|
|
error(_child._policy.name(), ": environment ",
|
|
|
|
CONNECTION::service_name(), " session denied "
|
|
|
|
"(", session.args(), ")");
|
2018-05-22 09:32:36 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If the env session is provided by an async service,
|
|
|
|
* we have to wake up the server when closing the env
|
|
|
|
* session.
|
|
|
|
*/
|
|
|
|
if (session.phase == Session_state::CLOSE_REQUESTED)
|
|
|
|
_service.wakeup();
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Session_state::Ready_callback
|
|
|
|
*/
|
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
|
|
|
void session_ready(Session_state &) override
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
{
|
|
|
|
_child._try_construct_env_dependent_members();
|
|
|
|
}
|
|
|
|
|
2017-05-08 14:49:00 +00:00
|
|
|
/**
|
|
|
|
* Service (Ram_transfer::Account) interface
|
|
|
|
*/
|
|
|
|
void transfer(Ram_session_capability to, Ram_quota amount) override
|
|
|
|
{
|
|
|
|
Ram_transfer::Account &from = _service;
|
|
|
|
from.transfer(to, amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Service (Ram_transfer::Account) interface
|
|
|
|
*/
|
|
|
|
Ram_session_capability cap(Ram_quota) const override
|
|
|
|
{
|
|
|
|
Ram_transfer::Account &to = _service;
|
|
|
|
return to.cap(Ram_quota());
|
|
|
|
}
|
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
|
|
|
|
|
|
|
/**
|
|
|
|
* Service (Cap_transfer::Account) interface
|
|
|
|
*/
|
|
|
|
void transfer(Pd_session_capability to, Cap_quota amount) override
|
|
|
|
{
|
|
|
|
Cap_transfer::Account &from = _service;
|
|
|
|
from.transfer(to, amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Service (Cap_transfer::Account) interface
|
|
|
|
*/
|
|
|
|
Pd_session_capability cap(Cap_quota) const override
|
|
|
|
{
|
|
|
|
Cap_transfer::Account &to = _service;
|
|
|
|
return to.cap(Cap_quota());
|
|
|
|
}
|
|
|
|
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
void wakeup() override { _service.wakeup(); }
|
2017-02-21 22:00:24 +00:00
|
|
|
|
|
|
|
bool operator == (Service const &other) const override
|
|
|
|
{
|
|
|
|
return _service == other;
|
|
|
|
}
|
2017-02-19 20:40:52 +00:00
|
|
|
};
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
|
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
|
|
|
Constructible<Env_service> _env_service { };
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
|
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
|
|
|
Constructible<Local_connection<CONNECTION> > _connection { };
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Construct session arguments with the child policy applied
|
|
|
|
*/
|
|
|
|
Args _construct_args(Child_policy &policy, Label const &label)
|
|
|
|
{
|
|
|
|
/* copy original arguments into modifiable buffer */
|
|
|
|
char buf[Session_state::Args::capacity()];
|
|
|
|
buf[0] = 0;
|
|
|
|
|
|
|
|
/* supply label as session argument */
|
|
|
|
if (label.valid())
|
|
|
|
Arg_string::set_arg_string(buf, sizeof(buf), "label", label.string());
|
|
|
|
|
|
|
|
/* apply policy to argument buffer */
|
|
|
|
policy.filter_session_args(CONNECTION::service_name(), buf, sizeof(buf));
|
|
|
|
|
|
|
|
return Session_state::Args(Cstring(buf));
|
|
|
|
}
|
|
|
|
|
|
|
|
static char const *_service_name() { return CONNECTION::service_name(); }
|
|
|
|
|
|
|
|
Env_connection(Child &child, Id_space<Parent::Client>::Id id,
|
|
|
|
Label const &label = Label())
|
|
|
|
:
|
2017-02-19 20:40:52 +00:00
|
|
|
_child(child), _client_id(id),
|
|
|
|
_args(_construct_args(child._policy, label))
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
{ }
|
|
|
|
|
2017-02-19 20:40:52 +00:00
|
|
|
/**
|
|
|
|
* Initiate routing and creation of the environment session
|
|
|
|
*/
|
|
|
|
void initiate()
|
|
|
|
{
|
|
|
|
/* don't attempt to initiate env session twice */
|
|
|
|
if (_connection.constructed())
|
|
|
|
return;
|
|
|
|
|
2017-03-03 11:45:03 +00:00
|
|
|
try {
|
|
|
|
Child_policy::Route const route =
|
|
|
|
_child._resolve_session_request(_child._policy,
|
|
|
|
_service_name(),
|
|
|
|
_args.string());
|
|
|
|
_env_service.construct(_child, route.service);
|
|
|
|
_connection.construct(*_env_service, _child._id_space, _client_id,
|
|
|
|
_args, _child._policy.filter_session_affinity(Affinity()),
|
2017-05-08 17:45:47 +00:00
|
|
|
route.label, route.diag);
|
2017-03-03 11:45:03 +00:00
|
|
|
}
|
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
|
|
|
catch (Service_denied) {
|
2017-03-03 11:45:03 +00:00
|
|
|
error(_child._policy.name(), ": ", _service_name(), " "
|
|
|
|
"environment session denied"); }
|
2017-02-19 20:40:52 +00:00
|
|
|
}
|
|
|
|
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
typedef typename CONNECTION::Session_type SESSION;
|
|
|
|
|
2017-05-08 13:37:14 +00:00
|
|
|
SESSION &session() { return _connection->session(); }
|
|
|
|
SESSION const &session() const { return _connection->session(); }
|
2017-02-19 20:40:52 +00:00
|
|
|
|
2017-03-03 11:45:03 +00:00
|
|
|
Capability<SESSION> cap() const {
|
|
|
|
return _connection.constructed() ? _connection->cap()
|
|
|
|
: Capability<SESSION>(); }
|
2018-05-22 09:32:36 +00:00
|
|
|
|
2018-06-07 15:24:00 +00:00
|
|
|
bool closed() const { return !_connection.constructed() || _connection->closed(); }
|
2018-05-22 09:32:36 +00:00
|
|
|
|
|
|
|
void close() { if (_connection.constructed()) _connection->close(); }
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Env_connection<Pd_connection> _pd { *this, Env::pd(), _policy.name() };
|
|
|
|
Env_connection<Cpu_connection> _cpu { *this, Env::cpu(), _policy.name() };
|
|
|
|
Env_connection<Log_connection> _log { *this, Env::log(), _policy.name() };
|
|
|
|
Env_connection<Rom_connection> _binary { *this, Env::binary(), _policy.binary_name() };
|
|
|
|
|
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
|
|
|
Constructible<Env_connection<Rom_connection> > _linker { };
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
|
|
|
|
Dataspace_capability _linker_dataspace()
|
|
|
|
{
|
|
|
|
return _linker.constructed() ? _linker->session().dataspace()
|
|
|
|
: Rom_dataspace_capability();
|
|
|
|
}
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2016-11-06 13:26:34 +00:00
|
|
|
void _revert_quota_and_destroy(Session_state &);
|
|
|
|
|
2017-01-18 12:47:17 +00:00
|
|
|
void _discard_env_session(Id_space<Parent::Client>::Id);
|
|
|
|
|
2016-11-06 13:26:34 +00:00
|
|
|
Close_result _close(Session_state &);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
2016-11-06 13:26:34 +00:00
|
|
|
* Session_state::Ready_callback
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
void session_ready(Session_state &session) override;
|
2015-08-10 11:34:16 +00:00
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
/**
|
2016-11-06 13:26:34 +00:00
|
|
|
* Session_state::Closed_callback
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
void session_closed(Session_state &) override;
|
2015-03-04 20:12:14 +00:00
|
|
|
|
2017-05-07 23:33:40 +00:00
|
|
|
template <typename UNIT>
|
|
|
|
static UNIT _effective_quota(UNIT requested_quota, UNIT env_quota)
|
|
|
|
{
|
|
|
|
if (requested_quota.value < env_quota.value)
|
|
|
|
return UNIT { 0 };
|
|
|
|
|
|
|
|
return UNIT { requested_quota.value - env_quota.value };
|
|
|
|
}
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
public:
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2013-08-14 19:19:11 +00:00
|
|
|
/**
|
2015-03-04 20:12:14 +00:00
|
|
|
* Constructor
|
2013-08-14 19:19:11 +00:00
|
|
|
*
|
2016-11-06 13:26:34 +00:00
|
|
|
* \param rm local address space, usually 'env.rm()'
|
|
|
|
* \param entrypoint entrypoint used to serve the parent interface of
|
|
|
|
* the child
|
|
|
|
* \param policy policy for the child
|
2015-03-04 20:12:14 +00:00
|
|
|
*
|
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
|
|
|
* \throw Service_denied the initial sessions for the child's
|
|
|
|
* environment could not be established
|
2013-08-14 19:19:11 +00:00
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
Child(Region_map &rm, Rpc_entrypoint &entrypoint, Child_policy &policy);
|
2013-08-14 19:19:11 +00:00
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
/**
|
2015-03-04 20:12:14 +00:00
|
|
|
* Destructor
|
|
|
|
*
|
|
|
|
* On destruction of a child, we close all sessions of the child to
|
|
|
|
* other services.
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
2015-03-04 20:12:14 +00:00
|
|
|
virtual ~Child();
|
2011-12-22 15:19:25 +00:00
|
|
|
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
/**
|
|
|
|
* Return true if the child has been started
|
|
|
|
*
|
|
|
|
* After the child's construction, the child is not always able to run
|
|
|
|
* immediately. In particular, a session of the child's environment
|
|
|
|
* may still be pending. This method returns true only if the child's
|
|
|
|
* environment is completely initialized at the time of calling.
|
|
|
|
*
|
|
|
|
* If all environment sessions are immediately available (as is the
|
|
|
|
* case for local services or parent services), the return value is
|
|
|
|
* expected to be true. If this is not the case, one of child's
|
|
|
|
* environment sessions could not be established, e.g., the ROM session
|
|
|
|
* of the binary could not be obtained.
|
|
|
|
*/
|
|
|
|
bool active() const { return _process.constructed(); }
|
|
|
|
|
2017-02-19 20:40:52 +00:00
|
|
|
/**
|
|
|
|
* Initialize the child's RAM session
|
|
|
|
*/
|
|
|
|
void initiate_env_ram_session();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Trigger the routing and creation of the child's environment session
|
|
|
|
*
|
|
|
|
* See the description of 'Child_policy::initiate_env_sessions'.
|
|
|
|
*/
|
|
|
|
void initiate_env_sessions();
|
|
|
|
|
2018-05-22 09:32:36 +00:00
|
|
|
/**
|
|
|
|
* Return true if the child is safe to be destroyed
|
|
|
|
*
|
|
|
|
* The child must not be destroyed until all environment sessions
|
|
|
|
* are closed at the respective servers. Otherwise, the session state,
|
|
|
|
* which is kept as part of the child object may be gone before
|
|
|
|
* the close request reaches the server.
|
|
|
|
*/
|
|
|
|
bool env_sessions_closed() const
|
|
|
|
{
|
2018-06-07 15:24:00 +00:00
|
|
|
if (_linker.constructed() && !_linker->closed()) return false;
|
2018-05-22 09:32:36 +00:00
|
|
|
|
2018-06-07 15:24:00 +00:00
|
|
|
/*
|
|
|
|
* Note that the state of the CPU session remains unchecked here
|
|
|
|
* because the eager CPU-session destruction does not work on all
|
|
|
|
* kernels (search for KERNEL_SUPPORTS_EAGER_CHILD_DESTRUCTION).
|
|
|
|
*/
|
|
|
|
return _log.closed() && _binary.closed();
|
2018-05-22 09:32:36 +00:00
|
|
|
}
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
/**
|
2017-05-07 23:33:40 +00:00
|
|
|
* Quota unconditionally consumed by the child's environment
|
2016-11-06 13:26:34 +00:00
|
|
|
*/
|
2017-05-07 23:33:40 +00:00
|
|
|
static Ram_quota env_ram_quota()
|
2016-11-06 13:26:34 +00:00
|
|
|
{
|
2017-05-11 18:03:28 +00:00
|
|
|
return { Cpu_connection::RAM_QUOTA + Pd_connection::RAM_QUOTA +
|
|
|
|
Log_connection::RAM_QUOTA + 2*Rom_connection::RAM_QUOTA };
|
2016-11-06 13:26:34 +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
|
|
|
static Cap_quota env_cap_quota()
|
|
|
|
{
|
2017-05-11 18:03:28 +00:00
|
|
|
return { Cpu_connection::CAP_QUOTA + Pd_connection::CAP_QUOTA +
|
|
|
|
Log_connection::CAP_QUOTA + 2*Rom_connection::CAP_QUOTA +
|
|
|
|
1 /* parent 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
|
|
|
}
|
|
|
|
|
2018-01-12 13:10:47 +00:00
|
|
|
void close_all_sessions();
|
|
|
|
|
2017-02-17 14:25:52 +00:00
|
|
|
template <typename FN>
|
|
|
|
void for_each_session(FN const &fn) const
|
|
|
|
{
|
|
|
|
_id_space.for_each<Session_state const>(fn);
|
|
|
|
}
|
|
|
|
|
2016-11-06 13:26:34 +00:00
|
|
|
/**
|
2017-05-07 23:33:40 +00:00
|
|
|
* Deduce env session costs from usable RAM quota
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
2017-05-07 23:33:40 +00:00
|
|
|
static Ram_quota effective_quota(Ram_quota quota)
|
2016-11-06 13:26:34 +00:00
|
|
|
{
|
2017-05-07 23:33:40 +00:00
|
|
|
return _effective_quota(quota, env_ram_quota());
|
2016-11-06 13:26:34 +00:00
|
|
|
}
|
2012-10-24 14:27:26 +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
|
|
|
/**
|
|
|
|
* Deduce env session costs from usable cap quota
|
|
|
|
*/
|
|
|
|
static Cap_quota effective_quota(Cap_quota quota)
|
|
|
|
{
|
|
|
|
return _effective_quota(quota, env_cap_quota());
|
|
|
|
}
|
|
|
|
|
2017-05-11 18:03:28 +00:00
|
|
|
Ram_session_capability ram_session_cap() const { return _pd.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
|
|
|
Pd_session_capability pd_session_cap() const { return _pd.cap(); }
|
2016-11-06 13:26:34 +00:00
|
|
|
|
|
|
|
Parent_capability parent_cap() const { return cap(); }
|
|
|
|
|
2017-05-11 18:03:28 +00:00
|
|
|
Ram_session &ram() { return _pd.session(); }
|
|
|
|
Ram_session const &ram() const { return _pd.session(); }
|
2017-05-08 13:37:14 +00:00
|
|
|
Cpu_session &cpu() { return _cpu.session(); }
|
|
|
|
Pd_session &pd() { return _pd .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
|
|
|
Pd_session const &pd() const { return _pd .session(); }
|
2016-11-06 13:26:34 +00:00
|
|
|
|
base: apply routing policy to environment sessions
This patch changes the child-construction procedure to allow the routing
of environment sessions to arbitrary servers, not only to the parent.
In particular, it restores the ability to route the LOG session of the
child to a LOG service provided by a child of init. In principle, it
becomes possible to also route the immediate child's PD, CPU, and RAM
environment sessions in arbitrary ways, which simplifies scenarios that
intercept those sessions, e.g., the CPU sampler.
Note that the latter ability should be used with great caution because
init needs to interact with these sessions to create/destruct the child.
Normally, the sessions are provided by the parent. So init is safe at
all times. If they are routed to a child however, init will naturally
become dependent on this particular child. For the LOG session, this is
actually not a problem because even though the parent creates the LOG
session as part of the child's environment, it never interacts with the
session directly.
Fixes #2197
2016-12-12 16:40:55 +00:00
|
|
|
/**
|
|
|
|
* Request factory for creating session-state objects
|
|
|
|
*/
|
base: remove Child::heap
This patch improves the accounting for the backing store of
session-state meta data. Originally, the session state used to be
allocated by a child-local heap partition fed from the child's RAM
session. However, whereas this approach was somehow practical from a
runtime's (parent's) point of view, the child component could not count
on the quota in its own RAM session. I.e., if the Child::heap grew at
the parent side, the child's RAM session would magically diminish. This
caused two problems. First, it violates assumptions of components like
init that carefully manage their RAM resources (and giving most of them
away their children). Second, if a child transfers most of its RAM
session quota to another RAM session (like init does), the child's RAM
session may actually not allow the parent's heap to grow, which is a
very difficult error condition to deal with.
In the new version, there is no Child::heap anymore. Instead, session
states are allocated from the runtime's RAM session. In order to let
children pay for these costs, the parent withdraws the local session
costs from the session quota donated from the child when the child
initiates a new session. Hence, in principle, all components on the
route of the session request take a small bite from the session quota to
pay for their local book keeping
Consequently, the session quota that ends up at the server may become
depleted more or less, depending on the route. In the case where the
remaining quota is insufficient for the server, the server responds with
'QUOTA_EXCEEDED'. Since this behavior must generally be expected, this
patch equips the client-side 'Env::session' implementation with the
ability to re-issue session requests with successively growing quota
donations.
For several of core's services (ROM, IO_MEM, IRQ), the default session
quota has now increased by 2 KiB, which should suffice for session
requests to up to 3 hops as is the common case for most run scripts. For
longer routes, the retry mechanism as described above comes into effect.
For the time being, we give a warning whenever the server-side quota
check triggers the retry mechanism. The warning may eventually be
removed at a later stage.
2017-02-19 09:31:50 +00:00
|
|
|
Session_state::Factory &session_factory() { return _session_factory; }
|
2013-09-25 08:51:57 +00:00
|
|
|
|
|
|
|
/**
|
2015-03-04 20:12:14 +00:00
|
|
|
* Instruct the child to yield resources
|
2013-09-25 08:51:57 +00:00
|
|
|
*
|
2015-03-20 16:50:41 +00:00
|
|
|
* By calling this method, the child will be notified about the
|
2015-03-04 20:12:14 +00:00
|
|
|
* need to release the specified amount of resources. For more
|
|
|
|
* details about the protocol between a child and its parent,
|
|
|
|
* refer to the description given in 'parent/parent.h'.
|
2013-09-25 08:51:57 +00:00
|
|
|
*/
|
2015-03-04 20:12:14 +00:00
|
|
|
void yield(Resource_args const &args);
|
2013-09-25 08:51:57 +00:00
|
|
|
|
|
|
|
/**
|
2015-03-04 20:12:14 +00:00
|
|
|
* Notify the child about newly available resources
|
2013-09-25 08:51:57 +00:00
|
|
|
*/
|
2015-03-04 20:12:14 +00:00
|
|
|
void notify_resource_avail() const;
|
|
|
|
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
** Parent interface **
|
|
|
|
**********************/
|
|
|
|
|
2016-11-06 13:26:34 +00:00
|
|
|
void announce(Service_name const &) override;
|
|
|
|
void session_sigh(Signal_context_capability) override;
|
|
|
|
Session_capability session(Client::Id, Service_name const &,
|
|
|
|
Session_args const &, Affinity const &) override;
|
|
|
|
Session_capability session_cap(Client::Id) override;
|
|
|
|
Upgrade_result upgrade(Client::Id, Upgrade_args const &) override;
|
|
|
|
Close_result close(Client::Id) override;
|
2015-03-04 20:12:14 +00:00
|
|
|
void exit(int) override;
|
2016-11-06 13:26:34 +00:00
|
|
|
void session_response(Server::Id, Session_response) override;
|
|
|
|
void deliver_session_cap(Server::Id, Session_capability) override;
|
2015-03-04 20:12:14 +00:00
|
|
|
Thread_capability main_thread_cap() const override;
|
|
|
|
void resource_avail_sigh(Signal_context_capability) override;
|
|
|
|
void resource_request(Resource_args const &) override;
|
|
|
|
void yield_sigh(Signal_context_capability) override;
|
|
|
|
Resource_args yield_request() override;
|
|
|
|
void yield_response() override;
|
|
|
|
};
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
#endif /* _INCLUDE__BASE__CHILD_H_ */
|