base-foc: introduce state in platform thread

When destroying a thread, which was not bound to a protection domain via kernel
primitives beforehand, it is critical to change the pager and exregs the thread
in the destruction process. Therefore, this commit introduces two thread states:
DEAD and RUNNING. On the basis of the thread state, we can decide whether to
reset the thread before destroying it, or not.
This commit is contained in:
Stefan Kalkowski 2013-03-26 17:23:40 +01:00 committed by Norman Feske
parent 9a4887dcad
commit 074e522990
2 changed files with 22 additions and 12 deletions

View File

@ -33,8 +33,11 @@ namespace Genode {
{
private:
enum State { DEAD, RUNNING };
friend class Platform_pd;
State _state;
bool _core_thread;
Cap_mapping _thread;
Cap_mapping _gate;

View File

@ -54,6 +54,8 @@ int Platform_thread::start(void *ip, void *sp)
return -1;
}
_state = RUNNING;
/* set ip and sp and run the thread */
tag = l4_thread_ex_regs(_thread.local.dst(), (l4_addr_t) ip,
(l4_addr_t) sp, 0);
@ -143,16 +145,18 @@ void Platform_thread::bind(Platform_pd *pd)
void Platform_thread::unbind()
{
/* first set the thread as its own pager */
l4_thread_control_start();
l4_thread_control_pager(_gate.remote);
l4_thread_control_exc_handler(_gate.remote);
if (l4_msgtag_has_error(l4_thread_control_commit(_thread.local.dst())))
PWRN("l4_thread_control_commit for %lx failed!",
(unsigned long) _thread.local.dst());
if (_state == RUNNING) {
/* first set the thread as its own pager */
l4_thread_control_start();
l4_thread_control_pager(_gate.remote);
l4_thread_control_exc_handler(_gate.remote);
if (l4_msgtag_has_error(l4_thread_control_commit(_thread.local.dst())))
PWRN("l4_thread_control_commit for %lx failed!",
(unsigned long) _thread.local.dst());
/* now force it into a pagefault */
l4_thread_ex_regs(_thread.local.dst(), 0, 0, L4_THREAD_EX_REGS_CANCEL);
/* now force it into a pagefault */
l4_thread_ex_regs(_thread.local.dst(), 0, 0, L4_THREAD_EX_REGS_CANCEL);
}
_platform_pd = (Platform_pd*) 0;
}
@ -249,7 +253,8 @@ Weak_ptr<Address_space> Platform_thread::address_space()
Platform_thread::Platform_thread(const char *name,
unsigned prio)
: _core_thread(false),
: _state(DEAD),
_core_thread(false),
_thread(true),
_irq(true),
_utcb(0),
@ -265,7 +270,8 @@ Platform_thread::Platform_thread(const char *name,
Platform_thread::Platform_thread(Core_cap_index* thread,
Core_cap_index* irq, const char *name)
: _core_thread(true),
: _state(RUNNING),
_core_thread(true),
_thread(Native_capability(thread), L4_BASE_THREAD_CAP),
_irq(Native_capability(irq)),
_utcb(0),
@ -279,7 +285,8 @@ Platform_thread::Platform_thread(Core_cap_index* thread,
Platform_thread::Platform_thread(const char *name)
: _core_thread(true),
: _state(DEAD),
_core_thread(true),
_thread(true),
_irq(true),
_utcb(0),