diff --git a/src/system/kernel/scheduler/scheduler.cpp b/src/system/kernel/scheduler/scheduler.cpp index 9ecb4e3e15..1913e57b35 100644 --- a/src/system/kernel/scheduler/scheduler.cpp +++ b/src/system/kernel/scheduler/scheduler.cpp @@ -108,19 +108,20 @@ enqueue(Thread* thread, bool newOne) ASSERT(thread->previous_cpu != NULL); ASSERT(threadData->Core() != NULL); targetCPU = &gCPUEntries[thread->previous_cpu->cpu_num]; - } else if (gSingleCore) + } else if (gSingleCore) { targetCore = &gCoreEntries[0]; - else if (threadData->Core() != NULL + } else if (threadData->Core() != NULL && (!newOne || !threadData->HasCacheExpired())) { targetCore = threadData->Rebalance(); } - bool rescheduleNeeded = threadData->ChooseCoreAndCPU(targetCore, targetCPU); + const bool rescheduleNeeded = threadData->ChooseCoreAndCPU(targetCore, targetCPU); TRACE("enqueueing thread %ld with priority %ld on CPU %ld (core %ld)\n", thread->id, threadPriority, targetCPU->ID(), targetCore->ID()); - threadData->Enqueue(); + bool wasRunQueueEmpty = false; + threadData->Enqueue(wasRunQueueEmpty); // notify listeners NotifySchedulerListeners(&SchedulerListener::ThreadEnqueuedInRunQueue, @@ -128,11 +129,12 @@ enqueue(Thread* thread, bool newOne) int32 heapPriority = CPUPriorityHeap::GetKey(targetCPU); if (threadPriority > heapPriority - || (threadPriority == heapPriority && rescheduleNeeded)) { + || (threadPriority == heapPriority && rescheduleNeeded) + || wasRunQueueEmpty) { - if (targetCPU->ID() == smp_get_current_cpu()) + if (targetCPU->ID() == smp_get_current_cpu()) { gCPU[targetCPU->ID()].invoke_scheduler = true; - else { + } else { smp_send_ici(targetCPU->ID(), SMP_MSG_RESCHEDULE, 0, 0, 0, NULL, SMP_MSG_FLAG_ASYNC); } diff --git a/src/system/kernel/scheduler/scheduler_thread.h b/src/system/kernel/scheduler/scheduler_thread.h index 73e581e282..e3504569c9 100644 --- a/src/system/kernel/scheduler/scheduler_thread.h +++ b/src/system/kernel/scheduler/scheduler_thread.h @@ -74,7 +74,7 @@ public: inline bigtime_t WentSleepActive() const { return fWentSleepActive; } inline void PutBack(); - inline void Enqueue(); + inline void Enqueue(bool& wasRunQueueEmpty); inline bool Dequeue(); inline void UpdateActivity(bigtime_t active); @@ -406,7 +406,7 @@ ThreadData::PutBack() inline void -ThreadData::Enqueue() +ThreadData::Enqueue(bool& wasRunQueueEmpty) { SCHEDULER_ENTER_FUNCTION(); @@ -427,8 +427,7 @@ ThreadData::Enqueue() fThread->state = B_THREAD_READY; - int32 priority = GetEffectivePriority(); - + const int32 priority = GetEffectivePriority(); if (fThread->pinned_to_cpu > 0) { ASSERT(fThread->previous_cpu != NULL); CPUEntry* cpu = CPUEntry::GetCPU(fThread->previous_cpu->cpu_num); @@ -437,12 +436,18 @@ ThreadData::Enqueue() ASSERT(!fEnqueued); fEnqueued = true; + ThreadData* top = cpu->PeekThread(); + wasRunQueueEmpty = (top == NULL || top->IsIdle()); + cpu->PushBack(this, priority); } else { CoreRunQueueLocker _(fCore); ASSERT(!fEnqueued); fEnqueued = true; + ThreadData* top = fCore->PeekThread(); + wasRunQueueEmpty = (top == NULL || top->IsIdle()); + fCore->PushBack(this, priority); } }