![try_to_wake_up()在哪里将任务添加到CPU运行队列中?](https://linux22.com/image/189215/try_to_wake_up()%E5%9C%A8%E5%93%AA%E9%87%8C%E5%B0%86%E4%BB%BB%E5%8A%A1%E6%B7%BB%E5%8A%A0%E5%88%B0CPU%E8%BF%90%E8%A1%8C%E9%98%9F%E5%88%97%E4%B8%AD%EF%BC%9F.png)
我一直在试图理解Linux内核中的try_to_wake_up()函数好一些。从概念上讲,我(认为)要唤醒一个进程,我们必须将其添加到 CPU 运行队列中,但我很难看出这种情况发生在哪里。
//try_to_wake_up()
if (p == current) {
/* I omitted some comments here*/
success = 1;
cpu = task_cpu(p); //task_cpu(p) returns READ_ONCE(p->cpu);
trace_sched_waking(p); //This is just a logging call
p->state = TASK_RUNNING;
trace_sched_wakeup(p); //Another logging call
goto out;
}
所以任务CPU()似乎根本没有修改CPU运行队列,所以我决定去看看标签,它正在调用ttwu_stat():
/*I omitted some intermediate code here*/
out:
if (success)
ttwu_stat(p, cpu, wake_flags);
preempt_enable();
return success;
但当我去看的时候ttwu_stat(),这似乎只是一堆对此的调用__schedstat_inc只是增加其输入参数的宏。
那么...我们实际上在哪里将 task_struct* p 添加到 CPU 运行队列中?
任何想法表示赞赏。
谢谢。
答案1
您引用的代码块是一种特殊情况,如省略的注释中所述:
* We're waking current, this means 'p->on_rq' and 'task_cpu(p)
* == smp_processor_id()'. Together this means we can special
* case the whole 'p->on_rq && ttwu_remote()' case below
* without taking any locks.
由于要唤醒的任务是当前任务,因此它已经在运行队列 ( p->on_rq
) 中,因此不需要将其添加到运行队列中。
处理将任务添加到运行队列再向下:
cpu = select_task_rq(p, p->wake_cpu, SD_BALANCE_WAKE, wake_flags);
这会将任务添加到运行队列并返回调度该任务的 CPU,因此可以在必要时处理迁移。
该#ifdef CONFIG_SMP
条件值得一些解释:如果不支持 SMP,则多个任务不能并发运行,并且由于我们知道我们不会唤醒当前任务,因此唯一需要处理的情况是 I/O 等待。