From d14af9fde63d4a76b347b5d7d92f8379a57941fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 31 Jan 2006 01:58:49 +0000 Subject: [PATCH] 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 --- headers/private/kernel/thread_types.h | 3 ++- src/system/kernel/scheduler.c | 13 +++++-------- src/system/kernel/sem.c | 10 ++++------ src/system/kernel/thread.c | 20 +++++++++----------- 4 files changed, 20 insertions(+), 26 deletions(-) diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index fc7bb07104..b7dd401425 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -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; diff --git a/src/system/kernel/scheduler.c b/src/system/kernel/scheduler.c index 2e975a00b8..1b59b619bf 100644 --- a/src/system/kernel/scheduler.c +++ b/src/system/kernel/scheduler.c @@ -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; } diff --git a/src/system/kernel/sem.c b/src/system/kernel/sem.c index cd1b3b2218..ff48ef16bb 100644 --- a/src/system/kernel/sem.c +++ b/src/system/kernel/sem.c @@ -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(); diff --git a/src/system/kernel/thread.c b/src/system/kernel/thread.c index c1c86fbf34..47fd19a2da 100644 --- a/src/system/kernel/thread.c +++ b/src/system/kernel/thread.c @@ -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);