mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
hw: simplify IPC node's state model (fix #1691)
Merge the Ipc_node class' state PREPARE_AND_AWAIT_REPLY and AWAIT_REPLY, as well as PREPARE_REPLY ans INACTIVE into one.
This commit is contained in:
parent
5d434944eb
commit
37bae7bc1f
@ -42,11 +42,9 @@ class Kernel::Ipc_node : public Ipc_node_queue::Element
|
||||
|
||||
enum State
|
||||
{
|
||||
INACTIVE = 1,
|
||||
AWAIT_REPLY = 2,
|
||||
AWAIT_REQUEST = 3,
|
||||
PREPARE_REPLY = 4,
|
||||
PREPARE_AND_AWAIT_REPLY = 5,
|
||||
INACTIVE = 1,
|
||||
AWAIT_REPLY = 2,
|
||||
AWAIT_REQUEST = 3,
|
||||
};
|
||||
|
||||
void _init(Genode::Native_utcb * utcb, Ipc_node * callee);
|
||||
@ -170,12 +168,11 @@ class Kernel::Ipc_node : public Ipc_node_queue::Element
|
||||
template <typename F> void for_each_helper(F f)
|
||||
{
|
||||
/* if we have a helper in the receive buffer, call 'f' for it */
|
||||
if (_state == PREPARE_REPLY || _state == PREPARE_AND_AWAIT_REPLY) {
|
||||
if (_caller->_help) { f(_caller); } }
|
||||
if (_caller && _caller->_help) f(_caller);
|
||||
|
||||
/* call 'f' for each helper in our request queue */
|
||||
_request_queue.for_each([f] (Ipc_node * const node) {
|
||||
if (node->_help) { f(node); } });
|
||||
if (node->_help) f(node); });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,15 +86,14 @@ void Ipc_node::_receive_request(Ipc_node * const caller)
|
||||
{
|
||||
copy_msg(caller);
|
||||
_caller = caller;
|
||||
_state = PREPARE_REPLY;
|
||||
_state = INACTIVE;
|
||||
}
|
||||
|
||||
|
||||
void Ipc_node::_receive_reply(Ipc_node * callee)
|
||||
{
|
||||
copy_msg(callee);
|
||||
_state = (_state != PREPARE_AND_AWAIT_REPLY) ? INACTIVE
|
||||
: PREPARE_REPLY;
|
||||
_state = INACTIVE;
|
||||
_send_request_succeeded();
|
||||
}
|
||||
|
||||
@ -151,16 +150,12 @@ void Ipc_node::_outbuf_request_cancelled()
|
||||
if (_callee == nullptr) return;
|
||||
|
||||
_callee = nullptr;
|
||||
_state = (!_caller) ? INACTIVE : PREPARE_REPLY;
|
||||
_state = INACTIVE;
|
||||
_send_request_failed();
|
||||
}
|
||||
|
||||
|
||||
bool Ipc_node::_helps_outbuf_dst()
|
||||
{
|
||||
return (_state == PREPARE_AND_AWAIT_REPLY ||
|
||||
_state == AWAIT_REPLY) && _help;
|
||||
}
|
||||
bool Ipc_node::_helps_outbuf_dst() { return (_state == AWAIT_REPLY) && _help; }
|
||||
|
||||
|
||||
void Ipc_node::_init(Genode::Native_utcb * utcb, Ipc_node * starter)
|
||||
@ -177,16 +172,15 @@ void Ipc_node::_init(Genode::Native_utcb * utcb, Ipc_node * starter)
|
||||
void Ipc_node::send_request(Ipc_node * const callee, capid_t capid, bool help,
|
||||
unsigned rcv_caps)
|
||||
{
|
||||
/* assertions */
|
||||
assert(_state == INACTIVE || _state == PREPARE_REPLY);
|
||||
|
||||
if (_state != INACTIVE) {
|
||||
PERR("IPC send request: bad state");
|
||||
return;
|
||||
}
|
||||
Genode::Allocator &slab = pd()->platform_pd()->capability_slab();
|
||||
for (unsigned i = 0; i < rcv_caps; i++)
|
||||
_obj_id_ref_ptr[i] = slab.alloc(sizeof(Object_identity_reference));
|
||||
|
||||
/* update state */
|
||||
_state = (_state != PREPARE_REPLY) ? AWAIT_REPLY
|
||||
: PREPARE_AND_AWAIT_REPLY;
|
||||
_state = AWAIT_REPLY;
|
||||
_callee = callee;
|
||||
_capid = capid;
|
||||
_help = false;
|
||||
@ -205,9 +199,10 @@ Ipc_node * Ipc_node::helping_sink() {
|
||||
|
||||
bool Ipc_node::await_request(unsigned rcv_caps)
|
||||
{
|
||||
/* assertions */
|
||||
assert(_state == INACTIVE);
|
||||
|
||||
if (_state != INACTIVE) {
|
||||
PERR("IPC await request: bad state");
|
||||
return true;
|
||||
}
|
||||
Genode::Allocator &slab = pd()->platform_pd()->capability_slab();
|
||||
for (unsigned i = 0; i < rcv_caps; i++)
|
||||
_obj_id_ref_ptr[i] = slab.alloc(sizeof(Object_identity_reference));
|
||||
@ -229,12 +224,9 @@ bool Ipc_node::await_request(unsigned rcv_caps)
|
||||
void Ipc_node::send_reply()
|
||||
{
|
||||
/* reply to the last request if we have to */
|
||||
if (_state == PREPARE_REPLY) {
|
||||
if (_caller != nullptr) {
|
||||
_caller->_receive_reply(this);
|
||||
_caller = nullptr;
|
||||
}
|
||||
_state = INACTIVE;
|
||||
if (_state == INACTIVE && _caller) {
|
||||
_caller->_receive_reply(this);
|
||||
_caller = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,10 +243,6 @@ void Ipc_node::cancel_waiting()
|
||||
_state = INACTIVE;
|
||||
_await_request_failed();
|
||||
break;
|
||||
case PREPARE_AND_AWAIT_REPLY:
|
||||
_cancel_outbuf_request();
|
||||
_state = PREPARE_REPLY;
|
||||
_send_request_failed();
|
||||
return;
|
||||
default: return;
|
||||
}
|
||||
|
@ -455,11 +455,6 @@ void Thread::_print_activity_when_awaits_ipc()
|
||||
case AWAIT_REQUEST: {
|
||||
Genode::printf("\033[32m await REQ\033[0m");
|
||||
break; }
|
||||
case PREPARE_AND_AWAIT_REPLY: {
|
||||
Thread * const server = dynamic_cast<Thread *>(Ipc_node::callee());
|
||||
Genode::printf("\033[32m prep RPL await RPL %s -> %s\033[0m",
|
||||
server->pd_label(), server->label());
|
||||
break; }
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user