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;
|
||||
default:
|
||||
PERR("invalid syscall");
|
||||
user->crash();
|
||||
user->stop();
|
||||
reset_lap_time();
|
||||
}
|
||||
}
|
||||
|
@ -17,21 +17,21 @@
|
||||
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;
|
||||
Signal_receiver * _receiver;
|
||||
|
||||
/**
|
||||
* Backend for for destructor and cancel_waiting
|
||||
*/
|
||||
void _cancel_waiting();
|
||||
|
||||
/**
|
||||
* Let the handler block for signal receipt
|
||||
*
|
||||
@ -86,7 +91,12 @@ class Kernel::Signal_handler
|
||||
/**
|
||||
* 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
|
||||
@ -97,6 +107,11 @@ class Kernel::Signal_context_killer
|
||||
|
||||
Signal_context * _context;
|
||||
|
||||
/**
|
||||
* Backend for for destructor and cancel_waiting
|
||||
*/
|
||||
void _cancel_waiting();
|
||||
|
||||
/**
|
||||
* Notice that the destruction is pending
|
||||
*/
|
||||
@ -117,7 +132,12 @@ class Kernel::Signal_context_killer
|
||||
/**
|
||||
* 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
|
||||
@ -128,6 +148,11 @@ class Kernel::Signal_receiver_killer
|
||||
|
||||
Signal_receiver * _receiver;
|
||||
|
||||
/**
|
||||
* Backend for for destructor and cancel_waiting
|
||||
*/
|
||||
void _cancel_waiting();
|
||||
|
||||
/**
|
||||
* Notice that the destruction is pending
|
||||
*/
|
||||
@ -148,7 +173,12 @@ class Kernel::Signal_receiver_killer
|
||||
/**
|
||||
* 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
|
||||
@ -188,7 +218,7 @@ class Kernel::Signal_context
|
||||
/**
|
||||
* Notice that the killer of the context has been destructed
|
||||
*/
|
||||
void _killer_destructed() { _killer = 0; }
|
||||
void _killer_cancelled() { _killer = 0; }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
@ -275,6 +305,7 @@ class Kernel::Signal_receiver
|
||||
public Signal_context_killer
|
||||
{
|
||||
friend class Signal_context;
|
||||
friend class Signal_handler;
|
||||
friend class Signal_receiver_killer;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
@ -106,7 +106,8 @@ class Kernel::Thread
|
||||
AWAIT_IRQ = 7,
|
||||
AWAIT_SIGNAL = 8,
|
||||
AWAIT_SIGNAL_CONTEXT_KILL = 9,
|
||||
CRASHED = 10,
|
||||
AWAIT_SIGNAL_RECEIVER_KILL = 10,
|
||||
STOPPED = 11,
|
||||
};
|
||||
|
||||
Platform_thread * const _platform_thread;
|
||||
@ -127,22 +128,40 @@ class Kernel::Thread
|
||||
_state = SCHEDULED;
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
** Signal_context_killer **
|
||||
***************************/
|
||||
|
||||
void _signal_context_kill_pending()
|
||||
{
|
||||
cpu_scheduler()->remove(this);
|
||||
assert(_state == SCHEDULED);
|
||||
_state = AWAIT_SIGNAL_CONTEXT_KILL;
|
||||
cpu_scheduler()->remove(this);
|
||||
}
|
||||
|
||||
void _signal_context_kill_done()
|
||||
{
|
||||
if (_state != AWAIT_SIGNAL_CONTEXT_KILL) {
|
||||
PDBG("ignore unexpected signal-context destruction");
|
||||
return;
|
||||
assert(_state == AWAIT_SIGNAL_CONTEXT_KILL);
|
||||
user_arg_0(0);
|
||||
_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);
|
||||
_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 **
|
||||
**************/
|
||||
@ -188,7 +198,7 @@ class Kernel::Thread
|
||||
return;
|
||||
default:
|
||||
PERR("wrong thread state to receive IPC");
|
||||
crash();
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -203,7 +213,7 @@ class Kernel::Thread
|
||||
return;
|
||||
default:
|
||||
PERR("wrong thread state to await IPC");
|
||||
crash();
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -223,7 +233,7 @@ class Kernel::Thread
|
||||
return;
|
||||
default:
|
||||
PERR("wrong thread state to receive IPC");
|
||||
crash();
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -233,23 +243,23 @@ class Kernel::Thread
|
||||
switch (_state) {
|
||||
case AWAIT_IPC:
|
||||
PERR("failed to receive IPC");
|
||||
crash();
|
||||
stop();
|
||||
return;
|
||||
case SCHEDULED:
|
||||
PERR("failed to receive IPC");
|
||||
crash();
|
||||
stop();
|
||||
return;
|
||||
case AWAIT_PAGER_IPC:
|
||||
PERR("failed to get pagefault resolved");
|
||||
crash();
|
||||
stop();
|
||||
return;
|
||||
case AWAIT_PAGER:
|
||||
PERR("failed to get pagefault resolved");
|
||||
crash();
|
||||
stop();
|
||||
return;
|
||||
default:
|
||||
PERR("wrong thread state to cancel IPC");
|
||||
crash();
|
||||
stop();
|
||||
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); }
|
||||
_state = CRASHED;
|
||||
_state = STOPPED;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -369,15 +379,6 @@ class Kernel::Thread
|
||||
_state = AWAIT_RESUME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop this thread
|
||||
*/
|
||||
void stop()
|
||||
{
|
||||
cpu_scheduler()->remove(this);
|
||||
_state = AWAIT_START;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume this thread
|
||||
*/
|
||||
@ -388,36 +389,44 @@ class Kernel::Thread
|
||||
_schedule();
|
||||
return 0;
|
||||
case AWAIT_PAGER:
|
||||
/* pagefault has been resolved before pager replied */
|
||||
_state = AWAIT_PAGER_IPC;
|
||||
return 0;
|
||||
case AWAIT_PAGER_IPC:
|
||||
PERR("cancel message receipt");
|
||||
Ipc_node::cancel_waiting();
|
||||
return 0;
|
||||
case SCHEDULED:
|
||||
return 1;
|
||||
case AWAIT_IPC:
|
||||
PDBG("cancel IPC receipt");
|
||||
PERR("cancel message receipt");
|
||||
Ipc_node::cancel_waiting();
|
||||
_schedule();
|
||||
return 0;
|
||||
case AWAIT_IRQ:
|
||||
PDBG("cancel IRQ receipt");
|
||||
PERR("cancel interrupt receipt");
|
||||
Irq_receiver::cancel_waiting();
|
||||
_schedule();
|
||||
return 0;
|
||||
case AWAIT_SIGNAL:
|
||||
PDBG("cancel signal receipt");
|
||||
_signal_receiver->remove_handler(this);
|
||||
PERR("cancel signal receipt");
|
||||
Signal_handler::cancel_waiting();
|
||||
_schedule();
|
||||
return 0;
|
||||
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();
|
||||
return 0;
|
||||
case AWAIT_START:
|
||||
default:
|
||||
PERR("wrong state to resume thread");
|
||||
crash();
|
||||
return -1;
|
||||
case STOPPED:;
|
||||
}
|
||||
PERR("failed to resume thread");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user