hw: fix bug in Kernel::yield_thread

ref #899
This commit is contained in:
Martin Stein 2013-09-19 16:47:38 +02:00 committed by Norman Feske
parent 6912e638fb
commit d6d4938916
2 changed files with 33 additions and 22 deletions

View File

@ -380,13 +380,19 @@ namespace Kernel
*/ */
void do_resume_thread(Thread * const user) void do_resume_thread(Thread * const user)
{ {
/* get targeted thread */ /* lookup thread */
Thread * const t = Thread::pool()->object(user->user_arg_1()); Thread * const t = Thread::pool()->object(user->user_arg_1());
assert(t); if (!t) {
PERR("unknown thread");
user->user_arg_0(-1);
return;
}
/* check permissions */ /* check permissions */
assert(user->pd_id() == core_id() || user->pd_id() == t->pd_id()); if (user->pd_id() != core_id() && user->pd_id() != t->pd_id()) {
PERR("not entitled to resume thread");
user->user_arg_0(-1);
return;
}
/* resume targeted thread */ /* resume targeted thread */
user->user_arg_0(t->resume()); user->user_arg_0(t->resume());
} }
@ -397,22 +403,21 @@ namespace Kernel
*/ */
void do_resume_faulter(Thread * const user) void do_resume_faulter(Thread * const user)
{ {
/* get targeted thread */ /* lookup thread */
Thread * const t = Thread::pool()->object(user->user_arg_1()); Thread * const t = Thread::pool()->object(user->user_arg_1());
assert(t); if (!t) {
PERR("unknown thread");
user->user_arg_0(-1);
return;
}
/* check permissions */ /* check permissions */
assert(user->pd_id() == core_id() || user->pd_id() == t->pd_id()); if (user->pd_id() != core_id() && user->pd_id() != t->pd_id()) {
PERR("not entitled to resume thread");
/* user->user_arg_0(-1);
* Writeback the TLB entry that resolves the fault. return;
* This is a substitution for write-through-flagging }
* the memory that holds the TLB data, because the latter /* writeback translation table and resume faulter */
* is not feasible in core space.
*/
Cpu::tlb_insertions(); Cpu::tlb_insertions();
/* resume targeted thread */
t->resume(); t->resume();
} }
@ -422,11 +427,8 @@ namespace Kernel
*/ */
void do_yield_thread(Thread * const user) void do_yield_thread(Thread * const user)
{ {
/* get targeted thread */
Thread * const t = Thread::pool()->object(user->user_arg_1()); Thread * const t = Thread::pool()->object(user->user_arg_1());
if (t) { t->receive_yielded_cpu(); }
/* invoke kernel object */
if (t) t->resume();
cpu_scheduler()->yield(); cpu_scheduler()->yield();
} }

View File

@ -488,6 +488,15 @@ class Kernel::Thread
*/ */
unsigned id() const { return Object::id(); } unsigned id() const { return Object::id(); }
/**
* Notice that another thread yielded the CPU to us
*/
void receive_yielded_cpu()
{
if (_state == AWAIT_RESUME) { _schedule(); }
else { PERR("failed to receive yielded CPU"); }
}
/*********************** /***********************
** Execution_context ** ** Execution_context **