Implement resource-balancing in parent interface

This commit is contained in:
Norman Feske 2013-09-25 10:51:57 +02:00
parent f65606f179
commit 93bd4d55f8
2 changed files with 73 additions and 8 deletions

View File

@ -112,6 +112,19 @@ namespace Genode {
* argument to core, i.e., the chroot path, the UID, and the GID.
*/
virtual Native_pd_args const *pd_args() const { return 0; }
/**
* Respond to the release of resources by the child
*
* This function is called when the child confirms the release of
* 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 &) { }
};
@ -178,11 +191,17 @@ namespace Genode {
/* server role */
Server _server;
/**
* Session-argument buffer
*/
/* session-argument buffer */
char _args[Parent::Session_args::MAX_SIZE];
/* signal handlers registered by the child */
Signal_context_capability _resource_avail_sigh;
Signal_context_capability _yield_sigh;
/* arguments fetched by the child in response to a yield signal */
Lock _yield_request_lock;
Resource_args _yield_request_args;
Process _process;
/**
@ -274,6 +293,21 @@ namespace Genode {
*/
void revoke_server(const Server *server);
/**
* Instruct the child to yield resources
*
* By calling this function, the child will be notified about the
* 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'.
*/
void yield(Resource_args const &args);
/**
* Notify the child about newly available resources
*/
void notify_resource_avail() const;
/**********************
** Parent interface **

View File

@ -233,6 +233,26 @@ void Child::revoke_server(Server const *server)
}
void Child::yield(Resource_args const &args)
{
Lock::Guard guard(_yield_request_lock);
/* buffer yield request arguments to be picked up by the child */
_yield_request_args = args;
/* notify the child about the yield request */
if (_yield_sigh.valid())
Signal_transmitter(_yield_sigh).submit();
}
void Child::notify_resource_avail() const
{
if (_resource_avail_sigh.valid())
Signal_transmitter(_resource_avail_sigh).submit();
}
void Child::announce(Parent::Service_name const &name, Root_capability root)
{
if (!name.is_valid_string()) return;
@ -417,19 +437,30 @@ Thread_capability Child::main_thread_cap() const
}
void Child::resource_avail_sigh(Signal_context_capability) { }
void Child::resource_avail_sigh(Signal_context_capability sigh)
{
_resource_avail_sigh = sigh;
}
void Child::resource_request(Resource_args const &) { }
void Child::resource_request(Resource_args const &args)
{
_policy->resource_request(args);
}
void Child::yield_sigh(Signal_context_capability) { }
void Child::yield_sigh(Signal_context_capability sigh) { _yield_sigh = sigh; }
Parent::Resource_args Child::yield_request() { return Resource_args(); }
Parent::Resource_args Child::yield_request()
{
Lock::Guard guard(_yield_request_lock);
return _yield_request_args;
}
void Child::yield_response() { }
void Child::yield_response() { _policy->yield_response(); }
Child::Child(Dataspace_capability elf_ds,