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:
Pawel Dziepak 2014-03-09 15:21:01 +01:00
parent 5df1ecb2ab
commit a57a7a8c6d

View File

@ -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;