前言
我们之前多次提到过睡眠的进程由于没有占用CPU资源,所以其vruntime会比较少,睡眠时间越长,vruntime越小。为了防止睡眠进程醒来后,独占CPU导致其他进程饿死,进程醒来后,会重新调整其vruntime值,使其既能够收到CPU的优待,又不至于导致其他进程饥饿。
另外,由于之前只分析了CFS调度器相关的代码,所以本文涉及到具体调度器的时候,全部以CFS调度器为例。
进程睡眠msleep函数
msleep
void msleep(unsigned int msecs)
{
unsigned long timeout = msecs_to_jiffies(msecs) + 1;
while (timeout)
timeout = schedule_timeout_uninterruptible(timeout);
}
- 以jiffies为单位计算超时时间
- 调用schedule_timeout_uninterruptible进行下一步处理。
因为这里是sleep,说睡眠多久就睡眠多久,不能被提前唤醒,所以这里的睡眠是无法中断的,因此调用schedule_timeout_uninterruptible接口。
sleep->schedule_timeout_uninterruptible
signed long __sched schedule_timeout_uninterruptible(signed long timeout)
{
__set_current_state(TASK_UNINTERRUPTIBLE);
return schedule_timeout(timeout);
}
- 进程状态设置为TASK_UNINTERRUPTIBLE状态,也就是说不能被提前唤醒。
- 调用 schedule_timeout接口进行下一步处理。
sleep->schedule_timeout_uninterruptible->schedule_timeout
signed long __sched schedule_timeout(signed long timeout)
{
struct timer_list timer;
unsigned long expire;
switch (timeout)
{
case MAX_SCHEDULE_TIMEOUT:
/*
* These two special cases are useful to be comfortable
* in the caller. Nothing more. We could take
* MAX_SCHEDULE_TIMEOUT from one of the negative value
* but I' d like to return a valid offset (>=0) to allow
* the caller to