scheduler: Improve thread creation performance

This commit is contained in:
Pawel Dziepak
2014-01-06 01:22:53 +01:00
parent cb66faef24
commit 8235bbc996
5 changed files with 64 additions and 68 deletions
+1 -1
View File
@@ -383,7 +383,7 @@ reschedule(int32 nextState)
int32 thisCPU = smp_get_current_cpu(); int32 thisCPU = smp_get_current_cpu();
CPUEntry* cpu = &gCPUEntries[thisCPU]; CPUEntry* cpu = CPUEntry::GetCPU(thisCPU);
CoreEntry* core = CoreEntry::GetCore(thisCPU); CoreEntry* core = CoreEntry::GetCore(thisCPU);
TRACE("reschedule(): cpu %ld, current thread = %ld\n", thisCPU, TRACE("reschedule(): cpu %ld, current thread = %ld\n", thisCPU,
+20 -8
View File
@@ -123,6 +123,14 @@ CPUEntry::Remove(ThreadData* thread)
} }
inline ThreadData*
CoreEntry::PeekThread() const
{
SCHEDULER_ENTER_FUNCTION();
return fRunQueue.PeekMaximum();
}
inline ThreadData* inline ThreadData*
CPUEntry::PeekThread() const CPUEntry::PeekThread() const
{ {
@@ -152,6 +160,9 @@ CPUEntry::UpdatePriority(int32 priority)
return; return;
fCore->CPUHeap()->ModifyKey(this, priority); fCore->CPUHeap()->ModifyKey(this, priority);
if (gSingleCore)
return;
if (oldPriority == B_IDLE_PRIORITY) if (oldPriority == B_IDLE_PRIORITY)
fCore->CPUWakesUp(this); fCore->CPUWakesUp(this);
else if (priority == B_IDLE_PRIORITY) else if (priority == B_IDLE_PRIORITY)
@@ -164,6 +175,7 @@ CPUEntry::ComputeLoad()
{ {
SCHEDULER_ENTER_FUNCTION(); SCHEDULER_ENTER_FUNCTION();
ASSERT(gTrackLoad);
ASSERT(fCPUNumber == smp_get_current_cpu()); ASSERT(fCPUNumber == smp_get_current_cpu());
int oldLoad = compute_load(fMeasureTime, fMeasureActiveTime, fLoad); int oldLoad = compute_load(fMeasureTime, fMeasureActiveTime, fLoad);
@@ -244,10 +256,12 @@ CPUEntry::TrackActivity(ThreadData* oldThreadData, ThreadData* nextThreadData)
oldThreadData->UpdateActivity(active); oldThreadData->UpdateActivity(active);
} }
oldThreadData->ComputeLoad(); if (gTrackLoad) {
nextThreadData->ComputeLoad(); oldThreadData->ComputeLoad();
if (gTrackLoad && !cpuEntry->disabled) nextThreadData->ComputeLoad();
ComputeLoad(); if (!cpuEntry->disabled)
ComputeLoad();
}
Thread* nextThread = nextThreadData->GetThread(); Thread* nextThread = nextThreadData->GetThread();
if (!thread_is_idle_thread(nextThread)) { if (!thread_is_idle_thread(nextThread)) {
@@ -256,19 +270,17 @@ CPUEntry::TrackActivity(ThreadData* oldThreadData, ThreadData* nextThreadData)
nextThreadData->SetLastInterruptTime(cpuEntry->interrupt_time); nextThreadData->SetLastInterruptTime(cpuEntry->interrupt_time);
if (gCPUFrequencyManagement)
_RequestPerformanceLevel(nextThreadData); _RequestPerformanceLevel(nextThreadData);
} }
} }
inline void void
CPUEntry::_RequestPerformanceLevel(ThreadData* threadData) CPUEntry::_RequestPerformanceLevel(ThreadData* threadData)
{ {
SCHEDULER_ENTER_FUNCTION(); SCHEDULER_ENTER_FUNCTION();
if (!gCPUFrequencyManagement)
return;
if (gCPU[fCPUNumber].disabled) { if (gCPU[fCPUNumber].disabled) {
decrease_cpu_performance(kCPUPerformanceScaleMax); decrease_cpu_performance(kCPUPerformanceScaleMax);
return; return;
@@ -112,7 +112,6 @@ public:
void Dump(); void Dump();
}; };
class CoreEntry : public MinMaxHeapLinkImpl<CoreEntry, int32>, class CoreEntry : public MinMaxHeapLinkImpl<CoreEntry, int32>,
public DoublyLinkedListLinkImpl<CoreEntry> { public DoublyLinkedListLinkImpl<CoreEntry> {
public: public:
@@ -190,7 +189,6 @@ private:
friend class DebugDumper; friend class DebugDumper;
} CACHE_LINE_ALIGN; } CACHE_LINE_ALIGN;
class CoreLoadHeap : public MinMaxHeap<CoreEntry, int32> { class CoreLoadHeap : public MinMaxHeap<CoreEntry, int32> {
public: public:
CoreLoadHeap() { } CoreLoadHeap() { }
@@ -356,14 +354,6 @@ CoreEntry::IncreaseActiveTime(bigtime_t activeTime)
} }
inline ThreadData*
CoreEntry::PeekThread() const
{
SCHEDULER_ENTER_FUNCTION();
return fRunQueue.PeekMaximum();
}
inline bigtime_t inline bigtime_t
CoreEntry::GetActiveTime() const CoreEntry::GetActiveTime() const
{ {
@@ -12,6 +12,28 @@ using namespace Scheduler;
static bigtime_t sQuantumLengths[THREAD_MAX_SET_PRIORITY + 1]; 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* inline CoreEntry*
ThreadData::_ChooseCore() const ThreadData::_ChooseCore() const
{ {
@@ -30,7 +52,8 @@ ThreadData::_ChooseCPU(CoreEntry* core, bool& rescheduleNeeded) const
int32 threadPriority = GetEffectivePriority(); int32 threadPriority = GetEffectivePriority();
if (fThread->previous_cpu != NULL) { 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) { if (previousCPU->Core() == core && !fThread->previous_cpu->disabled) {
CoreCPUHeapLocker _(core); CoreCPUHeapLocker _(core);
if (CPUPriorityHeap::GetKey(previousCPU) < threadPriority) { if (CPUPriorityHeap::GetKey(previousCPU) < threadPriority) {
@@ -74,48 +97,18 @@ ThreadData::ThreadData(Thread* thread)
void void
ThreadData::Init() ThreadData::Init()
{ {
fAdditionalPenalty = 0; _InitBase();
fEffectivePriority = -1;
fTimeLeft = 0; ThreadData* currentThreadData = thread_get_current_thread()->scheduler_data;
fStolenTime = 0; fCore = currentThreadData->fCore;
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;
}
} }
void void
ThreadData::Init(CoreEntry* core) ThreadData::Init(CoreEntry* core)
{ {
Init(); _InitBase();
fCore = core; fCore = core;
} }
@@ -172,8 +165,7 @@ ThreadData::ComputeLoad()
{ {
SCHEDULER_ENTER_FUNCTION(); SCHEDULER_ENTER_FUNCTION();
if (!gTrackLoad) ASSERT(gTrackLoad);
return;
if (fLastInterruptTime > 0) { if (fLastInterruptTime > 0) {
bigtime_t interruptTime = gCPU[smp_get_current_cpu()].interrupt_time; bigtime_t interruptTime = gCPU[smp_get_current_cpu()].interrupt_time;
+13 -11
View File
@@ -165,9 +165,6 @@ inline int32
ThreadData::GetEffectivePriority() const ThreadData::GetEffectivePriority() const
{ {
SCHEDULER_ENTER_FUNCTION(); SCHEDULER_ENTER_FUNCTION();
if (fEffectivePriority == -1)
_ComputeEffectivePriority();
return fEffectivePriority; return fEffectivePriority;
} }
@@ -184,7 +181,6 @@ ThreadData::IncreasePenalty()
TRACE("increasing thread %ld penalty\n", fThread->id); TRACE("increasing thread %ld penalty\n", fThread->id);
fEffectivePriority = -1;
int32 oldPenalty = fPriorityPenalty++; int32 oldPenalty = fPriorityPenalty++;
ASSERT(fThread->priority - oldPenalty >= B_LOWEST_ACTIVE_PRIORITY); ASSERT(fThread->priority - oldPenalty >= B_LOWEST_ACTIVE_PRIORITY);
@@ -194,6 +190,8 @@ ThreadData::IncreasePenalty()
fPriorityPenalty = oldPenalty; fPriorityPenalty = oldPenalty;
fAdditionalPenalty++; fAdditionalPenalty++;
} }
_ComputeEffectivePriority();
} }
@@ -202,13 +200,15 @@ ThreadData::CancelPenalty()
{ {
SCHEDULER_ENTER_FUNCTION(); SCHEDULER_ENTER_FUNCTION();
if (fPriorityPenalty != 0) { int32 oldPenalty = fPriorityPenalty;
TRACE("cancelling thread %ld penalty\n", fThread->id);
fEffectivePriority = -1;
}
fAdditionalPenalty = 0; fAdditionalPenalty = 0;
fPriorityPenalty = 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(); SCHEDULER_ENTER_FUNCTION();
if (fCore == NULL || fWentSleep == 0) if (fCore == NULL)
return false; return false;
return fCore->StarvationCounter() != fWentSleepCount return fCore->StarvationCounter() != fWentSleepCount
@@ -251,7 +251,8 @@ ThreadData::PutBack()
{ {
SCHEDULER_ENTER_FUNCTION(); SCHEDULER_ENTER_FUNCTION();
ComputeLoad(); if (gTrackLoad)
ComputeLoad();
fWentSleepCount = -1; fWentSleepCount = -1;
int32 priority = GetEffectivePriority(); int32 priority = GetEffectivePriority();
@@ -282,7 +283,8 @@ ThreadData::Enqueue()
fThread->state = B_THREAD_READY; fThread->state = B_THREAD_READY;
ComputeLoad(); if (gTrackLoad)
ComputeLoad();
fWentSleepCount = 0; fWentSleepCount = 0;
int32 priority = GetEffectivePriority(); int32 priority = GetEffectivePriority();