scheduler: Always update core heaps after thread migration

The main purpose of this patch is to eliminate the delay between thread
migration and result of that migration being visible in load statistics.
Such delay, in certain circumstances, may cause some cores to become
overloaded because the scheduler migrates too many threads to them before
the effect of migration becomes apparent.
This commit is contained in:
Pawel Dziepak
2014-02-06 03:23:28 +01:00
parent 230d1fcfea
commit 667b23ddc2
2 changed files with 17 additions and 11 deletions
+14 -8
View File
@@ -527,7 +527,7 @@ CoreEntry::RemoveCPU(CPUEntry* cpu, ThreadProcessing& threadPostProcessing)
void
CoreEntry::_UpdateLoad()
CoreEntry::_UpdateLoad(bool forceUpdate)
{
SCHEDULER_ENTER_FUNCTION();
@@ -535,9 +535,11 @@ CoreEntry::_UpdateLoad()
return;
bigtime_t now = system_time();
if (now < kLoadMeasureInterval + fLastLoadUpdate)
bool intervalEnded = now >= kLoadMeasureInterval + fLastLoadUpdate;
if (!intervalEnded && !forceUpdate)
return;
WriteSpinLocker locker(fLoadLock);
WriteSpinLocker coreLocker(gCoreHeapsLock);
int32 newKey = GetLoad();
@@ -546,12 +548,16 @@ CoreEntry::_UpdateLoad()
ASSERT(oldKey >= 0);
ASSERT(newKey >= 0);
ASSERT(fCurrentLoad >= 0);
ASSERT(fLoad >= fCurrentLoad);
if (intervalEnded) {
WriteSpinLocker locker(fLoadLock);
fLoad = fCurrentLoad;
fLoadMeasurementEpoch++;
fLastLoadUpdate = now;
ASSERT(fCurrentLoad >= 0);
ASSERT(fLoad >= fCurrentLoad);
fLoad = fCurrentLoad;
fLoadMeasurementEpoch++;
fLastLoadUpdate = now;
}
if (oldKey == newKey)
return;
+3 -3
View File
@@ -173,7 +173,7 @@ public:
static inline CoreEntry* GetCore(int32 cpu);
private:
void _UpdateLoad();
void _UpdateLoad(bool forceUpdate = false);
static void _UnassignThread(Thread* thread,
void* core);
@@ -416,7 +416,7 @@ CoreEntry::AddLoad(int32 load, uint32 epoch, bool updateLoad)
locker.Unlock();
if (updateLoad)
_UpdateLoad();
_UpdateLoad(true);
}
@@ -434,7 +434,7 @@ CoreEntry::RemoveLoad(int32 load, bool force)
atomic_add(&fLoad, -load);
locker.Unlock();
_UpdateLoad();
_UpdateLoad(true);
}
return fLoadMeasurementEpoch;
}