scheduler: Let ThreadData::ShouldRebalance() choose the actual core

Currently, ThreadData::ShouldRebalance() (and mode specific functions
it calls) only decides whether to migrate thread to another core or not.
However, in most cases it actually needs to find the best candidate for
new core so it could as well return that information.
This commit is contained in:
Pawel Dziepak
2014-04-09 03:24:34 +02:00
parent e439b00397
commit 1bba129c56
5 changed files with 30 additions and 30 deletions
+11 -10
View File
@@ -72,18 +72,19 @@ choose_core(const ThreadData* /* threadData */)
}
static bool
should_rebalance(const ThreadData* threadData)
static CoreEntry*
rebalance(const ThreadData* threadData)
{
SCHEDULER_ENTER_FUNCTION();
int32 coreLoad = threadData->Core()->GetLoad();
int32 threadLoad = threadData->GetLoad() / threadData->Core()->CPUCount();
CoreEntry* core = threadData->Core();
int32 coreLoad = core->GetLoad();
int32 threadLoad = threadData->GetLoad() / core->CPUCount();
// If the thread produces more than 50% of the load, leave it here. In
// such situation it is better to move other threads away.
if (threadLoad >= coreLoad / 2)
return false;
return core;
// Get the least loaded core.
ReadSpinLocker coreLocker(gCoreHeapsLock);
@@ -93,18 +94,18 @@ should_rebalance(const ThreadData* threadData)
coreLocker.Unlock();
ASSERT(other != NULL);
if (other == threadData->Core())
return false;
if (other == core)
return core;
// If there are idle cores give them some work unless that will cause
// the current core to become idle.
int32 coreNewLoad = coreLoad - threadLoad;
if (other->GetLoad() == 0 && coreNewLoad != 0)
return true;
return other;
// Attempt to keep load balanced.
int32 otherNewLoad = other->GetLoad() + threadLoad;
return coreNewLoad - otherNewLoad >= kLoadDifference;
return coreNewLoad - otherNewLoad >= kLoadDifference ? other : core;
}
@@ -168,7 +169,7 @@ scheduler_mode_operations gSchedulerLowLatencyMode = {
set_cpu_enabled,
has_cache_expired,
choose_core,
should_rebalance,
rebalance,
rebalance_irqs,
};
+12 -12
View File
@@ -114,8 +114,8 @@ choose_core(const ThreadData* threadData)
}
static bool
should_rebalance(const ThreadData* threadData)
static CoreEntry*
rebalance(const ThreadData* threadData)
{
SCHEDULER_ENTER_FUNCTION();
@@ -128,15 +128,15 @@ should_rebalance(const ThreadData* threadData)
if (coreLoad > kHighLoad) {
if (sSmallTaskCore == core) {
sSmallTaskCore = NULL;
choose_small_task_core();
CoreEntry* smallTaskCore = choose_small_task_core();
if (threadLoad > coreLoad / 3)
return false;
return coreLoad > kVeryHighLoad;
return core;
return coreLoad > kVeryHighLoad ? smallTaskCore : core;
}
if (threadLoad >= coreLoad / 2)
return false;
return core;
ReadSpinLocker coreLocker(gCoreHeapsLock);
CoreEntry* other = gCoreLoadHeap.PeekMaximum();
@@ -147,17 +147,17 @@ should_rebalance(const ThreadData* threadData)
int32 coreNewLoad = coreLoad - threadLoad;
int32 otherNewLoad = other->GetLoad() + threadLoad;
return coreNewLoad - otherNewLoad >= kLoadDifference / 2;
return coreNewLoad - otherNewLoad >= kLoadDifference / 2 ? other : core;
}
if (coreLoad >= kMediumLoad)
return false;
return core;
CoreEntry* smallTaskCore = choose_small_task_core();
if (smallTaskCore == NULL)
return false;
return smallTaskCore != core
&& smallTaskCore->GetLoad() + threadLoad < kHighLoad;
return core;
return smallTaskCore->GetLoad() + threadLoad < kHighLoad
? smallTaskCore : core;
}
@@ -249,7 +249,7 @@ scheduler_mode_operations gSchedulerPowerSavingMode = {
set_cpu_enabled,
has_cache_expired,
choose_core,
should_rebalance,
rebalance,
rebalance_irqs,
};
+2 -3
View File
@@ -111,9 +111,8 @@ enqueue(Thread* thread, bool newOne)
} else if (gSingleCore)
targetCore = &gCoreEntries[0];
else if (threadData->Core() != NULL
&& (!newOne || !threadData->HasCacheExpired())
&& !threadData->ShouldRebalance()) {
targetCore = threadData->Core();
&& (!newOne || !threadData->HasCacheExpired())) {
targetCore = threadData->Rebalance();
}
bool rescheduleNeeded = threadData->ChooseCoreAndCPU(targetCore, targetCPU);
@@ -25,7 +25,7 @@ struct scheduler_mode_operations {
const Scheduler::ThreadData* threadData);
Scheduler::CoreEntry* (*choose_core)(
const Scheduler::ThreadData* threadData);
bool (*should_rebalance)(
Scheduler::CoreEntry* (*rebalance)(
const Scheduler::ThreadData* threadData);
void (*rebalance_irqs)(bool idle);
};
@@ -44,7 +44,7 @@ public:
inline bool IsIdle() const;
inline bool HasCacheExpired() const;
inline bool ShouldRebalance() const;
inline CoreEntry* Rebalance() const;
inline int32 GetEffectivePriority() const;
@@ -176,13 +176,13 @@ ThreadData::HasCacheExpired() const
}
inline bool
ThreadData::ShouldRebalance() const
inline CoreEntry*
ThreadData::Rebalance() const
{
SCHEDULER_ENTER_FUNCTION();
ASSERT(!gSingleCore);
return gCurrentMode->should_rebalance(this);
return gCurrentMode->rebalance(this);
}