* The loop that should select a thread of the next priority class actually did

not work; it would always choose the last thread of the current priority.
  IOW a thread was never skipped, and lower priority threads were never called
  when a higher priority thread was running - from the POV of the scheduler,
  we only has real time threads...
* Improved "run_queue" KDL output.
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22515 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-10-12 10:29:08 +00:00
parent 00ef60f643
commit 4ff0c50078
+25 -29
View File
@@ -7,7 +7,7 @@
* Distributed under the terms of the NewOS License. * Distributed under the terms of the NewOS License.
*/ */
/* The thread scheduler */ /*! The thread scheduler */
#include <OS.h> #include <OS.h>
@@ -30,10 +30,6 @@
#endif #endif
// prototypes
static int dump_run_queue(int argc, char **argv);
static int _rand(void);
// 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 struct thread *sRunQueue = NULL; static struct thread *sRunQueue = NULL;
@@ -58,10 +54,12 @@ dump_run_queue(int argc, char **argv)
thread = sRunQueue; thread = sRunQueue;
if (!thread) if (!thread)
dprintf("Run queue is empty!\n"); kprintf("Run queue is empty!\n");
else { else {
kprintf("thread id priority name\n");
while (thread) { while (thread) {
dprintf("Thread id: %ld - priority: %ld\n", thread->id, thread->priority); kprintf("%p %-7ld %-8ld %s\n", thread, thread->id,
thread->priority, thread->name);
thread = thread->queue_next; thread = thread->queue_next;
} }
} }
@@ -70,10 +68,9 @@ dump_run_queue(int argc, char **argv)
} }
/** Enqueues the thread into the run queue. /*! Enqueues the thread into the run queue.
* Note: thread lock must be held when entering this function Note: thread lock must be held when entering this function
*/ */
void void
scheduler_enqueue_in_run_queue(struct thread *thread) scheduler_enqueue_in_run_queue(struct thread *thread)
{ {
@@ -98,17 +95,17 @@ scheduler_enqueue_in_run_queue(struct thread *thread)
} }
/** Removes a thread from the run queue. /*! Removes a thread from the run queue.
* Note: thread lock must be held when entering this function Note: thread lock must be held when entering this function
*/ */
void void
scheduler_remove_from_run_queue(struct thread *thread) scheduler_remove_from_run_queue(struct thread *thread)
{ {
struct thread *item, *prev; struct thread *item, *prev;
// find thread in run queue // find thread in run queue
for (item = sRunQueue, prev = NULL; item && item != thread; item = item->queue_next) { for (item = sRunQueue, prev = NULL; item && item != thread;
item = item->queue_next) {
if (prev) if (prev)
prev = prev->queue_next; prev = prev->queue_next;
else else
@@ -145,10 +142,9 @@ reschedule_event(timer *unused)
} }
/** Runs the scheduler. /*! Runs the scheduler.
* Note: expects thread spinlock to be held Note: expects thread spinlock to be held
*/ */
void void
scheduler_reschedule(void) scheduler_reschedule(void)
{ {
@@ -206,17 +202,18 @@ scheduler_reschedule(void)
if (nextThread->queue_next && nextThread->queue_next->priority == B_IDLE_PRIORITY) if (nextThread->queue_next && nextThread->queue_next->priority == B_IDLE_PRIORITY)
break; break;
// skip normal threads sometimes (roughly 16%) // skip normal threads sometimes (roughly 20%)
if (_rand() > 0x2000) if (_rand() > 0x1a00)
break; break;
// skip until next lower priority // skip until next lower priority
int32 priority = nextThread->priority; int32 priority = nextThread->priority;
while (nextThread->queue_next && priority == nextThread->queue_next->priority do {
&& nextThread->queue_next->priority > B_IDLE_PRIORITY) {
prevThread = nextThread; prevThread = nextThread;
nextThread = nextThread->queue_next; nextThread = nextThread->queue_next;
} } while (nextThread->queue_next != NULL
&& priority == nextThread->queue_next->priority
&& nextThread->queue_next->priority > B_IDLE_PRIORITY);
} }
} }
@@ -273,10 +270,9 @@ scheduler_init(void)
} }
/** This starts the scheduler. Must be run under the context of /*! This starts the scheduler. Must be run under the context of
* the initial idle thread. the initial idle thread.
*/ */
void void
scheduler_start(void) scheduler_start(void)
{ {