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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user