diff --git a/repos/base/include/base/child.h b/repos/base/include/base/child.h index 403be1d9e9..5512f83590 100644 --- a/repos/base/include/base/child.h +++ b/repos/base/include/base/child.h @@ -300,6 +300,8 @@ class Genode::Child : protected Rpc_object, /* arguments fetched by the child in response to a yield signal */ Mutex _yield_request_mutex { }; Resource_args _yield_request_args { }; + Mutex _resource_gain_mutex { }; + Resource_args _gained_resources { }; /* number of unanswered heartbeat signals */ unsigned _outstanding_heartbeats = 0; @@ -782,6 +784,14 @@ class Genode::Child : protected Rpc_object, */ void yield(Resource_args const &args); + /** + * Bestow resources on the child + * + * By calling this method, the child will be notified about + * the having gained the specified amount of resources. + */ + void accept(Resource_args const &args); + /** * Notify the child about newly available resources */ @@ -818,6 +828,7 @@ class Genode::Child : protected Rpc_object, void resource_request(Resource_args const &) override; void yield_sigh(Signal_context_capability) override; Resource_args yield_request() override; + Resource_args gained_resources() override; void yield_response() override; void heartbeat_sigh(Signal_context_capability) override; void heartbeat_response() override; diff --git a/repos/base/include/parent/client.h b/repos/base/include/parent/client.h index 5a6fc949c3..5cab7f396c 100644 --- a/repos/base/include/parent/client.h +++ b/repos/base/include/parent/client.h @@ -67,6 +67,8 @@ struct Genode::Parent_client : Rpc_client call(sigh); } Resource_args yield_request() override { return call(); } + + Resource_args gained_resources() override { return call(); } void yield_response() override { call(); } diff --git a/repos/base/include/parent/parent.h b/repos/base/include/parent/parent.h index 2bc99ce6c6..47e13513a8 100644 --- a/repos/base/include/parent/parent.h +++ b/repos/base/include/parent/parent.h @@ -281,6 +281,12 @@ class Genode::Parent */ virtual void yield_response() = 0; + /** + * Obtain information about the resources gained, e.g. from a resource request + * + */ + virtual Resource_args gained_resources() = 0; + /* * Health monitoring */ @@ -334,6 +340,7 @@ class Genode::Parent Resource_args const &); GENODE_RPC(Rpc_yield_sigh, void, yield_sigh, Signal_context_capability); GENODE_RPC(Rpc_yield_request, Resource_args, yield_request); + GENODE_RPC(Rpc_gained_resources, Resource_args, gained_resources); GENODE_RPC(Rpc_yield_response, void, yield_response); GENODE_RPC(Rpc_heartbeat_sigh, void, heartbeat_sigh, Signal_context_capability); GENODE_RPC(Rpc_heartbeat_response, void, heartbeat_response); @@ -343,7 +350,7 @@ class Genode::Parent Rpc_close, Rpc_session_response, Rpc_main_thread, Rpc_deliver_session_cap, Rpc_resource_avail_sigh, Rpc_resource_request, Rpc_yield_sigh, - Rpc_yield_request, Rpc_yield_response, + Rpc_yield_request, Rpc_yield_response, Rpc_gained_resources, Rpc_heartbeat_sigh, Rpc_heartbeat_response); }; diff --git a/repos/base/src/lib/base/child.cc b/repos/base/src/lib/base/child.cc index 45d96ee399..1accf6ce82 100644 --- a/repos/base/src/lib/base/child.cc +++ b/repos/base/src/lib/base/child.cc @@ -45,6 +45,15 @@ void Child::yield(Resource_args const &args) Signal_transmitter(_yield_sigh).submit(); } +void Child::accept(Resource_args const &args) +{ + Mutex::Guard guard{_resource_gain_mutex}; + + _gained_resources = args; + + if (_resource_avail_sigh.valid()) + Signal_transmitter(_resource_avail_sigh).submit(); +} void Child::notify_resource_avail() const { @@ -691,6 +700,12 @@ Parent::Resource_args Child::yield_request() return _yield_request_args; } +Parent::Resource_args Child::gained_resources() +{ + Mutex::Guard guard(_resource_gain_mutex); + + return _gained_resources; +} void Child::yield_response() { _policy.yield_response(); }