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:
Stefan Kalkowski 2015-09-15 13:20:35 +02:00 committed by Christian Helmuth
parent 5d434944eb
commit 37bae7bc1f
3 changed files with 21 additions and 41 deletions

View File

@ -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); });
}
/**

View File

@ -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;
}

View File

@ -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;
}
}