scheduler: Remove sCorePriorityHeap
sCorePriorityHeap was meant to be a temporary solution anyway. Thread migration and assignment is now entirely based on core load.
This commit is contained in:
@@ -115,15 +115,11 @@ struct CoreEntry : public DoublyLinkedListLinkImpl<CoreEntry> {
|
|||||||
|
|
||||||
int fLoad;
|
int fLoad;
|
||||||
} CACHE_LINE_ALIGN;
|
} CACHE_LINE_ALIGN;
|
||||||
typedef Heap<CoreEntry, int32, HeapLesserCompare<int32>,
|
|
||||||
HeapMemberGetLink<CoreEntry, int32, &CoreEntry::fPriorityHeapLink> >
|
|
||||||
CorePriorityHeap;
|
|
||||||
typedef MinMaxHeap<CoreEntry, int, MinMaxHeapCompare<int>,
|
typedef MinMaxHeap<CoreEntry, int, MinMaxHeapCompare<int>,
|
||||||
MinMaxHeapMemberGetLink<CoreEntry, int, &CoreEntry::fLoadHeapLink> >
|
MinMaxHeapMemberGetLink<CoreEntry, int, &CoreEntry::fLoadHeapLink> >
|
||||||
CoreLoadHeap;
|
CoreLoadHeap;
|
||||||
|
|
||||||
static CoreEntry* sCoreEntries;
|
static CoreEntry* sCoreEntries;
|
||||||
static CorePriorityHeap* sCorePriorityHeap;
|
|
||||||
static CoreLoadHeap* sCoreLoadHeap;
|
static CoreLoadHeap* sCoreLoadHeap;
|
||||||
static CoreLoadHeap* sCoreHighLoadHeap;
|
static CoreLoadHeap* sCoreHighLoadHeap;
|
||||||
|
|
||||||
@@ -390,33 +386,6 @@ dump_core_load_heap(CoreLoadHeap* heap)
|
|||||||
static int
|
static int
|
||||||
dump_cpu_heap(int argc, char** argv)
|
dump_cpu_heap(int argc, char** argv)
|
||||||
{
|
{
|
||||||
CorePriorityHeap temp(sRunQueueCount);
|
|
||||||
|
|
||||||
CoreEntry* entry = sCorePriorityHeap->PeekRoot();
|
|
||||||
if (entry != NULL)
|
|
||||||
kprintf("core priority\n");
|
|
||||||
else
|
|
||||||
kprintf("No active cores.\n");
|
|
||||||
|
|
||||||
while (entry) {
|
|
||||||
int32 core = entry->fCoreID;
|
|
||||||
int32 key = CorePriorityHeap::GetKey(entry);
|
|
||||||
kprintf("%4" B_PRId32 " %8" B_PRId32 "\n", core, key);
|
|
||||||
|
|
||||||
sCorePriorityHeap->RemoveRoot();
|
|
||||||
temp.Insert(entry, key);
|
|
||||||
|
|
||||||
entry = sCorePriorityHeap->PeekRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
entry = temp.PeekRoot();
|
|
||||||
while (entry) {
|
|
||||||
int32 key = CorePriorityHeap::GetKey(entry);
|
|
||||||
temp.RemoveRoot();
|
|
||||||
sCorePriorityHeap->Insert(entry, key);
|
|
||||||
entry = temp.PeekRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
kprintf("\ncore load\n");
|
kprintf("\ncore load\n");
|
||||||
dump_core_load_heap(sCoreLoadHeap);
|
dump_core_load_heap(sCoreLoadHeap);
|
||||||
kprintf("---------\n");
|
kprintf("---------\n");
|
||||||
@@ -664,6 +633,8 @@ update_priority_heaps(int32 cpu, int32 priority)
|
|||||||
{
|
{
|
||||||
int32 core = sCPUToCore[cpu];
|
int32 core = sCPUToCore[cpu];
|
||||||
|
|
||||||
|
int32 corePriority = CPUHeap::GetKey(sCPUPriorityHeaps[core].PeekMaximum());
|
||||||
|
|
||||||
sCPUPriorityHeaps[core].ModifyKey(&sCPUEntries[cpu], priority);
|
sCPUPriorityHeaps[core].ModifyKey(&sCPUEntries[cpu], priority);
|
||||||
|
|
||||||
if (sSingleCore)
|
if (sSingleCore)
|
||||||
@@ -671,72 +642,63 @@ update_priority_heaps(int32 cpu, int32 priority)
|
|||||||
|
|
||||||
int32 maxPriority
|
int32 maxPriority
|
||||||
= CPUHeap::GetKey(sCPUPriorityHeaps[core].PeekMaximum());
|
= CPUHeap::GetKey(sCPUPriorityHeaps[core].PeekMaximum());
|
||||||
int32 corePriority = CorePriorityHeap::GetKey(&sCoreEntries[core]);
|
|
||||||
|
|
||||||
if (corePriority != maxPriority) {
|
if (corePriority == maxPriority)
|
||||||
if (maxPriority == B_IDLE_PRIORITY) {
|
return;
|
||||||
sCorePriorityHeap->ModifyKey(&sCoreEntries[core], B_IDLE_PRIORITY);
|
|
||||||
ASSERT(sCorePriorityHeap->PeekRoot() == &sCoreEntries[core]);
|
|
||||||
sCorePriorityHeap->RemoveRoot();
|
|
||||||
} else if (corePriority == B_IDLE_PRIORITY)
|
|
||||||
sCorePriorityHeap->Insert(&sCoreEntries[core], maxPriority);
|
|
||||||
else
|
|
||||||
sCorePriorityHeap->ModifyKey(&sCoreEntries[core], maxPriority);
|
|
||||||
|
|
||||||
int32 package = sCPUToPackage[cpu];
|
int32 package = sCPUToPackage[cpu];
|
||||||
PackageEntry* packageEntry = &sPackageEntries[package];
|
PackageEntry* packageEntry = &sPackageEntries[package];
|
||||||
if (maxPriority == B_IDLE_PRIORITY) {
|
if (maxPriority == B_IDLE_PRIORITY) {
|
||||||
// core goes idle
|
// core goes idle
|
||||||
ASSERT(packageEntry->fIdleCoreCount >= 0);
|
ASSERT(packageEntry->fIdleCoreCount >= 0);
|
||||||
ASSERT(packageEntry->fIdleCoreCount < packageEntry->fCoreCount);
|
ASSERT(packageEntry->fIdleCoreCount < packageEntry->fCoreCount);
|
||||||
|
|
||||||
packageEntry->fIdleCoreCount++;
|
packageEntry->fIdleCoreCount++;
|
||||||
packageEntry->fIdleCores.Add(&sCoreEntries[core]);
|
packageEntry->fIdleCores.Add(&sCoreEntries[core]);
|
||||||
|
|
||||||
if (packageEntry->fIdleCoreCount == 1) {
|
if (packageEntry->fIdleCoreCount == 1) {
|
||||||
// first core on that package to go idle
|
// first core on that package to go idle
|
||||||
|
|
||||||
if (packageEntry->fCoreCount > 1)
|
|
||||||
sPackageUsageHeap->Insert(packageEntry, 1);
|
|
||||||
else
|
|
||||||
sIdlePackageList->Add(packageEntry);
|
|
||||||
} else if (packageEntry->fIdleCoreCount
|
|
||||||
== packageEntry->fCoreCount) {
|
|
||||||
// package goes idle
|
|
||||||
sPackageUsageHeap->ModifyKey(packageEntry, 0);
|
|
||||||
ASSERT(sPackageUsageHeap->PeekMinimum() == packageEntry);
|
|
||||||
sPackageUsageHeap->RemoveMinimum();
|
|
||||||
|
|
||||||
|
if (packageEntry->fCoreCount > 1)
|
||||||
|
sPackageUsageHeap->Insert(packageEntry, 1);
|
||||||
|
else
|
||||||
sIdlePackageList->Add(packageEntry);
|
sIdlePackageList->Add(packageEntry);
|
||||||
} else {
|
} else if (packageEntry->fIdleCoreCount
|
||||||
sPackageUsageHeap->ModifyKey(packageEntry,
|
== packageEntry->fCoreCount) {
|
||||||
packageEntry->fIdleCoreCount);
|
// package goes idle
|
||||||
}
|
sPackageUsageHeap->ModifyKey(packageEntry, 0);
|
||||||
} else if (corePriority == B_IDLE_PRIORITY) {
|
ASSERT(sPackageUsageHeap->PeekMinimum() == packageEntry);
|
||||||
// core wakes up
|
sPackageUsageHeap->RemoveMinimum();
|
||||||
ASSERT(packageEntry->fIdleCoreCount > 0);
|
|
||||||
ASSERT(packageEntry->fIdleCoreCount <= packageEntry->fCoreCount);
|
sIdlePackageList->Add(packageEntry);
|
||||||
|
} else {
|
||||||
packageEntry->fIdleCoreCount--;
|
sPackageUsageHeap->ModifyKey(packageEntry,
|
||||||
packageEntry->fIdleCores.Remove(&sCoreEntries[core]);
|
packageEntry->fIdleCoreCount);
|
||||||
|
}
|
||||||
if (packageEntry->fIdleCoreCount + 1 == packageEntry->fCoreCount) {
|
} else if (corePriority == B_IDLE_PRIORITY) {
|
||||||
// package wakes up
|
// core wakes up
|
||||||
sIdlePackageList->Remove(packageEntry);
|
ASSERT(packageEntry->fIdleCoreCount > 0);
|
||||||
|
ASSERT(packageEntry->fIdleCoreCount <= packageEntry->fCoreCount);
|
||||||
if (packageEntry->fIdleCoreCount > 0) {
|
|
||||||
sPackageUsageHeap->Insert(packageEntry,
|
packageEntry->fIdleCoreCount--;
|
||||||
packageEntry->fIdleCoreCount);
|
packageEntry->fIdleCores.Remove(&sCoreEntries[core]);
|
||||||
}
|
|
||||||
} else if (packageEntry->fIdleCoreCount == 0) {
|
if (packageEntry->fIdleCoreCount + 1 == packageEntry->fCoreCount) {
|
||||||
// no more idle cores in the package
|
// package wakes up
|
||||||
sPackageUsageHeap->ModifyKey(packageEntry, 0);
|
sIdlePackageList->Remove(packageEntry);
|
||||||
ASSERT(sPackageUsageHeap->PeekMinimum() == packageEntry);
|
|
||||||
sPackageUsageHeap->RemoveMinimum();
|
if (packageEntry->fIdleCoreCount > 0) {
|
||||||
} else {
|
sPackageUsageHeap->Insert(packageEntry,
|
||||||
sPackageUsageHeap->ModifyKey(packageEntry,
|
|
||||||
packageEntry->fIdleCoreCount);
|
packageEntry->fIdleCoreCount);
|
||||||
}
|
}
|
||||||
|
} else if (packageEntry->fIdleCoreCount == 0) {
|
||||||
|
// no more idle cores in the package
|
||||||
|
sPackageUsageHeap->ModifyKey(packageEntry, 0);
|
||||||
|
ASSERT(sPackageUsageHeap->PeekMinimum() == packageEntry);
|
||||||
|
sPackageUsageHeap->RemoveMinimum();
|
||||||
|
} else {
|
||||||
|
sPackageUsageHeap->ModifyKey(packageEntry,
|
||||||
|
packageEntry->fIdleCoreCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -757,14 +719,9 @@ choose_core_low_latency(Thread* thread)
|
|||||||
entry = package->fIdleCores.Last();
|
entry = package->fIdleCores.Last();
|
||||||
} else {
|
} else {
|
||||||
// no idle cores, use least occupied core
|
// no idle cores, use least occupied core
|
||||||
entry = sCorePriorityHeap->PeekRoot();
|
entry = sCoreLoadHeap->PeekMinimum();
|
||||||
|
if (entry == NULL)
|
||||||
int32 priority = get_effective_priority(thread);
|
entry = sCoreHighLoadHeap->PeekMinimum();
|
||||||
if (CorePriorityHeap::GetKey(entry) >= priority) {
|
|
||||||
entry = sCoreLoadHeap->PeekMinimum();
|
|
||||||
if (entry == NULL)
|
|
||||||
entry = sCoreHighLoadHeap->PeekMinimum();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(entry != NULL);
|
ASSERT(entry != NULL);
|
||||||
@@ -792,11 +749,9 @@ choose_core_power_saving(Thread* thread)
|
|||||||
if (sSmallTaskCore < 0)
|
if (sSmallTaskCore < 0)
|
||||||
sSmallTaskCore = sCoreLoadHeap->PeekMaximum()->fCoreID;
|
sSmallTaskCore = sCoreLoadHeap->PeekMaximum()->fCoreID;
|
||||||
entry = &sCoreEntries[sSmallTaskCore];
|
entry = &sCoreEntries[sSmallTaskCore];
|
||||||
} else if (sCorePriorityHeap->PeekRoot() != NULL
|
} else if (sCoreLoadHeap->PeekMinimum() != NULL) {
|
||||||
&& CorePriorityHeap::GetKey(sCorePriorityHeap->PeekRoot())
|
|
||||||
< priority) {
|
|
||||||
// run immediately on already woken core
|
// run immediately on already woken core
|
||||||
entry = sCorePriorityHeap->PeekRoot();
|
entry = sCoreLoadHeap->PeekMinimum();
|
||||||
} else if (sPackageUsageHeap->PeekMinimum() != NULL) {
|
} else if (sPackageUsageHeap->PeekMinimum() != NULL) {
|
||||||
// wake new core
|
// wake new core
|
||||||
PackageEntry* package = sPackageUsageHeap->PeekMinimum();
|
PackageEntry* package = sPackageUsageHeap->PeekMinimum();
|
||||||
@@ -1749,11 +1704,6 @@ _scheduler_init()
|
|||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
ArrayDeleter<CoreEntry> coreEntriesDeleter(sCoreEntries);
|
ArrayDeleter<CoreEntry> coreEntriesDeleter(sCoreEntries);
|
||||||
|
|
||||||
sCorePriorityHeap = new CorePriorityHeap(coreCount);
|
|
||||||
if (sCorePriorityHeap == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
ObjectDeleter<CorePriorityHeap> corePriorityHeapDeleter(sCorePriorityHeap);
|
|
||||||
|
|
||||||
sCoreLoadHeap = new CoreLoadHeap;
|
sCoreLoadHeap = new CoreLoadHeap;
|
||||||
if (sCoreLoadHeap == NULL)
|
if (sCoreLoadHeap == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
@@ -1770,11 +1720,6 @@ _scheduler_init()
|
|||||||
status_t result = sCoreLoadHeap->Insert(&sCoreEntries[i], 0);
|
status_t result = sCoreLoadHeap->Insert(&sCoreEntries[i], 0);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
result = sCorePriorityHeap->Insert(&sCoreEntries[i], B_IDLE_PRIORITY);
|
|
||||||
if (result != B_OK)
|
|
||||||
return result;
|
|
||||||
sCorePriorityHeap->RemoveRoot();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sCPUPriorityHeaps = new CPUHeap[coreCount];
|
sCPUPriorityHeaps = new CPUHeap[coreCount];
|
||||||
@@ -1845,7 +1790,6 @@ _scheduler_init()
|
|||||||
pinnedRunQueuesDeleter.Detach();
|
pinnedRunQueuesDeleter.Detach();
|
||||||
coreHighLoadHeapDeleter.Detach();
|
coreHighLoadHeapDeleter.Detach();
|
||||||
coreLoadHeapDeleter.Detach();
|
coreLoadHeapDeleter.Detach();
|
||||||
corePriorityHeapDeleter.Detach();
|
|
||||||
cpuPriorityHeapDeleter.Detach();
|
cpuPriorityHeapDeleter.Detach();
|
||||||
coreEntriesDeleter.Detach();
|
coreEntriesDeleter.Detach();
|
||||||
cpuEntriesDeleter.Detach();
|
cpuEntriesDeleter.Detach();
|
||||||
|
|||||||
Reference in New Issue
Block a user