From 6761f5a660bcba247e0967e09ac58f2f4488bd55 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Fri, 25 Jan 2008 15:55:54 +0000 Subject: [PATCH] Move the handling of still running threads into scheduler_enqueue_in_run_queue(). This should be in line with all uses of scheduler_enqueue_in_run_queue() and simplifies a few places where it is used. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23738 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/condition_variable.cpp | 5 +-- src/system/kernel/debug/user_debugger.cpp | 1 - src/system/kernel/image.c | 5 +-- src/system/kernel/scheduler.cpp | 13 +++++- src/system/kernel/sem.cpp | 50 ++++++----------------- src/system/kernel/signal.cpp | 18 +++----- src/system/kernel/team.cpp | 9 +--- src/system/kernel/thread.cpp | 1 - 8 files changed, 33 insertions(+), 69 deletions(-) diff --git a/src/system/kernel/condition_variable.cpp b/src/system/kernel/condition_variable.cpp index 3e709e68e5..45593dabe2 100644 --- a/src/system/kernel/condition_variable.cpp +++ b/src/system/kernel/condition_variable.cpp @@ -365,10 +365,8 @@ PrivateConditionVariable::_Notify(bool all, status_t result) // wake up the thread thread->condition_variable_entry = NULL; - if (thread->state == B_THREAD_WAITING) { - thread->state = B_THREAD_READY; + if (thread->state == B_THREAD_WAITING) scheduler_enqueue_in_run_queue(thread); - } if (!all) break; @@ -412,7 +410,6 @@ condition_variable_interrupt_thread(struct thread* thread) // wake up the thread thread->condition_variable_entry = NULL; - thread->state = B_THREAD_READY; scheduler_enqueue_in_run_queue(thread); return B_OK; diff --git a/src/system/kernel/debug/user_debugger.cpp b/src/system/kernel/debug/user_debugger.cpp index af428c80b4..879b86a667 100644 --- a/src/system/kernel/debug/user_debugger.cpp +++ b/src/system/kernel/debug/user_debugger.cpp @@ -2363,7 +2363,6 @@ _user_debug_thread(thread_id threadID) switch (thread->state) { case B_THREAD_SUSPENDED: // thread suspended: wake it up - thread->state = thread->next_state = B_THREAD_READY; scheduler_enqueue_in_run_queue(thread); break; diff --git a/src/system/kernel/image.c b/src/system/kernel/image.c index 78d27acba5..a36b1af648 100644 --- a/src/system/kernel/image.c +++ b/src/system/kernel/image.c @@ -301,11 +301,8 @@ notify_loading_app(status_t result, bool suspend) GRAB_THREAD_LOCK(); // wake up the waiting thread - if (loadingInfo->thread->state == B_THREAD_SUSPENDED) { - loadingInfo->thread->state = B_THREAD_READY; - loadingInfo->thread->next_state = B_THREAD_READY; + if (loadingInfo->thread->state == B_THREAD_SUSPENDED) scheduler_enqueue_in_run_queue(loadingInfo->thread); - } // suspend ourselves, if desired if (suspend) { diff --git a/src/system/kernel/scheduler.cpp b/src/system/kernel/scheduler.cpp index a2ac6357c0..16ccb574b1 100644 --- a/src/system/kernel/scheduler.cpp +++ b/src/system/kernel/scheduler.cpp @@ -74,8 +74,17 @@ dump_run_queue(int argc, char **argv) void scheduler_enqueue_in_run_queue(struct thread *thread) { - struct thread *curr, *prev; + if (thread->state == B_THREAD_RUNNING) { + // The thread is currently running (on another CPU) and we cannot + // insert it into the run queue. Set the next state to ready so the + // thread is inserted into the run queue on the next reschedule. + thread->next_state = B_THREAD_READY; + return; + } + thread->state = thread->next_state = B_THREAD_READY; + + struct thread *curr, *prev; for (curr = sRunQueue, prev = NULL; curr && curr->priority >= thread->next_priority; curr = curr->queue_next) { @@ -153,6 +162,7 @@ scheduler_reschedule(void) TRACE(("reschedule(): cpu %d, cur_thread = 0x%lx\n", smp_get_current_cpu(), thread_get_current_thread()->id)); + oldThread->state = oldThread->next_state; switch (oldThread->next_state) { case B_THREAD_RUNNING: case B_THREAD_READY: @@ -171,7 +181,6 @@ scheduler_reschedule(void) TRACE(("not enqueueing thread 0x%lx into run q. next_state = %ld\n", oldThread->id, oldThread->next_state)); break; } - oldThread->state = oldThread->next_state; nextThread = sRunQueue; prevThread = NULL; diff --git a/src/system/kernel/sem.cpp b/src/system/kernel/sem.cpp index 28f217c01b..67681df6e4 100644 --- a/src/system/kernel/sem.cpp +++ b/src/system/kernel/sem.cpp @@ -319,14 +319,9 @@ sem_timeout(timer *data) GRAB_THREAD_LOCK(); // put the threads in the run q here to make sure we dont deadlock in sem_interrupt_thread - while ((thread = thread_dequeue(&wakeupQueue)) != NULL) { - if (thread->state == B_THREAD_RUNNING) - thread->next_state = B_THREAD_READY; - else { - thread->state = thread->next_state = B_THREAD_READY; - scheduler_enqueue_in_run_queue(thread); - } - } + while ((thread = thread_dequeue(&wakeupQueue)) != NULL) + scheduler_enqueue_in_run_queue(thread); + RELEASE_THREAD_LOCK(); restore_interrupts(state); @@ -614,14 +609,8 @@ sem_interrupt_thread(struct thread *thread) RELEASE_SEM_LOCK(sSems[slot]); - while ((thread = thread_dequeue(&wakeupQueue)) != NULL) { - if (thread->state == B_THREAD_RUNNING) - thread->next_state = B_THREAD_READY; - else { - thread->state = thread->next_state = B_THREAD_READY; - scheduler_enqueue_in_run_queue(thread); - } - } + while ((thread = thread_dequeue(&wakeupQueue)) != NULL) + scheduler_enqueue_in_run_queue(thread); return B_NO_ERROR; } @@ -792,14 +781,9 @@ delete_sem(sem_id id) if (releasedThreads > 0) { GRAB_THREAD_LOCK(); - while ((thread = thread_dequeue(&releaseQueue)) != NULL) { - if (thread->state == B_THREAD_RUNNING) - thread->next_state = B_THREAD_READY; - else { - thread->state = thread->next_state = B_THREAD_READY; - scheduler_enqueue_in_run_queue(thread); - } - } + while ((thread = thread_dequeue(&releaseQueue)) != NULL) + scheduler_enqueue_in_run_queue(thread); + scheduler_reschedule(); RELEASE_THREAD_LOCK(); } @@ -955,14 +939,9 @@ switch_sem_etc(sem_id semToBeReleased, sem_id id, int32 count, B_INTERRUPTED, true); } RELEASE_SEM_LOCK(sSems[slot]); - while ((thread = thread_dequeue(&wakeupQueue)) != NULL) { - if (thread->state == B_THREAD_RUNNING) - thread->next_state = B_THREAD_READY; - else { - thread->state = thread->next_state = B_THREAD_READY; - scheduler_enqueue_in_run_queue(thread); - } - } + while ((thread = thread_dequeue(&wakeupQueue)) != NULL) + scheduler_enqueue_in_run_queue(thread); + // fall through and reschedule since another thread with a higher priority may have been woken up } scheduler_reschedule(); @@ -1108,12 +1087,7 @@ release_sem_etc(sem_id id, int32 count, uint32 flags) thread->next_priority = thread->priority >= B_FIRST_REAL_TIME_PRIORITY ? thread->priority : thread->priority + 1; #endif - if (thread->state == B_THREAD_RUNNING) - thread->next_state = B_THREAD_READY; - else { - thread->state = thread->next_state = B_THREAD_READY; - scheduler_enqueue_in_run_queue(thread); - } + scheduler_enqueue_in_run_queue(thread); } if ((flags & B_DO_NOT_RESCHEDULE) == 0) scheduler_reschedule(); diff --git a/src/system/kernel/signal.cpp b/src/system/kernel/signal.cpp index 802df64ffe..06d21d2413 100644 --- a/src/system/kernel/signal.cpp +++ b/src/system/kernel/signal.cpp @@ -462,10 +462,8 @@ deliver_signal(struct thread *thread, uint signal, uint32 flags) if (thread->team == team_get_kernel_team()) { // Signals to kernel threads will only wake them up - if (thread->state == B_THREAD_SUSPENDED) { - thread->state = thread->next_state = B_THREAD_READY; + if (thread->state == B_THREAD_SUSPENDED) scheduler_enqueue_in_run_queue(thread); - } return B_OK; } @@ -479,29 +477,25 @@ deliver_signal(struct thread *thread, uint signal, uint32 flags) mainThread->sig_pending |= SIGNAL_TO_MASK(SIGKILLTHR); // Wake up main thread - if (mainThread->state == B_THREAD_SUSPENDED) { - mainThread->state = mainThread->next_state = B_THREAD_READY; + if (mainThread->state == B_THREAD_SUSPENDED) scheduler_enqueue_in_run_queue(mainThread); - } else if (mainThread->state == B_THREAD_WAITING) + else if (mainThread->state == B_THREAD_WAITING) signal_interrupt_thread(mainThread); // Supposed to fall through } case SIGKILLTHR: // Wake up suspended threads and interrupt waiting ones - if (thread->state == B_THREAD_SUSPENDED) { - thread->state = thread->next_state = B_THREAD_READY; + if (thread->state == B_THREAD_SUSPENDED) scheduler_enqueue_in_run_queue(thread); - } else if (thread->state == B_THREAD_WAITING) + else if (thread->state == B_THREAD_WAITING) signal_interrupt_thread(thread); break; case SIGCONT: // Wake up thread if it was suspended - if (thread->state == B_THREAD_SUSPENDED) { - thread->state = thread->next_state = B_THREAD_READY; + if (thread->state == B_THREAD_SUSPENDED) scheduler_enqueue_in_run_queue(thread); - } atomic_and(&thread->sig_pending, ~STOP_SIGNALS); // remove any pending stop signals diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 9c6a103938..2b896d5e09 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -1159,10 +1159,8 @@ load_image_etc(int32 argCount, char * const *args, int32 envCount, mainThread = thread_get_thread_struct_locked(thread); if (mainThread) { // resume the team's main thread - if (mainThread->state == B_THREAD_SUSPENDED) { - mainThread->state = mainThread->next_state = B_THREAD_READY; + if (mainThread->state == B_THREAD_SUSPENDED) scheduler_enqueue_in_run_queue(mainThread); - } // Now suspend ourselves until loading is finished. // We will be woken either by the thread, when it finished or @@ -2159,11 +2157,8 @@ team_delete_team(struct team *team) GRAB_THREAD_LOCK(); // wake up the waiting thread - if (loadingInfo->thread->state == B_THREAD_SUSPENDED) { - loadingInfo->thread->state = B_THREAD_READY; - loadingInfo->thread->next_state = B_THREAD_READY; + if (loadingInfo->thread->state == B_THREAD_SUSPENDED) scheduler_enqueue_in_run_queue(loadingInfo->thread); - } RELEASE_THREAD_LOCK(); } diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index 694fae1e3e..7e4ece6567 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -937,7 +937,6 @@ make_thread_resumed(int argc, char **argv) continue; if (thread->state == B_THREAD_SUSPENDED) { - thread->state = thread->next_state = B_THREAD_READY; scheduler_enqueue_in_run_queue(thread); kprintf("thread %ld resumed\n", thread->id); }