From 8235bbc9965b083b294b366ea5438d2ff274dbf7 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Mon, 6 Jan 2014 01:18:37 +0100 Subject: [PATCH] scheduler: Improve thread creation performance --- src/system/kernel/scheduler/scheduler.cpp | 2 +- src/system/kernel/scheduler/scheduler_cpu.cpp | 28 +++++--- src/system/kernel/scheduler/scheduler_cpu.h | 10 --- .../kernel/scheduler/scheduler_thread.cpp | 68 ++++++++----------- .../kernel/scheduler/scheduler_thread.h | 24 ++++--- 5 files changed, 64 insertions(+), 68 deletions(-) diff --git a/src/system/kernel/scheduler/scheduler.cpp b/src/system/kernel/scheduler/scheduler.cpp index 2916b5b9aa..646c756ad6 100644 --- a/src/system/kernel/scheduler/scheduler.cpp +++ b/src/system/kernel/scheduler/scheduler.cpp @@ -383,7 +383,7 @@ reschedule(int32 nextState) int32 thisCPU = smp_get_current_cpu(); - CPUEntry* cpu = &gCPUEntries[thisCPU]; + CPUEntry* cpu = CPUEntry::GetCPU(thisCPU); CoreEntry* core = CoreEntry::GetCore(thisCPU); TRACE("reschedule(): cpu %ld, current thread = %ld\n", thisCPU, diff --git a/src/system/kernel/scheduler/scheduler_cpu.cpp b/src/system/kernel/scheduler/scheduler_cpu.cpp index 7ec4ab5eec..771f1d799d 100644 --- a/src/system/kernel/scheduler/scheduler_cpu.cpp +++ b/src/system/kernel/scheduler/scheduler_cpu.cpp @@ -123,6 +123,14 @@ CPUEntry::Remove(ThreadData* thread) } +inline ThreadData* +CoreEntry::PeekThread() const +{ + SCHEDULER_ENTER_FUNCTION(); + return fRunQueue.PeekMaximum(); +} + + inline ThreadData* CPUEntry::PeekThread() const { @@ -152,6 +160,9 @@ CPUEntry::UpdatePriority(int32 priority) return; fCore->CPUHeap()->ModifyKey(this, priority); + if (gSingleCore) + return; + if (oldPriority == B_IDLE_PRIORITY) fCore->CPUWakesUp(this); else if (priority == B_IDLE_PRIORITY) @@ -164,6 +175,7 @@ CPUEntry::ComputeLoad() { SCHEDULER_ENTER_FUNCTION(); + ASSERT(gTrackLoad); ASSERT(fCPUNumber == smp_get_current_cpu()); int oldLoad = compute_load(fMeasureTime, fMeasureActiveTime, fLoad); @@ -244,10 +256,12 @@ CPUEntry::TrackActivity(ThreadData* oldThreadData, ThreadData* nextThreadData) oldThreadData->UpdateActivity(active); } - oldThreadData->ComputeLoad(); - nextThreadData->ComputeLoad(); - if (gTrackLoad && !cpuEntry->disabled) - ComputeLoad(); + if (gTrackLoad) { + oldThreadData->ComputeLoad(); + nextThreadData->ComputeLoad(); + if (!cpuEntry->disabled) + ComputeLoad(); + } Thread* nextThread = nextThreadData->GetThread(); if (!thread_is_idle_thread(nextThread)) { @@ -256,19 +270,17 @@ CPUEntry::TrackActivity(ThreadData* oldThreadData, ThreadData* nextThreadData) nextThreadData->SetLastInterruptTime(cpuEntry->interrupt_time); + if (gCPUFrequencyManagement) _RequestPerformanceLevel(nextThreadData); } } -inline void +void CPUEntry::_RequestPerformanceLevel(ThreadData* threadData) { SCHEDULER_ENTER_FUNCTION(); - if (!gCPUFrequencyManagement) - return; - if (gCPU[fCPUNumber].disabled) { decrease_cpu_performance(kCPUPerformanceScaleMax); return; diff --git a/src/system/kernel/scheduler/scheduler_cpu.h b/src/system/kernel/scheduler/scheduler_cpu.h index b62ee5f3a2..1def98d4e6 100644 --- a/src/system/kernel/scheduler/scheduler_cpu.h +++ b/src/system/kernel/scheduler/scheduler_cpu.h @@ -112,7 +112,6 @@ public: void Dump(); }; - class CoreEntry : public MinMaxHeapLinkImpl, public DoublyLinkedListLinkImpl { public: @@ -190,7 +189,6 @@ private: friend class DebugDumper; } CACHE_LINE_ALIGN; - class CoreLoadHeap : public MinMaxHeap { public: CoreLoadHeap() { } @@ -356,14 +354,6 @@ CoreEntry::IncreaseActiveTime(bigtime_t activeTime) } -inline ThreadData* -CoreEntry::PeekThread() const -{ - SCHEDULER_ENTER_FUNCTION(); - return fRunQueue.PeekMaximum(); -} - - inline bigtime_t CoreEntry::GetActiveTime() const { diff --git a/src/system/kernel/scheduler/scheduler_thread.cpp b/src/system/kernel/scheduler/scheduler_thread.cpp index aef21a59f1..6f9c818dad 100644 --- a/src/system/kernel/scheduler/scheduler_thread.cpp +++ b/src/system/kernel/scheduler/scheduler_thread.cpp @@ -12,6 +12,28 @@ using namespace Scheduler; static bigtime_t sQuantumLengths[THREAD_MAX_SET_PRIORITY + 1]; +void +ThreadData::_InitBase() +{ + fPriorityPenalty = 0; + fAdditionalPenalty = 0; + fEffectivePriority = fThread->priority; + + fTimeLeft = 0; + fStolenTime = 0; + + fMeasureActiveTime = 0; + fMeasureTime = 0; + fLoad = 0; + + fWentSleep = 0; + fWentSleepActive = 0; + fWentSleepCount = -1; + + fEnqueued = false; +} + + inline CoreEntry* ThreadData::_ChooseCore() const { @@ -30,7 +52,8 @@ ThreadData::_ChooseCPU(CoreEntry* core, bool& rescheduleNeeded) const int32 threadPriority = GetEffectivePriority(); if (fThread->previous_cpu != NULL) { - CPUEntry* previousCPU = &gCPUEntries[fThread->previous_cpu->cpu_num]; + CPUEntry* previousCPU + = CPUEntry::GetCPU(fThread->previous_cpu->cpu_num); if (previousCPU->Core() == core && !fThread->previous_cpu->disabled) { CoreCPUHeapLocker _(core); if (CPUPriorityHeap::GetKey(previousCPU) < threadPriority) { @@ -74,48 +97,18 @@ ThreadData::ThreadData(Thread* thread) void ThreadData::Init() { - fAdditionalPenalty = 0; - fEffectivePriority = -1; + _InitBase(); - fTimeLeft = 0; - fStolenTime = 0; - - fMeasureActiveTime = 0; - fMeasureTime = 0; - fLoad = 0; - - fWentSleep = 0; - fWentSleepActive = 0; - fWentSleepCount = -1; - - fEnqueued = false; - - Thread* currentThread = thread_get_current_thread(); - ASSERT(currentThread != NULL); - if (!thread_is_idle_thread(currentThread)) { - ThreadData* currentThreadData = currentThread->scheduler_data; - int32 penalty = currentThreadData->fPriorityPenalty; - - int32 minimalPriority = _GetMinimalPriority(); - if (fThread->priority - penalty >= minimalPriority) - fPriorityPenalty = penalty; - else - fPriorityPenalty = fThread->priority - minimalPriority; - - fCore = currentThreadData->fCore; - } else { - fPriorityPenalty = 0; - fAdditionalPenalty = 0; - - fCore = NULL; - } + ThreadData* currentThreadData = thread_get_current_thread()->scheduler_data; + fCore = currentThreadData->fCore; } void ThreadData::Init(CoreEntry* core) { - Init(); + _InitBase(); + fCore = core; } @@ -172,8 +165,7 @@ ThreadData::ComputeLoad() { SCHEDULER_ENTER_FUNCTION(); - if (!gTrackLoad) - return; + ASSERT(gTrackLoad); if (fLastInterruptTime > 0) { bigtime_t interruptTime = gCPU[smp_get_current_cpu()].interrupt_time; diff --git a/src/system/kernel/scheduler/scheduler_thread.h b/src/system/kernel/scheduler/scheduler_thread.h index de932dd1dd..8d9cbdda2d 100644 --- a/src/system/kernel/scheduler/scheduler_thread.h +++ b/src/system/kernel/scheduler/scheduler_thread.h @@ -165,9 +165,6 @@ inline int32 ThreadData::GetEffectivePriority() const { SCHEDULER_ENTER_FUNCTION(); - - if (fEffectivePriority == -1) - _ComputeEffectivePriority(); return fEffectivePriority; } @@ -184,7 +181,6 @@ ThreadData::IncreasePenalty() TRACE("increasing thread %ld penalty\n", fThread->id); - fEffectivePriority = -1; int32 oldPenalty = fPriorityPenalty++; ASSERT(fThread->priority - oldPenalty >= B_LOWEST_ACTIVE_PRIORITY); @@ -194,6 +190,8 @@ ThreadData::IncreasePenalty() fPriorityPenalty = oldPenalty; fAdditionalPenalty++; } + + _ComputeEffectivePriority(); } @@ -202,13 +200,15 @@ ThreadData::CancelPenalty() { SCHEDULER_ENTER_FUNCTION(); - if (fPriorityPenalty != 0) { - TRACE("cancelling thread %ld penalty\n", fThread->id); - fEffectivePriority = -1; - } + int32 oldPenalty = fPriorityPenalty; fAdditionalPenalty = 0; fPriorityPenalty = 0; + + if (oldPenalty != 0) { + TRACE("cancelling thread %ld penalty\n", fThread->id); + _ComputeEffectivePriority(); + } } @@ -217,7 +217,7 @@ ThreadData::ShouldCancelPenalty() const { SCHEDULER_ENTER_FUNCTION(); - if (fCore == NULL || fWentSleep == 0) + if (fCore == NULL) return false; return fCore->StarvationCounter() != fWentSleepCount @@ -251,7 +251,8 @@ ThreadData::PutBack() { SCHEDULER_ENTER_FUNCTION(); - ComputeLoad(); + if (gTrackLoad) + ComputeLoad(); fWentSleepCount = -1; int32 priority = GetEffectivePriority(); @@ -282,7 +283,8 @@ ThreadData::Enqueue() fThread->state = B_THREAD_READY; - ComputeLoad(); + if (gTrackLoad) + ComputeLoad(); fWentSleepCount = 0; int32 priority = GetEffectivePriority();