base-hw: no error return codes in signaling

Error return codes are used with non-const functions in the signaling modules.
This would have been impractical for the in-place translation of the module to
Ada in the context of the Spunky project. Besides, it is easy to get rid of
them and it makes the execution flow more clear.

Ref #3308
This commit is contained in:
Martin Stein 2019-05-21 22:39:00 +02:00 committed by Christian Helmuth
parent 751e6430fa
commit 793e12f8f3
4 changed files with 57 additions and 22 deletions

View File

@ -151,7 +151,9 @@ class Kernel::User_irq : public Kernel::Irq
*/
void occurred() override
{
_context.submit(1);
if (_context.can_submit(1)) {
_context.submit(1);
}
disable();
}

View File

@ -75,12 +75,18 @@ void Signal_context::_delivered()
void Signal_context::_killer_cancelled() { _killer = 0; }
int Signal_context::submit(unsigned const n)
bool Signal_context::can_submit(unsigned const n) const
{
if (_killed || _submits >= (unsigned)~0 - n) { return -1; }
if (_killed || _submits >= (unsigned)~0 - n) { return false; }
return true;
}
void Signal_context::submit(unsigned const n)
{
if (_killed || _submits >= (unsigned)~0 - n) { return; }
_submits += n;
if (_ack) { _deliverable(); }
return 0;
}
@ -100,24 +106,33 @@ void Signal_context::ack()
}
int Signal_context::kill(Signal_context_killer &k)
bool Signal_context::can_kill() const
{
/* check if in a kill operation or already killed */
if (_killed) {
if (_ack) { return 0; }
return -1;
if (_ack) { return true; }
return false;
}
return true;
}
void Signal_context::kill(Signal_context_killer &k)
{
/* check if in a kill operation or already killed */
if (_killed) {
return;
}
/* kill directly if there is no unacknowledged delivery */
if (_ack) {
_killed = 1;
return 0;
return;
}
/* wait for delivery acknowledgement */
_killer = &k;
_killed = 1;
_killer->_context = this;
_killer->_thread.signal_context_kill_pending();
return 0;
}
@ -194,14 +209,20 @@ void Signal_receiver::_add_context(Signal_context &c) {
_contexts.enqueue(c._contexts_fe); }
int Signal_receiver::add_handler(Signal_handler &h)
bool Signal_receiver::can_add_handler(Signal_handler const &h) const
{
if (h._receiver) { return -1; }
if (h._receiver) { return false; }
return true;
}
void Signal_receiver::add_handler(Signal_handler &h)
{
if (h._receiver) { return; }
_handlers.enqueue(h._handlers_fe);
h._receiver = this;
h._thread.signal_wait_for_signal();
_listen();
return 0;
}

View File

@ -169,7 +169,8 @@ class Kernel::Signal_context
* \retval 0 succeeded
* \retval -1 failed
*/
int submit(unsigned const n);
bool can_submit(unsigned const n) const;
void submit(unsigned const n);
/**
* Acknowledge delivery of signal
@ -184,7 +185,8 @@ class Kernel::Signal_context
* \retval 0 succeeded
* \retval -1 failed
*/
int kill(Signal_context_killer &k);
bool can_kill() const;
void kill(Signal_context_killer &k);
/**
* Create a signal context and assign it to a signal receiver
@ -267,7 +269,8 @@ class Kernel::Signal_receiver
* \retval 0 succeeded
* \retval -1 failed
*/
int add_handler(Signal_handler &h);
bool can_add_handler(Signal_handler const &h) const;
void add_handler(Signal_handler &h);
/**
* Syscall to create a signal receiver

View File

@ -449,8 +449,11 @@ void Thread::timeout_triggered()
{
Signal_context * const c =
pd().cap_tree().find<Signal_context>(_timeout_sigid);
if (!c || c->submit(1))
if (!c || !c->can_submit(1)) {
Genode::raw(*this, ": failed to submit timeout signal");
return;
}
c->submit(1);
}
@ -522,11 +525,12 @@ void Thread::_call_await_signal()
return;
}
/* register handler at the receiver */
if (r->add_handler(_signal_handler)) {
if (!r->can_add_handler(_signal_handler)) {
Genode::raw("failed to register handler at signal receiver");
user_arg_0(-1);
return;
}
r->add_handler(_signal_handler);
user_arg_0(0);
}
@ -543,10 +547,11 @@ void Thread::_call_pending_signal()
}
/* register handler at the receiver */
if (r->add_handler(_signal_handler)) {
if (!r->can_add_handler(_signal_handler)) {
user_arg_0(-1);
return;
}
r->add_handler(_signal_handler);
if (_state == AWAITS_SIGNAL) {
_cancel_blocking();
@ -588,11 +593,12 @@ void Thread::_call_submit_signal()
}
/* trigger signal context */
if (c->submit(user_arg_2())) {
if (!c->can_submit(user_arg_2())) {
Genode::raw("failed to submit signal context");
user_arg_0(-1);
return;
}
c->submit(user_arg_2());
user_arg_0(0);
}
@ -622,11 +628,12 @@ void Thread::_call_kill_signal_context()
}
/* kill signal context */
if (c->kill(_signal_context_killer)) {
if (!c->can_kill()) {
Genode::raw("failed to kill signal context");
user_arg_0(-1);
return;
}
c->kill(_signal_context_killer);
}
@ -809,9 +816,11 @@ void Thread::_mmu_exception()
if (_core)
Genode::raw(*this, " raised a fault, which should never happen ",
_fault);
_fault);
if (_pager) _pager->submit(1);
if (_pager && _pager->can_submit(1)) {
_pager->submit(1);
}
}