scheduler: Fix load update on idle cores
To make sure that load statistics are accurate on idle cores each time idle thread is scheduled a timer is set to update load when current load measurement interval elapses. However, core load is defined as the average load during last measurement interval and idle core may be still considered busy if it was not idle during entire measurement interval. Since, load update timer is a one shot timer that information will not be updated until the core becomes active again. To mitigate that issue load update timer is set to fire after two load measurement intervals had elapsed.
This commit is contained in:
parent
5df1ecb2ab
commit
a57a7a8c6d
@ -309,7 +309,7 @@ CPUEntry::StartQuantumTimer(ThreadData* thread, bool wasPreempted)
|
||||
B_ONE_SHOT_RELATIVE_TIMER);
|
||||
} else if (gTrackCoreLoad) {
|
||||
add_timer(&cpu->quantum_timer, &CPUEntry::_UpdateLoadEvent,
|
||||
kLoadMeasureInterval, B_ONE_SHOT_RELATIVE_TIMER);
|
||||
kLoadMeasureInterval * 2, B_ONE_SHOT_RELATIVE_TIMER);
|
||||
fUpdateLoadEvent = true;
|
||||
}
|
||||
}
|
||||
@ -536,28 +536,32 @@ CoreEntry::_UpdateLoad(bool forceUpdate)
|
||||
|
||||
bigtime_t now = system_time();
|
||||
bool intervalEnded = now >= kLoadMeasureInterval + fLastLoadUpdate;
|
||||
bool intervalSkipped = now >= kLoadMeasureInterval * 2 + fLastLoadUpdate;
|
||||
|
||||
if (!intervalEnded && !forceUpdate)
|
||||
return;
|
||||
|
||||
WriteSpinLocker coreLocker(gCoreHeapsLock);
|
||||
|
||||
int32 newKey = GetLoad();
|
||||
int32 oldKey = CoreLoadHeap::GetKey(this);
|
||||
|
||||
ASSERT(oldKey >= 0);
|
||||
ASSERT(newKey >= 0);
|
||||
|
||||
int32 newKey;
|
||||
if (intervalEnded) {
|
||||
WriteSpinLocker locker(fLoadLock);
|
||||
|
||||
newKey = intervalSkipped ? fCurrentLoad : GetLoad();
|
||||
|
||||
ASSERT(fCurrentLoad >= 0);
|
||||
ASSERT(fLoad >= fCurrentLoad);
|
||||
|
||||
fLoad = fCurrentLoad;
|
||||
fLoadMeasurementEpoch++;
|
||||
fLastLoadUpdate = now;
|
||||
}
|
||||
} else
|
||||
newKey = GetLoad();
|
||||
|
||||
int32 oldKey = CoreLoadHeap::GetKey(this);
|
||||
|
||||
ASSERT(oldKey >= 0);
|
||||
ASSERT(newKey >= 0);
|
||||
|
||||
if (oldKey == newKey)
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user