diff --git a/src/system/kernel/scheduler/low_latency.cpp b/src/system/kernel/scheduler/low_latency.cpp index bca90fd0b5..5b405393a0 100644 --- a/src/system/kernel/scheduler/low_latency.cpp +++ b/src/system/kernel/scheduler/low_latency.cpp @@ -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, }; diff --git a/src/system/kernel/scheduler/power_saving.cpp b/src/system/kernel/scheduler/power_saving.cpp index f9b4b62fca..9cbe24b874 100644 --- a/src/system/kernel/scheduler/power_saving.cpp +++ b/src/system/kernel/scheduler/power_saving.cpp @@ -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, }; diff --git a/src/system/kernel/scheduler/scheduler.cpp b/src/system/kernel/scheduler/scheduler.cpp index 67f99e2381..27022e371c 100644 --- a/src/system/kernel/scheduler/scheduler.cpp +++ b/src/system/kernel/scheduler/scheduler.cpp @@ -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); diff --git a/src/system/kernel/scheduler/scheduler_modes.h b/src/system/kernel/scheduler/scheduler_modes.h index 820912afd9..2d0979d92a 100644 --- a/src/system/kernel/scheduler/scheduler_modes.h +++ b/src/system/kernel/scheduler/scheduler_modes.h @@ -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); }; diff --git a/src/system/kernel/scheduler/scheduler_thread.h b/src/system/kernel/scheduler/scheduler_thread.h index 1127b69127..73e581e282 100644 --- a/src/system/kernel/scheduler/scheduler_thread.h +++ b/src/system/kernel/scheduler/scheduler_thread.h @@ -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); }