* 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:
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user