a2634874ed
Previous implementation based on the actual load of each core and share each thread has in that load turned up to be very problematic when balancing load on very heavily loaded systems (i.e. more threads consuming all available CPU time than there is logical CPUs). The new approach is to estimate how much load would a thread produce if it had all CPU time only for itself. Summing such load estimations of each thread assigned to a given core we get a rank that contains much more information than just simple actual core load.
58 lines
1.1 KiB
C
58 lines
1.1 KiB
C
/*
|
|
* Copyright 2013 Paweł Dziepak, pdziepak@quarnos.org.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
#ifndef _KERNEL_LOAD_TRACKING_H
|
|
#define _KERNEL_LOAD_TRACKING_H
|
|
|
|
|
|
#include <OS.h>
|
|
|
|
|
|
const int32 kMaxLoad = 1000;
|
|
const bigtime_t kLoadMeasureInterval = 50000;
|
|
const bigtime_t kIntervalInaccuracy = kLoadMeasureInterval / 4;
|
|
|
|
|
|
static inline int32
|
|
compute_load(bigtime_t& measureTime, bigtime_t& measureActiveTime, int32& load,
|
|
bigtime_t now)
|
|
{
|
|
if (measureTime == 0) {
|
|
measureTime = now;
|
|
return -1;
|
|
}
|
|
|
|
bigtime_t deltaTime = now - measureTime;
|
|
|
|
if (deltaTime < kLoadMeasureInterval)
|
|
return -1;
|
|
|
|
int32 oldLoad = load;
|
|
ASSERT(oldLoad >= 0 && oldLoad <= kMaxLoad);
|
|
|
|
int32 newLoad = measureActiveTime * kMaxLoad;
|
|
newLoad /= max_c(deltaTime, 1);
|
|
newLoad = max_c(min_c(newLoad, kMaxLoad), 0);
|
|
|
|
measureActiveTime = 0;
|
|
measureTime = now;
|
|
|
|
deltaTime += kIntervalInaccuracy;
|
|
int n = deltaTime / kLoadMeasureInterval;
|
|
ASSERT(n > 0);
|
|
|
|
if (n > 10)
|
|
load = newLoad;
|
|
else {
|
|
newLoad *= (1 << n) - 1;
|
|
load = (load + newLoad) / (1 << n);
|
|
ASSERT(load >= 0 && load <= kMaxLoad);
|
|
}
|
|
|
|
return oldLoad;
|
|
}
|
|
|
|
|
|
#endif // _KERNEL_LOAD_TRACKING_H
|