【WALT】update_window_start()代码详解
代码版本:Linux4.9 android-msm-crosshatch-4.9-android12
代码展示
static u64
update_window_start(struct rq *rq, u64 wallclock, int event)
{
s64 delta;
int nr_windows;
u64 old_window_start = rq->window_start;
delta = wallclock - rq->window_start;
/* If the MPM global timer is cleared, set delta as 0 to avoid kernel BUG happening */
if (delta < 0) {
delta = 0;
WARN_ONCE(1, "WALT wallclock appears to have gone backwards or reset\n");
}
if (delta < sched_ravg_window)
return old_window_start;
nr_windows = div64_u64(delta, sched_ravg_window);
rq->window_start += (u64)nr_windows * (u64)sched_ravg_window;
rq->cum_window_demand = rq->walt_stats.cumulative_runnable_avg;
return old_window_start;
}
代码逻辑
delta = wallclock - rq->window_start;
wallclock 是进入 WALT 算法时的时间,rq->window_start 是运行队列当前所在窗口的开始时间。
通过 wallclock - rq->window_start ,得到从窗口开始到现在所经过的时间。if (delta < sched_ravg_window) return old_window_start;
sched_ravg_window 是自定义的 WALT 算法的窗口的大小。
如果从窗口开始到现在所经过的时间不到一个窗口的大小,说明窗口还未翻滚,还没有得到新的窗口开始时间,就直接返回久的窗口开始时间。nr_windows = div64_u64(delta, sched_ravg_window);
如果执行到此处,说明窗口已经翻滚,计算从 rq 当前所在窗口的开始时间到现在一共经过了 nr_windows 个完整窗口。rq->window_start += (u64)nr_windows * (u64)sched_ravg_window;
rq 新窗口的开始时间就是旧窗口开始时间加上 nr_windows 个完整窗口的时间。rq->cum_window_demand = rq->walt_stats.cumulative_runnable_avg;
更新 rq 的累积的 demand,rq->walt_stats.cumulative_runnable_avg
详细计算将在详解 update_task_demand() 中介绍。return old_window_start;
就算更新了 rq 的窗口开始时间,也先返回久的窗口开始时间。