Fix migration when hierarchical scheduling is enabled

This commit is contained in:
Jan Stoess 2010-06-18 16:17:18 +02:00
parent 0c9073639b
commit d4308d3d2e
6 changed files with 33 additions and 14 deletions

View File

@ -1,6 +1,6 @@
/*********************************************************************
*
* Copyright (C) 2007-2009, Karlsruhe University
* Copyright (C) 2007-2010, Karlsruhe University
*
* File path: api/v4/sched-hs/schedule.cc
* Description:
@ -93,7 +93,7 @@ prio_queue_t * prio_queue_t::add_prio_domain(schedule_ctrl_t prio_control)
ASSERT(domain_tcb->sched_state.flags.is_set(sched_ktcb_t::is_schedule_domain));
domain_tcb->sched_state.set_prio_queue(this);
if( cpu != get_current_cpu() )
if( cpu != get_current_cpu() )
domain_tcb->migrate_to_processor(cpu);
TRACEPOINT (SCHEDULE_PRIO_DOMAIN, "new prio domain tcb %t, cpu %d, prio %d, stride %d\n",
@ -107,8 +107,9 @@ prio_queue_t *prio_queue_t::domain_partner( cpuid_t cpu )
{
ASSERT(domain_tcb);
if( domain_tcb->is_local_cpu() )
if( domain_tcb->get_cpu() == cpu )
return this;
#if defined(CONFIG_SMP)
prio_queue_t *partner_queue = cpu_head;
@ -577,6 +578,7 @@ static void xcpu_integrate_thread(tcb_t * tcb)
scheduler_t *scheduler = get_current_scheduler();
sched_ktcb_t *sched_state = &tcb->sched_state;
/* VU: the thread may have received an IPC meanwhile hence we
* check whether the thread is already running again. to make it
* fully working the waiting timeout must be set more carefull! */
@ -608,19 +610,23 @@ void scheduler_t::move_tcb(tcb_t *tcb, cpuid_t cpu)
tcb->set_cpu(cpu);
unlock_requeue();
prio_queue_t *new_prio_queue = tcb->sched_state.get_prio_queue()->domain_partner(cpu);
tcb->sched_state.set_pass(0); // Force tcb to use the pass of the target domain.
tcb->sched_state.set_prio_queue(new_prio_queue);
if (need_xcpu)
{
tcb->sched_state.requeue_callback = xcpu_integrate_thread;
remote_schedule(tcb);
}
prio_queue_t *new_prio_queue = tcb->sched_state.get_prio_queue()->domain_partner(cpu);
tcb->sched_state.set_pass(0); // Force tcb to use the pass of the target domain.
tcb->sched_state.set_prio_queue(new_prio_queue);
tcb->unlock();
TRACE_SCHEDULE_DETAILS("move_tcb: %t (s=%s) cpu %d pq %p dtcb %t", tcb,
tcb->get_state().string(), cpu, new_prio_queue,
new_prio_queue->get_domain_tcb());
}

View File

@ -246,7 +246,7 @@ public:
tcb->sched_state.requeue = NULL;
TRACE_SCHEDULE_DETAILS("smp_requeue:dequeue_head %t (s=%s) cpu %d (head %t)",
tcb, tcb->get_state().string(), tcb->get_cpu(), tcb_list);
tcb, tcb->get_state().string(), tcb->get_cpu(), tcb_list);
return (tcb_t *) tcb;
@ -287,10 +287,14 @@ public:
}
void enqueue_ready(tcb_t * tcb, bool head = false)
{
while (tcb != get_idle_tcb())
while (tcb->get_global_id() != IDLETHREAD )
{
ASSERT(tcb);
ASSERT(tcb->sched_state.get_prio_queue());
TRACE_SCHEDULE_DETAILS("enqueue_ready %t () pq %t dtcb %t idle %p\n", tcb,
tcb->sched_state.get_prio_queue(), tcb->sched_state.get_prio_queue()->get_domain_tcb(),
get_idle_tcb());
tcb->sched_state.get_prio_queue()->enqueue(tcb, head);
tcb = tcb->sched_state.get_prio_queue()->get_domain_tcb();
}
@ -299,7 +303,7 @@ public:
void dequeue_ready(tcb_t * tcb)
{
ASSERT(tcb);
while (tcb != get_idle_tcb())
while (tcb->get_global_id() != IDLETHREAD )
{
ASSERT(tcb);
ASSERT(tcb->sched_state.get_prio_queue());

View File

@ -389,7 +389,7 @@ void SECTION(".init") scheduler_t::init( bool bootcpu )
/* set idle-magic */
get_idle_tcb()->create_kernel_thread(NILTHREAD, &__idle_utcb, sktcb_lo);
get_idle_tcb()->set_space(get_kernel_space());
get_idle_tcb()->myself_global.set_raw((word_t)0x1d1e1d1e1d1e1d1eULL);
get_idle_tcb()->myself_global.set(IDLETHREAD);
get_idle_tcb()->create_startup_stack(idle_thread);
if( bootcpu )

View File

@ -319,6 +319,7 @@ private:
void commit_schedule_parameters(schedule_req_t &req);
static schedule_request_queue_t schedule_request_queue[CONFIG_SMP_MAX_CPUS];
static const word_t idle_tid = (word_t)0x1d1e1d1e1d1e1d1eULL;
};

View File

@ -1,6 +1,6 @@
/*********************************************************************
*
* Copyright (C) 2002-2008, Karlsruhe University
* Copyright (C) 2002-2008, 2010, Karlsruhe University
*
* File path: api/v4/thread.h
* Description: thread ids
@ -78,7 +78,7 @@ public:
static const threadid_t idlethread()
{
threadid_t tid;
tid.raw = 0x1d1e1d1e;
tid.raw = (word_t)0x1d1e1d1e1d1e1d1eULL;
return tid;
}
@ -107,6 +107,7 @@ public:
word_t get_raw() { return this->raw; }
void set_raw(word_t raw) { this->raw = raw; }
void set(threadid_t tid) { this->raw = tid.raw; }
/* operators */
bool operator == (const threadid_t & tid)
@ -119,6 +120,7 @@ public:
return this->raw != tid.raw;
}
private:
union {
word_t raw;
@ -154,6 +156,7 @@ INLINE threadid_t threadid(word_t rawid)
#define NILTHREAD (threadid_t::nilthread())
#define ANYTHREAD (threadid_t::anythread())
#define ANYLOCALTHREAD (threadid_t::anylocalthread())
#define IDLETHREAD (threadid_t::idlethread())
#endif /* !__API__V4__THREAD_H__ */

View File

@ -663,9 +663,14 @@ static SECTION(".init") void install_exception_handlers( cpuid_t cpu )
* The kernel's C entry point.
*
****************************************************************************/
#include <generic/simics.h>
extern "C" SECTION(".init") void l4_powerpc_init( word_t r3, word_t r4, word_t r5 )
{
MAGIC_BREAKPOINT;
init_console();
MAGIC_BREAKPOINT;
#if defined(CONFIG_KDB_CONS_OF1275)
init_of1275_console( r5 ); // XXX: use standard init routine!
#endif