mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-11 13:22:33 +00:00
parent
1571e09823
commit
6d03292a1e
base-hw/src
base/signal
core
@ -21,7 +21,7 @@ using namespace Genode;
|
||||
|
||||
|
||||
/**
|
||||
* Provide a static signal connection
|
||||
* Provide one signal connection per program
|
||||
*/
|
||||
static Signal_connection * signal_connection()
|
||||
{
|
||||
@ -40,12 +40,10 @@ void Signal::_dec_ref_and_unlock()
|
||||
Lock::Guard lock_guard(_data.context->_lock);
|
||||
_data.context->_ref_cnt--;
|
||||
|
||||
/*
|
||||
* We must ack a signal context to receive the next one,
|
||||
* so new signals are received only when ref_cnt = 0.
|
||||
*/
|
||||
if (_data.context->_ref_cnt == 0)
|
||||
/* acknowledge as soon as receipt is fully processed */
|
||||
if (_data.context->_ref_cnt == 0) {
|
||||
Kernel::ack_signal(_data.context->_cap.dst());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,11 +59,7 @@ void Signal::_inc_ref()
|
||||
|
||||
Signal::Signal(Signal::Data data) : _data(data)
|
||||
{
|
||||
/*
|
||||
* We assume that a kernel signal-context doesn't deliver
|
||||
* multiple signals simultaneously.
|
||||
*/
|
||||
if (_data.context) _data.context->_ref_cnt = 1;
|
||||
if (_data.context) { _data.context->_ref_cnt = 1; }
|
||||
}
|
||||
|
||||
|
||||
@ -73,9 +67,8 @@ Signal::Signal(Signal::Data data) : _data(data)
|
||||
** Signal transmitter **
|
||||
************************/
|
||||
|
||||
void Signal_transmitter::submit(unsigned cnt)
|
||||
void Signal_transmitter::submit(unsigned const cnt)
|
||||
{
|
||||
/* submits to invalid signal contexts get ignored */
|
||||
Kernel::submit_signal(_context.dst(), cnt);
|
||||
}
|
||||
|
||||
@ -116,7 +109,7 @@ void Signal_receiver::_platform_destructor()
|
||||
}
|
||||
|
||||
|
||||
void Signal_receiver::_unsynchronized_dissolve(Signal_context * c)
|
||||
void Signal_receiver::_unsynchronized_dissolve(Signal_context * const c)
|
||||
{
|
||||
/* release server resources of context */
|
||||
signal_connection()->free_context(c->_cap);
|
||||
@ -196,5 +189,6 @@ Signal Signal_receiver::wait_for_signal()
|
||||
|
||||
void Signal_receiver::local_submit(Signal::Data signal)
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
PDBG("not implemented");
|
||||
throw Exception();
|
||||
}
|
||||
|
@ -58,6 +58,16 @@ namespace Genode
|
||||
char _initial_receivers_sb [RECEIVERS_SB_SIZE];
|
||||
char _initial_contexts_sb [CONTEXTS_SB_SIZE];
|
||||
|
||||
/**
|
||||
* Destruct receiver 'r'
|
||||
*/
|
||||
void _destruct_receiver(Receiver * const r);
|
||||
|
||||
/**
|
||||
* Destruct context 'c'
|
||||
*/
|
||||
void _destruct_context(Context * const c);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
|
@ -596,7 +596,7 @@ namespace Kernel
|
||||
{
|
||||
/* check permissions */
|
||||
if (user->pd_id() != core_id()) {
|
||||
PERR("permission to create signal receiver denied");
|
||||
PERR("not entitled to create signal receiver");
|
||||
user->user_arg_0(0);
|
||||
return;
|
||||
}
|
||||
@ -622,7 +622,7 @@ namespace Kernel
|
||||
unsigned id = user->user_arg_2();
|
||||
Signal_receiver * const r = Signal_receiver::pool()->object(id);
|
||||
if (!r) {
|
||||
PERR("invalid signal receiver");
|
||||
PERR("unknown signal receiver");
|
||||
user->user_arg_0(0);
|
||||
return;
|
||||
}
|
||||
@ -649,12 +649,11 @@ namespace Kernel
|
||||
unsigned id = user->user_arg_1();
|
||||
Signal_receiver * const r = Signal_receiver::pool()->object(id);
|
||||
if (!r) {
|
||||
PERR("invalid signal receiver");
|
||||
PERR("unknown signal receiver");
|
||||
user->user_arg_0(-1);
|
||||
return;
|
||||
}
|
||||
/* register handler at the receiver */
|
||||
user->await_signal(r);
|
||||
if (r->add_handler(user)) {
|
||||
PERR("failed to register handler at signal receiver");
|
||||
user->user_arg_0(-1);
|
||||
@ -673,7 +672,7 @@ namespace Kernel
|
||||
unsigned id = user->user_arg_1();
|
||||
Signal_receiver * const r = Signal_receiver::pool()->object(id);
|
||||
if (!r) {
|
||||
PERR("invalid signal receiver");
|
||||
PERR("unknown signal receiver");
|
||||
user->user_arg_0(0);
|
||||
return;
|
||||
}
|
||||
@ -691,12 +690,13 @@ namespace Kernel
|
||||
unsigned const id = user->user_arg_1();
|
||||
Signal_context * const c = Signal_context::pool()->object(id);
|
||||
if(!c) {
|
||||
PERR("invalid signal context");
|
||||
PERR("unknown signal context");
|
||||
user->user_arg_0(-1);
|
||||
return;
|
||||
}
|
||||
/* trigger signal context */
|
||||
if (c->submit(user->user_arg_2())) {
|
||||
PERR("failed to submit signal context");
|
||||
user->user_arg_0(-1);
|
||||
return;
|
||||
}
|
||||
@ -713,7 +713,7 @@ namespace Kernel
|
||||
unsigned id = user->user_arg_1();
|
||||
Signal_context * const c = Signal_context::pool()->object(id);
|
||||
if (!c) {
|
||||
PWRN("invalid signal context");
|
||||
PERR("unknown signal context");
|
||||
return;
|
||||
}
|
||||
/* acknowledge */
|
||||
@ -736,11 +736,13 @@ namespace Kernel
|
||||
unsigned id = user->user_arg_1();
|
||||
Signal_context * const c = Signal_context::pool()->object(id);
|
||||
if (!c) {
|
||||
PERR("unknown signal context");
|
||||
user->user_arg_0(0);
|
||||
return;
|
||||
}
|
||||
/* kill signal context */
|
||||
if (c->kill(user)) {
|
||||
PERR("failed to kill signal context");
|
||||
user->user_arg_0(-1);
|
||||
return;
|
||||
}
|
||||
@ -760,15 +762,16 @@ namespace Kernel
|
||||
return;
|
||||
}
|
||||
/* lookup signal receiver */
|
||||
user->user_arg_0(1);
|
||||
unsigned id = user->user_arg_1();
|
||||
Signal_receiver * const r = Signal_receiver::pool()->object(id);
|
||||
if (!r) {
|
||||
PERR("unknown signal receiver");
|
||||
user->user_arg_0(0);
|
||||
return;
|
||||
}
|
||||
/* kill signal receiver */
|
||||
if (r->kill(user)) {
|
||||
PERR("unknown signal receiver");
|
||||
user->user_arg_0(-1);
|
||||
return;
|
||||
}
|
||||
|
@ -58,7 +58,14 @@ class Kernel::Signal_handler
|
||||
|
||||
typedef Genode::Fifo_element<Signal_handler> Fifo_element;
|
||||
|
||||
Fifo_element _handlers_fe;
|
||||
Fifo_element _handlers_fe;
|
||||
|
||||
/**
|
||||
* Let the handler block for signal receipt
|
||||
*
|
||||
* \param receiver the signal pool that the thread blocks for
|
||||
*/
|
||||
virtual void _await_signal(Signal_receiver * const receiver) = 0;
|
||||
|
||||
/**
|
||||
* Signal delivery backend
|
||||
@ -66,7 +73,7 @@ class Kernel::Signal_handler
|
||||
* \param base signal-data base
|
||||
* \param size signal-data size
|
||||
*/
|
||||
virtual void _signal_handler(void * const base, size_t const size) = 0;
|
||||
virtual void _receive_signal(void * const base, size_t const size) = 0;
|
||||
|
||||
public:
|
||||
|
||||
@ -267,7 +274,7 @@ class Kernel::Signal_receiver
|
||||
Signal_handler * const h = _handlers.dequeue()->object();
|
||||
Signal::Data data((Genode::Signal_context *)c->_imprint,
|
||||
c->_submits);
|
||||
h->_signal_handler(&data, sizeof(data));
|
||||
h->_receive_signal(&data, sizeof(data));
|
||||
c->_delivered();
|
||||
}
|
||||
}
|
||||
@ -317,6 +324,7 @@ class Kernel::Signal_receiver
|
||||
{
|
||||
if (_killer) { return -1; }
|
||||
_handlers.enqueue(&h->_handlers_fe);
|
||||
h->_await_signal(this);
|
||||
_listen();
|
||||
return 0;
|
||||
}
|
||||
|
@ -143,7 +143,14 @@ class Kernel::Thread
|
||||
** Signal_handler **
|
||||
********************/
|
||||
|
||||
void _signal_handler(void * const base, size_t const size)
|
||||
void _await_signal(Signal_receiver * const receiver)
|
||||
{
|
||||
cpu_scheduler()->remove(this);
|
||||
_state = AWAIT_SIGNAL;
|
||||
_signal_receiver = receiver;
|
||||
}
|
||||
|
||||
void _receive_signal(void * const base, size_t const size)
|
||||
{
|
||||
assert(_state == AWAIT_SIGNAL && size <= phys_utcb()->size());
|
||||
Genode::memcpy(phys_utcb()->base(), base, size);
|
||||
@ -392,18 +399,6 @@ class Kernel::Thread
|
||||
*/
|
||||
unsigned id() const { return Object::id(); }
|
||||
|
||||
/**
|
||||
* Let the thread block for signal receipt
|
||||
*
|
||||
* \param receiver the signal pool that the thread blocks for
|
||||
*/
|
||||
void await_signal(Signal_receiver * receiver)
|
||||
{
|
||||
cpu_scheduler()->remove(this);
|
||||
_state = AWAIT_SIGNAL;
|
||||
_signal_receiver = receiver;
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** Execution_context **
|
||||
|
@ -39,8 +39,16 @@ Signal_session_component::Signal_session_component(Allocator * const md,
|
||||
|
||||
Signal_session_component::~Signal_session_component()
|
||||
{
|
||||
PERR("%s: Not implemented", __PRETTY_FUNCTION__);
|
||||
while (1) ;
|
||||
while (1) {
|
||||
Context * const c = _contexts.first_locked();
|
||||
if (!c) { break; }
|
||||
_destruct_context(c);
|
||||
}
|
||||
while (1) {
|
||||
Receiver * const r = _receivers.first_locked();
|
||||
if (!r) { break; }
|
||||
_destruct_receiver(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -80,17 +88,8 @@ void Signal_session_component::free_receiver(Signal_receiver_capability cap)
|
||||
PERR("unknown signal receiver");
|
||||
throw Exception();
|
||||
}
|
||||
/* release kernel resources */
|
||||
if (Kernel::kill_signal_receiver(r->id()))
|
||||
{
|
||||
/* clean-up */
|
||||
r->release();
|
||||
PERR("failed to kill signal receiver");
|
||||
throw Exception();
|
||||
}
|
||||
/* release core resources */
|
||||
_receivers.remove_locked(r);
|
||||
r->~Receiver();
|
||||
/* release resources */
|
||||
_destruct_receiver(r);
|
||||
_receivers_slab.free(r, Receiver::slab_size());
|
||||
}
|
||||
|
||||
@ -132,6 +131,14 @@ void Signal_session_component::free_context(Signal_context_capability cap)
|
||||
PERR("unknown signal context");
|
||||
throw Exception();
|
||||
}
|
||||
/* release resources */
|
||||
_destruct_context(c);
|
||||
_contexts_slab.free(c, Context::slab_size());
|
||||
}
|
||||
|
||||
|
||||
void Signal_session_component::_destruct_context(Context * const c)
|
||||
{
|
||||
/* release kernel resources */
|
||||
if (Kernel::kill_signal_context(c->id()))
|
||||
{
|
||||
@ -143,5 +150,20 @@ void Signal_session_component::free_context(Signal_context_capability cap)
|
||||
/* release core resources */
|
||||
_contexts.remove_locked(c);
|
||||
c->~Context();
|
||||
_contexts_slab.free(c, Context::slab_size());
|
||||
}
|
||||
|
||||
|
||||
void Signal_session_component::_destruct_receiver(Receiver * const r)
|
||||
{
|
||||
/* release kernel resources */
|
||||
if (Kernel::kill_signal_receiver(r->id()))
|
||||
{
|
||||
/* clean-up */
|
||||
r->release();
|
||||
PERR("failed to kill signal receiver");
|
||||
throw Exception();
|
||||
}
|
||||
/* release core resources */
|
||||
_receivers.remove_locked(r);
|
||||
r->~Receiver();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user