scheduler: Improve thread creation performance

This commit is contained in:
Pawel Dziepak 2014-01-06 01:18:37 +01:00
parent cb66faef24
commit 8235bbc996
5 changed files with 64 additions and 68 deletions

View File

@ -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,

View File

@ -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;

View File

@ -112,7 +112,6 @@ public:
void Dump();
};
class CoreEntry : public MinMaxHeapLinkImpl<CoreEntry, int32>,
public DoublyLinkedListLinkImpl<CoreEntry> {
public:
@ -190,7 +189,6 @@ private:
friend class DebugDumper;
} CACHE_LINE_ALIGN;
class CoreLoadHeap : public MinMaxHeap<CoreEntry, int32> {
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
{

View File

@ -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;

View File

@ -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();