kernel: Use the new runqueue in non-MP scheduler
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2013, Paweł Dziepak, [email protected]
|
||||||
* Copyright 2008-2011, Ingo Weinhold, [email protected].
|
* Copyright 2008-2011, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2002-2010, Axel Dörfler, [email protected].
|
* Copyright 2002-2010, Axel Dörfler, [email protected].
|
||||||
* Copyright 2002, Angelo Mottola, [email protected].
|
* Copyright 2002, Angelo Mottola, [email protected].
|
||||||
@@ -25,6 +26,7 @@
|
|||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
#include <util/Random.h>
|
#include <util/Random.h>
|
||||||
|
|
||||||
|
#include "RunQueue.h"
|
||||||
#include "scheduler_common.h"
|
#include "scheduler_common.h"
|
||||||
#include "scheduler_tracing.h"
|
#include "scheduler_tracing.h"
|
||||||
|
|
||||||
@@ -41,23 +43,23 @@ const bigtime_t kThreadQuantum = 3000;
|
|||||||
|
|
||||||
|
|
||||||
// The run queue. Holds the threads ready to run ordered by priority.
|
// The run queue. Holds the threads ready to run ordered by priority.
|
||||||
static Thread *sRunQueue = NULL;
|
static RunQueue<Thread, THREAD_MAX_SET_PRIORITY>* sRunQueue;
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dump_run_queue(int argc, char **argv)
|
dump_run_queue(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Thread *thread;
|
RunQueue<Thread, THREAD_MAX_SET_PRIORITY>::ConstIterator iterator;
|
||||||
|
iterator = sRunQueue->GetConstIterator();
|
||||||
|
|
||||||
thread = sRunQueue;
|
if (!iterator.HasNext())
|
||||||
if (!thread)
|
|
||||||
kprintf("Run queue is empty!\n");
|
kprintf("Run queue is empty!\n");
|
||||||
else {
|
else {
|
||||||
kprintf("thread id priority name\n");
|
kprintf("thread id priority name\n");
|
||||||
while (thread) {
|
while (iterator.HasNext()) {
|
||||||
|
Thread *thread = iterator.Next();
|
||||||
kprintf("%p %-7" B_PRId32 " %-8" B_PRId32 " %s\n", thread,
|
kprintf("%p %-7" B_PRId32 " %-8" B_PRId32 " %s\n", thread,
|
||||||
thread->id, thread->priority, thread->name);
|
thread->id, thread->priority, thread->name);
|
||||||
thread = thread->queue_next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,24 +75,9 @@ simple_enqueue_in_run_queue(Thread *thread)
|
|||||||
{
|
{
|
||||||
thread->state = thread->next_state = B_THREAD_READY;
|
thread->state = thread->next_state = B_THREAD_READY;
|
||||||
|
|
||||||
Thread *curr, *prev;
|
//T(EnqueueThread(thread, prev, curr));
|
||||||
for (curr = sRunQueue, prev = NULL; curr
|
|
||||||
&& curr->priority >= thread->next_priority;
|
|
||||||
curr = curr->queue_next) {
|
|
||||||
if (prev)
|
|
||||||
prev = prev->queue_next;
|
|
||||||
else
|
|
||||||
prev = sRunQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
T(EnqueueThread(thread, prev, curr));
|
|
||||||
|
|
||||||
thread->queue_next = curr;
|
|
||||||
if (prev)
|
|
||||||
prev->queue_next = thread;
|
|
||||||
else
|
|
||||||
sRunQueue = thread;
|
|
||||||
|
|
||||||
|
sRunQueue->PushBack(thread, thread->next_priority);
|
||||||
thread->next_priority = thread->priority;
|
thread->next_priority = thread->priority;
|
||||||
|
|
||||||
// notify listeners
|
// notify listeners
|
||||||
@@ -127,23 +114,8 @@ simple_set_thread_priority(Thread *thread, int32 priority)
|
|||||||
NotifySchedulerListeners(&SchedulerListener::ThreadRemovedFromRunQueue,
|
NotifySchedulerListeners(&SchedulerListener::ThreadRemovedFromRunQueue,
|
||||||
thread);
|
thread);
|
||||||
|
|
||||||
// find thread in run queue
|
// remove thread from run queue
|
||||||
Thread *item, *prev;
|
sRunQueue->Remove(thread);
|
||||||
for (item = sRunQueue, prev = NULL; item && item != thread;
|
|
||||||
item = item->queue_next) {
|
|
||||||
if (prev)
|
|
||||||
prev = prev->queue_next;
|
|
||||||
else
|
|
||||||
prev = sRunQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(item == thread);
|
|
||||||
|
|
||||||
// remove the thread
|
|
||||||
if (prev)
|
|
||||||
prev->queue_next = item->queue_next;
|
|
||||||
else
|
|
||||||
sRunQueue = item->queue_next;
|
|
||||||
|
|
||||||
// set priority and re-insert
|
// set priority and re-insert
|
||||||
thread->priority = thread->next_priority = priority;
|
thread->priority = thread->next_priority = priority;
|
||||||
@@ -185,8 +157,8 @@ reschedule_event(timer *unused)
|
|||||||
static void
|
static void
|
||||||
simple_reschedule(void)
|
simple_reschedule(void)
|
||||||
{
|
{
|
||||||
Thread *oldThread = thread_get_current_thread();
|
Thread* oldThread = thread_get_current_thread();
|
||||||
Thread *nextThread, *prevThread;
|
Thread* nextThread;
|
||||||
|
|
||||||
// check whether we're only supposed to reschedule, if the current thread
|
// check whether we're only supposed to reschedule, if the current thread
|
||||||
// is idle
|
// is idle
|
||||||
@@ -220,64 +192,48 @@ simple_reschedule(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextThread = sRunQueue;
|
while (true) {
|
||||||
prevThread = NULL;
|
// select thread with the biggest priority
|
||||||
|
nextThread = sRunQueue->PeekMaximum();
|
||||||
|
if (!nextThread)
|
||||||
|
panic("reschedule(): run queue is empty!\n");
|
||||||
|
|
||||||
while (nextThread) {
|
|
||||||
// select next thread from the run queue
|
|
||||||
while (nextThread && nextThread->priority > B_IDLE_PRIORITY) {
|
|
||||||
#if 0
|
#if 0
|
||||||
if (oldThread == nextThread && nextThread->was_yielded) {
|
if (oldThread == nextThread && nextThread->was_yielded) {
|
||||||
// ignore threads that called thread_yield() once
|
// ignore threads that called thread_yield() once
|
||||||
nextThread->was_yielded = false;
|
nextThread->was_yielded = false;
|
||||||
prevThread = nextThread;
|
prevThread = nextThread;
|
||||||
nextThread = nextThread->queue_next;
|
nextThread = nextThread->queue_next;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// always extract real time threads
|
// always extract real time threads
|
||||||
if (nextThread->priority >= B_FIRST_REAL_TIME_PRIORITY)
|
if (nextThread->priority >= B_FIRST_REAL_TIME_PRIORITY)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// find next thread with lower priority
|
// find thread with the second biggest priority
|
||||||
Thread *lowerNextThread = nextThread->queue_next;
|
Thread* lowerNextThread = sRunQueue->PeekSecondMaximum();
|
||||||
Thread *lowerPrevThread = nextThread;
|
|
||||||
int32 priority = nextThread->priority;
|
|
||||||
|
|
||||||
while (lowerNextThread != NULL
|
// never skip last non-idle normal thread
|
||||||
&& priority == lowerNextThread->priority) {
|
if (lowerNextThread == NULL
|
||||||
lowerPrevThread = lowerNextThread;
|
|| lowerNextThread->priority == B_IDLE_PRIORITY)
|
||||||
lowerNextThread = lowerNextThread->queue_next;
|
break;
|
||||||
}
|
|
||||||
// never skip last non-idle normal thread
|
|
||||||
if (lowerNextThread == NULL
|
|
||||||
|| lowerNextThread->priority == B_IDLE_PRIORITY)
|
|
||||||
break;
|
|
||||||
|
|
||||||
int32 priorityDiff = priority - lowerNextThread->priority;
|
int32 priorityDiff = nextThread->priority - lowerNextThread->priority;
|
||||||
if (priorityDiff > 15)
|
if (priorityDiff > 15)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// skip normal threads sometimes
|
// skip normal threads sometimes
|
||||||
// (twice as probable per priority level)
|
// (twice as probable per priority level)
|
||||||
if ((fast_random_value() >> (15 - priorityDiff)) != 0)
|
if ((fast_random_value() >> (15 - priorityDiff)) != 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
nextThread = lowerNextThread;
|
nextThread = lowerNextThread;
|
||||||
prevThread = lowerPrevThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nextThread)
|
sRunQueue->Remove(nextThread);
|
||||||
panic("reschedule(): run queue is empty!\n");
|
|
||||||
|
|
||||||
// extract selected thread from the run queue
|
|
||||||
if (prevThread)
|
|
||||||
prevThread->queue_next = nextThread->queue_next;
|
|
||||||
else
|
|
||||||
sRunQueue = nextThread->queue_next;
|
|
||||||
|
|
||||||
T(ScheduleThread(nextThread, oldThread));
|
T(ScheduleThread(nextThread, oldThread));
|
||||||
|
|
||||||
@@ -375,6 +331,8 @@ static scheduler_ops kSimpleOps = {
|
|||||||
void
|
void
|
||||||
scheduler_simple_init()
|
scheduler_simple_init()
|
||||||
{
|
{
|
||||||
|
sRunQueue = new(std::nothrow) RunQueue<Thread, THREAD_MAX_SET_PRIORITY>;
|
||||||
|
|
||||||
gScheduler = &kSimpleOps;
|
gScheduler = &kSimpleOps;
|
||||||
|
|
||||||
add_debugger_command_etc("run_queue", &dump_run_queue,
|
add_debugger_command_etc("run_queue", &dump_run_queue,
|
||||||
|
|||||||
Reference in New Issue
Block a user