Introduced a next_priority field to struct thread that will be used when

enqueueing a thread to the run queue.
This mechanism is now used for the thread priority boost on semaphore
release. Also, those threads are no longer made real time threads, they
now get a temporary priority of B_FIRST_REAL_TIME_PRIORITY - 1.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16165 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2006-01-31 01:58:49 +00:00
parent a324efcfdc
commit d14af9fde6
4 changed files with 20 additions and 26 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004-2005, Haiku Inc.
* Copyright 2004-2006, Haiku Inc.
* Distributed under the terms of the MIT License.
*
* Thread definition and structures
@ -135,6 +135,7 @@ struct thread {
thread_id id;
char name[B_OS_NAME_LENGTH];
int32 priority;
int32 next_priority;
int32 state;
int32 next_state;
union cpu_ent *cpu;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2002, Angelo Mottola, a.mottola@libero.it.
* Distributed under the terms of the MIT License.
*
@ -79,13 +79,8 @@ scheduler_enqueue_in_run_queue(struct thread *thread)
{
struct thread *curr, *prev;
// these shouldn't exist
if (thread->priority > B_MAX_PRIORITY)
thread->priority = B_MAX_PRIORITY;
if (thread->priority < B_MIN_PRIORITY)
thread->priority = B_MIN_PRIORITY;
for (curr = sRunQueue.head, prev = NULL; curr && curr->priority >= thread->priority;
for (curr = sRunQueue.head, prev = NULL; curr
&& curr->priority >= thread->next_priority;
curr = curr->queue_next) {
if (prev)
prev = prev->queue_next;
@ -98,6 +93,8 @@ scheduler_enqueue_in_run_queue(struct thread *thread)
prev->queue_next = thread;
else
sRunQueue.head = thread;
thread->next_priority = thread->priority;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
@ -689,16 +689,14 @@ release_sem_etc(sem_id id, int32 count, uint32 flags)
// pull off any items in the release queue and put them in the run queue
if (releaseQueue.head != NULL) {
struct thread *thread;
int32 priority;
GRAB_THREAD_LOCK();
while ((thread = thread_dequeue(&releaseQueue)) != NULL) {
// temporarily place thread in a run queue with high priority to boost it up
priority = thread->priority;
thread->priority = thread->priority >= B_FIRST_REAL_TIME_PRIORITY ?
thread->priority : B_FIRST_REAL_TIME_PRIORITY;
// TODO: isn't realtime priority a bit too much??
thread->next_priority = thread->priority >= B_FIRST_REAL_TIME_PRIORITY ?
thread->priority : B_FIRST_REAL_TIME_PRIORITY - 1;
scheduler_enqueue_in_run_queue(thread);
thread->priority = priority;
}
if ((flags & B_DO_NOT_RESCHEDULE) == 0)
scheduler_reschedule();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
@ -196,7 +196,7 @@ create_thread_struct(const char *name, thread_id threadID)
thread->kernel_errno = 0;
thread->team_next = NULL;
thread->queue_next = NULL;
thread->priority = -1;
thread->priority = thread->next_priority = -1;
thread->args1 = NULL; thread->args2 = NULL;
thread->sig_pending = 0;
thread->sig_block_mask = 0;
@ -342,6 +342,7 @@ create_thread(const char *name, team_id teamID, thread_entry_func entry,
return B_NO_MEMORY;
thread->priority = priority == -1 ? B_NORMAL_PRIORITY : priority;
thread->next_priority = thread->priority;
// ToDo: this could be dangerous in case someone calls resume_thread() on us
thread->state = B_THREAD_SUSPENDED;
thread->next_state = B_THREAD_SUSPENDED;
@ -490,7 +491,7 @@ make_thread_unreal(int argc, char **argv)
continue;
if (thread->priority > B_DISPLAY_PRIORITY) {
thread->priority = B_NORMAL_PRIORITY;
thread->priority = thread->next_priority = B_NORMAL_PRIORITY;
kprintf("thread 0x%lx made unreal\n", thread->id);
}
}
@ -540,7 +541,7 @@ _dump_thread_info(struct thread *thread)
kprintf("name: \"%s\"\n", thread->name);
kprintf("all_next: %p\nteam_next: %p\nq_next: %p\n",
thread->all_next, thread->team_next, thread->queue_next);
kprintf("priority: %ld\n", thread->priority);
kprintf("priority: %ld (next %ld)\n", thread->priority, thread->next_priority);
kprintf("state: %s\n", state_to_text(thread, thread->state));
kprintf("next_state: %s\n", state_to_text(thread, thread->next_state));
kprintf("cpu: %p ", thread->cpu);
@ -903,7 +904,7 @@ thread_exit(void)
(int)thread->exit.status));
// boost our priority to get this over with
thread->priority = B_URGENT_DISPLAY_PRIORITY;
thread->priority = thread->next_priority = B_URGENT_DISPLAY_PRIORITY;
// stop debugging for this thread
state = disable_interrupts();
@ -1342,7 +1343,7 @@ thread_init(kernel_args *args)
}
thread->team = team_get_kernel_team();
thread->priority = B_IDLE_PRIORITY;
thread->priority = thread->next_priority = B_IDLE_PRIORITY;
thread->state = B_THREAD_RUNNING;
thread->next_state = B_THREAD_READY;
sprintf(name, "idle thread %lu kstack", i + 1);
@ -1780,7 +1781,7 @@ set_thread_priority(thread_id id, int32 priority)
// note that this might not return the correct value if we are preempted
// here, and another thread changes our priority before the next line is
// executed
thread->priority = priority;
thread->priority = thread->next_priority = priority;
} else {
cpu_status state = disable_interrupts();
GRAB_THREAD_LOCK();
@ -1788,12 +1789,9 @@ set_thread_priority(thread_id id, int32 priority)
thread = thread_get_thread_struct_locked(id);
if (thread) {
oldPriority = thread->priority;
thread->next_priority = priority;
if (thread->state == B_THREAD_READY && thread->priority != priority) {
// if the thread is in the run queue, we reinsert it at a new position
// ToDo: this doesn't seem to be necessary: if a thread is already in
// the run queue, running it once doesn't hurt, and if the priority
// is now very low, it probably wouldn't have been selected to be in
// the run queue at all right now, anyway.
scheduler_remove_from_run_queue(thread);
thread->priority = priority;
scheduler_enqueue_in_run_queue(thread);