mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 06:07:59 +00:00
parent
26db598fc0
commit
6912e638fb
@ -899,7 +899,7 @@ namespace Kernel
|
|||||||
case KILL_PD: do_kill_pd(user); return;
|
case KILL_PD: do_kill_pd(user); return;
|
||||||
default:
|
default:
|
||||||
PERR("invalid syscall");
|
PERR("invalid syscall");
|
||||||
user->crash();
|
user->stop();
|
||||||
reset_lap_time();
|
reset_lap_time();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,21 +17,21 @@
|
|||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
|
|
||||||
Signal_handler::~Signal_handler()
|
void Signal_handler::_cancel_waiting()
|
||||||
{
|
{
|
||||||
if (_receiver) { _receiver->remove_handler(this); }
|
if (_receiver) { _receiver->_handler_cancelled(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Signal_context_killer::~Signal_context_killer()
|
void Signal_context_killer::_cancel_waiting()
|
||||||
{
|
{
|
||||||
if (_context) { _context->_killer_destructed(); }
|
if (_context) { _context->_killer_cancelled(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Signal_receiver_killer::~Signal_receiver_killer()
|
void Signal_receiver_killer::_cancel_waiting()
|
||||||
{
|
{
|
||||||
if (_receiver) { _receiver->_killer_destructed(); }
|
if (_receiver) { _receiver->_killer_cancelled(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,6 +61,11 @@ class Kernel::Signal_handler
|
|||||||
Fifo_element _handlers_fe;
|
Fifo_element _handlers_fe;
|
||||||
Signal_receiver * _receiver;
|
Signal_receiver * _receiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backend for for destructor and cancel_waiting
|
||||||
|
*/
|
||||||
|
void _cancel_waiting();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Let the handler block for signal receipt
|
* Let the handler block for signal receipt
|
||||||
*
|
*
|
||||||
@ -86,7 +91,12 @@ class Kernel::Signal_handler
|
|||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
virtual ~Signal_handler();
|
virtual ~Signal_handler() { _cancel_waiting(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop waiting for a signal receiver
|
||||||
|
*/
|
||||||
|
void cancel_waiting() { _cancel_waiting(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Kernel::Signal_context_killer
|
class Kernel::Signal_context_killer
|
||||||
@ -97,6 +107,11 @@ class Kernel::Signal_context_killer
|
|||||||
|
|
||||||
Signal_context * _context;
|
Signal_context * _context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backend for for destructor and cancel_waiting
|
||||||
|
*/
|
||||||
|
void _cancel_waiting();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notice that the destruction is pending
|
* Notice that the destruction is pending
|
||||||
*/
|
*/
|
||||||
@ -117,7 +132,12 @@ class Kernel::Signal_context_killer
|
|||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
virtual ~Signal_context_killer();
|
virtual ~Signal_context_killer() { _cancel_waiting(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop waiting for a signal context
|
||||||
|
*/
|
||||||
|
void cancel_waiting() { _cancel_waiting(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Kernel::Signal_receiver_killer
|
class Kernel::Signal_receiver_killer
|
||||||
@ -128,6 +148,11 @@ class Kernel::Signal_receiver_killer
|
|||||||
|
|
||||||
Signal_receiver * _receiver;
|
Signal_receiver * _receiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backend for for destructor and cancel_waiting
|
||||||
|
*/
|
||||||
|
void _cancel_waiting();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notice that the destruction is pending
|
* Notice that the destruction is pending
|
||||||
*/
|
*/
|
||||||
@ -148,7 +173,12 @@ class Kernel::Signal_receiver_killer
|
|||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
virtual ~Signal_receiver_killer();
|
virtual ~Signal_receiver_killer() { _cancel_waiting(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop waiting for a signal receiver
|
||||||
|
*/
|
||||||
|
void cancel_waiting() { _cancel_waiting(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Kernel::Signal_context
|
class Kernel::Signal_context
|
||||||
@ -188,7 +218,7 @@ class Kernel::Signal_context
|
|||||||
/**
|
/**
|
||||||
* Notice that the killer of the context has been destructed
|
* Notice that the killer of the context has been destructed
|
||||||
*/
|
*/
|
||||||
void _killer_destructed() { _killer = 0; }
|
void _killer_cancelled() { _killer = 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
@ -275,6 +305,7 @@ class Kernel::Signal_receiver
|
|||||||
public Signal_context_killer
|
public Signal_context_killer
|
||||||
{
|
{
|
||||||
friend class Signal_context;
|
friend class Signal_context;
|
||||||
|
friend class Signal_handler;
|
||||||
friend class Signal_receiver_killer;
|
friend class Signal_receiver_killer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -340,9 +371,17 @@ class Kernel::Signal_receiver
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notice that the killer of the receiver has been destructed
|
* Notice that the killer of the receiver has cancelled waiting
|
||||||
*/
|
*/
|
||||||
void _killer_destructed() { _killer = 0; }
|
void _killer_cancelled() { _killer = 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notice that handler 'h' has cancelled waiting
|
||||||
|
*/
|
||||||
|
void _handler_cancelled(Signal_handler * const h)
|
||||||
|
{
|
||||||
|
_handlers.remove(&h->_handlers_fe);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
@ -386,14 +425,6 @@ class Kernel::Signal_receiver
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop a handler 'h' from waiting for signals of the receiver
|
|
||||||
*/
|
|
||||||
void remove_handler(Signal_handler * const h)
|
|
||||||
{
|
|
||||||
_handlers.remove(&h->_handlers_fe);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a context that is assigned to the receiver
|
* Create a context that is assigned to the receiver
|
||||||
*
|
*
|
||||||
|
@ -97,16 +97,17 @@ class Kernel::Thread
|
|||||||
|
|
||||||
enum State
|
enum State
|
||||||
{
|
{
|
||||||
SCHEDULED = 1,
|
SCHEDULED = 1,
|
||||||
AWAIT_START = 2,
|
AWAIT_START = 2,
|
||||||
AWAIT_IPC = 3,
|
AWAIT_IPC = 3,
|
||||||
AWAIT_RESUME = 4,
|
AWAIT_RESUME = 4,
|
||||||
AWAIT_PAGER = 5,
|
AWAIT_PAGER = 5,
|
||||||
AWAIT_PAGER_IPC = 6,
|
AWAIT_PAGER_IPC = 6,
|
||||||
AWAIT_IRQ = 7,
|
AWAIT_IRQ = 7,
|
||||||
AWAIT_SIGNAL = 8,
|
AWAIT_SIGNAL = 8,
|
||||||
AWAIT_SIGNAL_CONTEXT_KILL = 9,
|
AWAIT_SIGNAL_CONTEXT_KILL = 9,
|
||||||
CRASHED = 10,
|
AWAIT_SIGNAL_RECEIVER_KILL = 10,
|
||||||
|
STOPPED = 11,
|
||||||
};
|
};
|
||||||
|
|
||||||
Platform_thread * const _platform_thread;
|
Platform_thread * const _platform_thread;
|
||||||
@ -127,22 +128,40 @@ class Kernel::Thread
|
|||||||
_state = SCHEDULED;
|
_state = SCHEDULED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
** Signal_context_killer **
|
** Signal_context_killer **
|
||||||
***************************/
|
***************************/
|
||||||
|
|
||||||
void _signal_context_kill_pending()
|
void _signal_context_kill_pending()
|
||||||
{
|
{
|
||||||
cpu_scheduler()->remove(this);
|
assert(_state == SCHEDULED);
|
||||||
_state = AWAIT_SIGNAL_CONTEXT_KILL;
|
_state = AWAIT_SIGNAL_CONTEXT_KILL;
|
||||||
|
cpu_scheduler()->remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _signal_context_kill_done()
|
void _signal_context_kill_done()
|
||||||
{
|
{
|
||||||
if (_state != AWAIT_SIGNAL_CONTEXT_KILL) {
|
assert(_state == AWAIT_SIGNAL_CONTEXT_KILL);
|
||||||
PDBG("ignore unexpected signal-context destruction");
|
user_arg_0(0);
|
||||||
return;
|
_schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************
|
||||||
|
** Signal_receiver_killer **
|
||||||
|
****************************/
|
||||||
|
|
||||||
|
void _signal_receiver_kill_pending()
|
||||||
|
{
|
||||||
|
assert(_state == SCHEDULED);
|
||||||
|
_state = AWAIT_SIGNAL_RECEIVER_KILL;
|
||||||
|
cpu_scheduler()->remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _signal_receiver_kill_done()
|
||||||
|
{
|
||||||
|
assert(_state == AWAIT_SIGNAL_RECEIVER_KILL);
|
||||||
user_arg_0(0);
|
user_arg_0(0);
|
||||||
_schedule();
|
_schedule();
|
||||||
}
|
}
|
||||||
@ -167,15 +186,6 @@ class Kernel::Thread
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************
|
|
||||||
** Signal_receiver_killer **
|
|
||||||
****************************/
|
|
||||||
|
|
||||||
void _signal_receiver_kill_pending() { PERR("not implemented"); }
|
|
||||||
|
|
||||||
void _signal_receiver_kill_done() { PERR("not implemented"); }
|
|
||||||
|
|
||||||
|
|
||||||
/**************
|
/**************
|
||||||
** Ipc_node **
|
** Ipc_node **
|
||||||
**************/
|
**************/
|
||||||
@ -188,7 +198,7 @@ class Kernel::Thread
|
|||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
PERR("wrong thread state to receive IPC");
|
PERR("wrong thread state to receive IPC");
|
||||||
crash();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,7 +213,7 @@ class Kernel::Thread
|
|||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
PERR("wrong thread state to await IPC");
|
PERR("wrong thread state to await IPC");
|
||||||
crash();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,7 +233,7 @@ class Kernel::Thread
|
|||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
PERR("wrong thread state to receive IPC");
|
PERR("wrong thread state to receive IPC");
|
||||||
crash();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,23 +243,23 @@ class Kernel::Thread
|
|||||||
switch (_state) {
|
switch (_state) {
|
||||||
case AWAIT_IPC:
|
case AWAIT_IPC:
|
||||||
PERR("failed to receive IPC");
|
PERR("failed to receive IPC");
|
||||||
crash();
|
stop();
|
||||||
return;
|
return;
|
||||||
case SCHEDULED:
|
case SCHEDULED:
|
||||||
PERR("failed to receive IPC");
|
PERR("failed to receive IPC");
|
||||||
crash();
|
stop();
|
||||||
return;
|
return;
|
||||||
case AWAIT_PAGER_IPC:
|
case AWAIT_PAGER_IPC:
|
||||||
PERR("failed to get pagefault resolved");
|
PERR("failed to get pagefault resolved");
|
||||||
crash();
|
stop();
|
||||||
return;
|
return;
|
||||||
case AWAIT_PAGER:
|
case AWAIT_PAGER:
|
||||||
PERR("failed to get pagefault resolved");
|
PERR("failed to get pagefault resolved");
|
||||||
crash();
|
stop();
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
PERR("wrong thread state to cancel IPC");
|
PERR("wrong thread state to cancel IPC");
|
||||||
crash();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,12 +296,12 @@ class Kernel::Thread
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suspend the thread due to unrecoverable misbehavior
|
* Suspend the thread unrecoverably
|
||||||
*/
|
*/
|
||||||
void crash()
|
void stop()
|
||||||
{
|
{
|
||||||
if (_state == SCHEDULED) { cpu_scheduler()->remove(this); }
|
if (_state == SCHEDULED) { cpu_scheduler()->remove(this); }
|
||||||
_state = CRASHED;
|
_state = STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -369,15 +379,6 @@ class Kernel::Thread
|
|||||||
_state = AWAIT_RESUME;
|
_state = AWAIT_RESUME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop this thread
|
|
||||||
*/
|
|
||||||
void stop()
|
|
||||||
{
|
|
||||||
cpu_scheduler()->remove(this);
|
|
||||||
_state = AWAIT_START;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resume this thread
|
* Resume this thread
|
||||||
*/
|
*/
|
||||||
@ -388,36 +389,44 @@ class Kernel::Thread
|
|||||||
_schedule();
|
_schedule();
|
||||||
return 0;
|
return 0;
|
||||||
case AWAIT_PAGER:
|
case AWAIT_PAGER:
|
||||||
/* pagefault has been resolved before pager replied */
|
|
||||||
_state = AWAIT_PAGER_IPC;
|
_state = AWAIT_PAGER_IPC;
|
||||||
return 0;
|
return 0;
|
||||||
|
case AWAIT_PAGER_IPC:
|
||||||
|
PERR("cancel message receipt");
|
||||||
|
Ipc_node::cancel_waiting();
|
||||||
|
return 0;
|
||||||
case SCHEDULED:
|
case SCHEDULED:
|
||||||
return 1;
|
return 1;
|
||||||
case AWAIT_IPC:
|
case AWAIT_IPC:
|
||||||
PDBG("cancel IPC receipt");
|
PERR("cancel message receipt");
|
||||||
Ipc_node::cancel_waiting();
|
Ipc_node::cancel_waiting();
|
||||||
_schedule();
|
_schedule();
|
||||||
return 0;
|
return 0;
|
||||||
case AWAIT_IRQ:
|
case AWAIT_IRQ:
|
||||||
PDBG("cancel IRQ receipt");
|
PERR("cancel interrupt receipt");
|
||||||
Irq_receiver::cancel_waiting();
|
Irq_receiver::cancel_waiting();
|
||||||
_schedule();
|
_schedule();
|
||||||
return 0;
|
return 0;
|
||||||
case AWAIT_SIGNAL:
|
case AWAIT_SIGNAL:
|
||||||
PDBG("cancel signal receipt");
|
PERR("cancel signal receipt");
|
||||||
_signal_receiver->remove_handler(this);
|
Signal_handler::cancel_waiting();
|
||||||
_schedule();
|
_schedule();
|
||||||
return 0;
|
return 0;
|
||||||
case AWAIT_SIGNAL_CONTEXT_KILL:
|
case AWAIT_SIGNAL_CONTEXT_KILL:
|
||||||
PDBG("cancel signal context destruction");
|
PERR("cancel signal context destruction");
|
||||||
|
Signal_context_killer::cancel_waiting();
|
||||||
|
_schedule();
|
||||||
|
return 0;
|
||||||
|
case AWAIT_SIGNAL_RECEIVER_KILL:
|
||||||
|
PERR("cancel signal receiver destruction");
|
||||||
|
Signal_receiver_killer::cancel_waiting();
|
||||||
_schedule();
|
_schedule();
|
||||||
return 0;
|
return 0;
|
||||||
case AWAIT_START:
|
case AWAIT_START:
|
||||||
default:
|
case STOPPED:;
|
||||||
PERR("wrong state to resume thread");
|
|
||||||
crash();
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
PERR("failed to resume thread");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user