scheduler: Improve thread creation performance
This commit is contained in:
parent
cb66faef24
commit
8235bbc996
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user