base-hw: Ada/SPARK-friendly Ipc_node interface

This prevents the use of C++ features in the public method interface of the
synchronous-IPC module that would be impractical for the in-place
translation of the module into Ada in the context of the Spunky project.

* Get rid of thread accessor.
* Get rid of non-const functions with return values.
* Get rid of pointer return-values.

Ref #3308
This commit is contained in:
Martin Stein 2019-04-25 02:45:03 +02:00 committed by Christian Helmuth
parent a04243aaf4
commit 3cc7774fe4
3 changed files with 29 additions and 38 deletions

View File

@ -122,8 +122,8 @@ void Ipc_node::send_request(Ipc_node &callee, bool help)
} }
Ipc_node * Ipc_node::helping_sink() { Thread &Ipc_node::helping_sink() {
return _helps_outbuf_dst() ? _callee->helping_sink() : this; } return _helps_outbuf_dst() ? _callee->helping_sink() : _thread; }
bool Ipc_node::can_await_request() bool Ipc_node::can_await_request()
@ -132,18 +132,12 @@ bool Ipc_node::can_await_request()
} }
bool Ipc_node::await_request() void Ipc_node::await_request()
{ {
/* if no request announced then wait */
bool announced = false;
_state = AWAIT_REQUEST; _state = AWAIT_REQUEST;
/* if anybody already announced a request receive it */
_request_queue.dequeue([&] (Queue_item &item) { _request_queue.dequeue([&] (Queue_item &item) {
_receive_request(item.object()); _receive_request(item.object());
announced = true;
}); });
return announced;
} }

View File

@ -124,12 +124,13 @@ class Kernel::Ipc_node
* \param help wether the request implies a helping relationship * \param help wether the request implies a helping relationship
*/ */
bool can_send_request(); bool can_send_request();
void send_request(Ipc_node &callee, bool help); void send_request(Ipc_node &callee,
bool help);
/** /**
* Return root destination of the helping-relation tree we are in * Return root destination of the helping-relation tree we are in
*/ */
Ipc_node * helping_sink(); Thread &helping_sink();
/** /**
* Call function 'f' of type 'void (Ipc_node *)' for each helper * Call function 'f' of type 'void (Ipc_node *)' for each helper
@ -137,12 +138,12 @@ class Kernel::Ipc_node
template <typename F> void for_each_helper(F f) template <typename F> void for_each_helper(F f)
{ {
/* if we have a helper in the receive buffer, call 'f' for it */ /* if we have a helper in the receive buffer, call 'f' for it */
if (_caller && _caller->_help) f(*_caller); if (_caller && _caller->_help) f(_caller->_thread);
/* call 'f' for each helper in our request queue */ /* call 'f' for each helper in our request queue */
_request_queue.for_each([f] (Queue_item &item) { _request_queue.for_each([f] (Queue_item &item) {
Ipc_node &node { item.object() }; Ipc_node &node { item.object() };
if (node._help) f(node); if (node._help) f(node._thread);
}); });
} }
@ -152,7 +153,7 @@ class Kernel::Ipc_node
* \return wether a request could be received already * \return wether a request could be received already
*/ */
bool can_await_request(); bool can_await_request();
bool await_request(); void await_request();
/** /**
* Reply to last request if there's any * Reply to last request if there's any
@ -164,12 +165,7 @@ class Kernel::Ipc_node
*/ */
void cancel_waiting(); void cancel_waiting();
bool awaits_request() const { return _state == AWAIT_REQUEST; }
/***************
** Accessors **
***************/
Thread &thread() { return _thread; }
}; };
#endif /* _CORE__KERNEL__IPC_NODE_H_ */ #endif /* _CORE__KERNEL__IPC_NODE_H_ */

View File

@ -217,15 +217,15 @@ void Thread::ipc_await_request_failed()
void Thread::_deactivate_used_shares() void Thread::_deactivate_used_shares()
{ {
Cpu_job::_deactivate_own_share(); Cpu_job::_deactivate_own_share();
_ipc_node.for_each_helper([&] (Ipc_node &ipc_node) { _ipc_node.for_each_helper([&] (Thread &thread) {
ipc_node.thread()._deactivate_used_shares(); }); thread._deactivate_used_shares(); });
} }
void Thread::_activate_used_shares() void Thread::_activate_used_shares()
{ {
Cpu_job::_activate_own_share(); Cpu_job::_activate_own_share();
_ipc_node.for_each_helper([&] (Ipc_node &ipc_node) { _ipc_node.for_each_helper([&] (Thread &thread) {
ipc_node.thread()._activate_used_shares(); }); thread._activate_used_shares(); });
} }
void Thread::_become_active() void Thread::_become_active()
@ -246,7 +246,7 @@ void Thread::_die() { _become_inactive(DEAD); }
Cpu_job * Thread::helping_sink() { Cpu_job * Thread::helping_sink() {
return &_ipc_node.helping_sink()->thread(); } return &_ipc_node.helping_sink(); }
size_t Thread::_core_to_kernel_quota(size_t const quota) const size_t Thread::_core_to_kernel_quota(size_t const quota) const
@ -405,22 +405,23 @@ void Thread::_call_delete_thread()
void Thread::_call_await_request_msg() void Thread::_call_await_request_msg()
{ {
if (!_ipc_node.can_await_request()) { if (_ipc_node.can_await_request()) {
Genode::raw("IPC await request: bad state");
user_arg_0(0);
return;
}
unsigned const rcv_caps = user_arg_1(); unsigned const rcv_caps = user_arg_1();
Genode::Allocator &slab = pd().platform_pd().capability_slab(); Genode::Allocator &slab = pd().platform_pd().capability_slab();
for (unsigned i = 0; i < rcv_caps; i++) for (unsigned i = 0; i < rcv_caps; i++)
_obj_id_ref_ptr[i] = slab.alloc(sizeof(Object_identity_reference)); _obj_id_ref_ptr[i] = slab.alloc(sizeof(Object_identity_reference));
_ipc_rcv_caps = rcv_caps; _ipc_rcv_caps = rcv_caps;
if (_ipc_node.await_request()) { _ipc_node.await_request();
user_arg_0(0); if (_ipc_node.awaits_request()) {
return;
}
_become_inactive(AWAITS_IPC); _become_inactive(AWAITS_IPC);
} else {
user_arg_0(0);
}
} else {
Genode::raw("IPC await request: bad state");
user_arg_0(0);
}
} }