diff --git a/repos/base-hw/src/core/kernel/irq.h b/repos/base-hw/src/core/kernel/irq.h index 2b5a7b454..c71e59c93 100644 --- a/repos/base-hw/src/core/kernel/irq.h +++ b/repos/base-hw/src/core/kernel/irq.h @@ -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(); } diff --git a/repos/base-hw/src/core/kernel/signal_receiver.cc b/repos/base-hw/src/core/kernel/signal_receiver.cc index 691c56a3b..6c9bdac28 100644 --- a/repos/base-hw/src/core/kernel/signal_receiver.cc +++ b/repos/base-hw/src/core/kernel/signal_receiver.cc @@ -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; } diff --git a/repos/base-hw/src/core/kernel/signal_receiver.h b/repos/base-hw/src/core/kernel/signal_receiver.h index 6a3ef7927..f66c649e7 100644 --- a/repos/base-hw/src/core/kernel/signal_receiver.h +++ b/repos/base-hw/src/core/kernel/signal_receiver.h @@ -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 diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index 60d4ef390..fc656e5da 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -449,8 +449,11 @@ void Thread::timeout_triggered() { Signal_context * const c = pd().cap_tree().find(_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); + } }