scheduler: Use single ended heap for CPU heap

This commit is contained in:
Pawel Dziepak
2013-12-28 21:47:35 +01:00
parent 712f37e19e
commit ef8e55a1d0
5 changed files with 55 additions and 30 deletions
+1 -1
View File
@@ -138,7 +138,7 @@ rebalance_irqs(bool idle)
other = gCoreHighLoadHeap.PeekMinimum(); other = gCoreHighLoadHeap.PeekMinimum();
coreLocker.Unlock(); coreLocker.Unlock();
int32 newCPU = other->CPUHeap()->PeekMinimum()->ID(); int32 newCPU = other->CPUHeap()->PeekRoot()->ID();
ASSERT(other != NULL); ASSERT(other != NULL);
+2 -2
View File
@@ -174,7 +174,7 @@ pack_irqs()
irq_assignment* irq = (irq_assignment*)list_get_first_item(&cpu->irqs); irq_assignment* irq = (irq_assignment*)list_get_first_item(&cpu->irqs);
locker.Unlock(); locker.Unlock();
int32 newCPU = smallTaskCore->CPUHeap()->PeekMinimum()->ID(); int32 newCPU = smallTaskCore->CPUHeap()->PeekRoot()->ID();
if (newCPU != cpu->cpu_num) if (newCPU != cpu->cpu_num)
assign_io_interrupt_to_cpu(irq->irq, newCPU); assign_io_interrupt_to_cpu(irq->irq, newCPU);
@@ -219,7 +219,7 @@ rebalance_irqs(bool idle)
coreLocker.Unlock(); coreLocker.Unlock();
if (other == NULL) if (other == NULL)
return; return;
int32 newCPU = other->CPUHeap()->PeekMinimum()->ID(); int32 newCPU = other->CPUHeap()->PeekRoot()->ID();
CoreEntry* core = CoreEntry::GetCore(smp_get_current_cpu()); CoreEntry* core = CoreEntry::GetCore(smp_get_current_cpu());
if (other == core) if (other == core)
+44 -24
View File
@@ -146,22 +146,15 @@ CPUEntry::UpdatePriority(int32 priority)
if (gCPU[fCPUNumber].disabled) if (gCPU[fCPUNumber].disabled)
return; return;
CPUPriorityHeap* cpuHeap = fCore->CPUHeap(); int32 oldPriority = CPUPriorityHeap::GetKey(this);
int32 corePriority = CPUPriorityHeap::GetKey(cpuHeap->PeekMaximum()); if (oldPriority == priority)
cpuHeap->ModifyKey(this, priority);
if (gSingleCore)
return; return;
fCore->CPUHeap()->ModifyKey(this, priority);
int32 maxPriority = CPUPriorityHeap::GetKey(cpuHeap->PeekMaximum()); if (oldPriority == B_IDLE_PRIORITY)
if (corePriority == maxPriority) fCore->CPUWakesUp(this);
return; else if (priority == B_IDLE_PRIORITY)
fCore->CPUGoesIdle(this);
PackageEntry* packageEntry = fCore->Package();
if (maxPriority == B_IDLE_PRIORITY)
packageEntry->CoreGoesIdle(fCore);
else if (corePriority == B_IDLE_PRIORITY)
packageEntry->CoreWakesUp(fCore);
} }
@@ -292,7 +285,7 @@ CPUEntry::_RequestPerformanceLevel(ThreadData* threadData)
CPUPriorityHeap::CPUPriorityHeap(int32 cpuCount) CPUPriorityHeap::CPUPriorityHeap(int32 cpuCount)
: :
MinMaxHeap<CPUEntry, int32>(cpuCount) Heap<CPUEntry, int32>(cpuCount)
{ {
} }
@@ -301,25 +294,25 @@ void
CPUPriorityHeap::Dump() CPUPriorityHeap::Dump()
{ {
kprintf("cpu priority load\n"); kprintf("cpu priority load\n");
CPUEntry* entry = PeekMinimum(); CPUEntry* entry = PeekRoot();
while (entry) { while (entry) {
int32 cpu = entry->ID(); int32 cpu = entry->ID();
int32 key = GetKey(entry); int32 key = GetKey(entry);
kprintf("%3" B_PRId32 " %8" B_PRId32 " %3" B_PRId32 "%%\n", cpu, key, kprintf("%3" B_PRId32 " %8" B_PRId32 " %3" B_PRId32 "%%\n", cpu, key,
entry->GetLoad() / 10); entry->GetLoad() / 10);
RemoveMinimum(); RemoveRoot();
sDebugCPUHeap.Insert(entry, key); sDebugCPUHeap.Insert(entry, key);
entry = PeekMinimum(); entry = PeekRoot();
} }
entry = sDebugCPUHeap.PeekMinimum(); entry = sDebugCPUHeap.PeekRoot();
while (entry) { while (entry) {
int32 key = GetKey(entry); int32 key = GetKey(entry);
sDebugCPUHeap.RemoveMinimum(); sDebugCPUHeap.RemoveRoot();
Insert(entry, key); Insert(entry, key);
entry = sDebugCPUHeap.PeekMinimum(); entry = sDebugCPUHeap.PeekRoot();
} }
} }
@@ -327,6 +320,7 @@ CPUPriorityHeap::Dump()
CoreEntry::CoreEntry() CoreEntry::CoreEntry()
: :
fCPUCount(0), fCPUCount(0),
fCPUIdleCount(0),
fStarvationCounter(0), fStarvationCounter(0),
fThreadCount(0), fThreadCount(0),
fActiveTime(0), fActiveTime(0),
@@ -449,10 +443,33 @@ CoreEntry::UpdateLoad(int32 delta)
} }
inline void
CoreEntry::CPUGoesIdle(CPUEntry* /* cpu */)
{
ASSERT(fCPUIdleCount < fCPUCount);
if (++fCPUIdleCount == fCPUCount)
fPackage->CoreGoesIdle(this);
}
inline void
CoreEntry::CPUWakesUp(CPUEntry* /* cpu */)
{
ASSERT(fCPUIdleCount > 0);
if (fCPUIdleCount-- == fCPUCount)
fPackage->CoreWakesUp(this);
}
void void
CoreEntry::AddCPU(CPUEntry* cpu) CoreEntry::AddCPU(CPUEntry* cpu)
{ {
ASSERT(fCPUCount >= 0); ASSERT(fCPUCount >= 0);
ASSERT(fCPUIdleCount >= 0);
fCPUIdleCount++;
if (fCPUCount++ == 0) { if (fCPUCount++ == 0) {
// core has been reenabled // core has been reenabled
fLoad = 0; fLoad = 0;
@@ -470,6 +487,9 @@ void
CoreEntry::RemoveCPU(CPUEntry* cpu, ThreadProcessing& threadPostProcessing) CoreEntry::RemoveCPU(CPUEntry* cpu, ThreadProcessing& threadPostProcessing)
{ {
ASSERT(fCPUCount > 0); ASSERT(fCPUCount > 0);
ASSERT(fCPUIdleCount > 0);
fCPUIdleCount--;
if (--fCPUCount == 0) { if (--fCPUCount == 0) {
// core has been disabled // core has been disabled
if (fHighLoad) { if (fHighLoad) {
@@ -499,9 +519,9 @@ CoreEntry::RemoveCPU(CPUEntry* cpu, ThreadProcessing& threadPostProcessing)
fThreadCount = 0; fThreadCount = 0;
} }
fCPUHeap.ModifyKey(cpu, THREAD_MAX_SET_PRIORITY + 1); fCPUHeap.ModifyKey(cpu, -1);
ASSERT(fCPUHeap.PeekMaximum() == cpu); ASSERT(fCPUHeap.PeekRoot() == cpu);
fCPUHeap.RemoveMaximum(); fCPUHeap.RemoveRoot();
ASSERT(cpu->GetLoad() >= 0 && cpu->GetLoad() <= kMaxLoad); ASSERT(cpu->GetLoad() >= 0 && cpu->GetLoad() <= kMaxLoad);
fLoad -= cpu->GetLoad(); fLoad -= cpu->GetLoad();
+7 -2
View File
@@ -11,6 +11,7 @@
#include <thread.h> #include <thread.h>
#include <util/AutoLock.h> #include <util/AutoLock.h>
#include <util/MinMaxHeap.h> #include <util/MinMaxHeap.h>
#include <util/Heap.h>
#include <cpufreq.h> #include <cpufreq.h>
@@ -41,7 +42,7 @@ public:
void Dump() const; void Dump() const;
}; };
class CPUEntry : public MinMaxHeapLinkImpl<CPUEntry, int32> { class CPUEntry : public HeapLinkImpl<CPUEntry, int32> {
public: public:
CPUEntry(); CPUEntry();
@@ -99,7 +100,7 @@ private:
friend class DebugDumper; friend class DebugDumper;
} CACHE_LINE_ALIGN; } CACHE_LINE_ALIGN;
class CPUPriorityHeap : public MinMaxHeap<CPUEntry, int32> { class CPUPriorityHeap : public Heap<CPUEntry, int32> {
public: public:
CPUPriorityHeap() { } CPUPriorityHeap() { }
CPUPriorityHeap(int32 cpuCount); CPUPriorityHeap(int32 cpuCount);
@@ -146,6 +147,9 @@ public:
inline int32 StarvationCounter() const; inline int32 StarvationCounter() const;
inline void CPUGoesIdle(CPUEntry* cpu);
inline void CPUWakesUp(CPUEntry* cpu);
void AddCPU(CPUEntry* cpu); void AddCPU(CPUEntry* cpu);
void RemoveCPU(CPUEntry* cpu, void RemoveCPU(CPUEntry* cpu,
ThreadProcessing& ThreadProcessing&
@@ -161,6 +165,7 @@ private:
PackageEntry* fPackage; PackageEntry* fPackage;
int32 fCPUCount; int32 fCPUCount;
int32 fCPUIdleCount;
CPUPriorityHeap fCPUHeap; CPUPriorityHeap fCPUHeap;
spinlock fCPULock; spinlock fCPULock;
@@ -205,7 +205,7 @@ ThreadData::_ChooseCPU(CoreEntry* core, bool& rescheduleNeeded) const
} }
CoreCPUHeapLocker _(core); CoreCPUHeapLocker _(core);
CPUEntry* cpu = core->CPUHeap()->PeekMinimum(); CPUEntry* cpu = core->CPUHeap()->PeekRoot();
ASSERT(cpu != NULL); ASSERT(cpu != NULL);
if (CPUPriorityHeap::GetKey(cpu) < threadPriority) { if (CPUPriorityHeap::GetKey(cpu) < threadPriority) {