Linux调度分析(5)调度core之唤醒过程

唤醒流程

当某个线程由于某些原因比如资源不满足需要让出CPU时,它会通过schedule()或sleep()等让该线程让出CPU,让其他线程运行。当某个线程的资源满足时,其他线程通过Wake_up_process()唤醒这个休眠的线程。
唤醒流程如下(其中蓝色部分是特定调度器需要实现填充的):
image
(1) 判断需要唤醒的线程是否为当前运行的线程,如果为真,设置为TASK_RUNNING;否则执行步骤(2);
(2) 调用select_task_rq()选CPU,这个是唤醒的重点,由每个sched_class->select_task_rq()实现;
(3) 若支持TTWU_QUEUE特性且满足条件ttwu_queue_cond()时,通过__ttwu_queue_wakelist()将需要唤醒的task加入到CPU的wake_list,发送IPI中断将task加入到该CPU的rq中;
(4) 若不支持TTWU_QUEUE特性,在当前CPU上将active_task(sched_class->enqueue_task()),即加入到对应CPU的rq中;
(5) 检查是否需要抢占当前线程,调用sched_class->wakeup_preempt();
(6) 将task设置为TASK_RUNNING;

TTWU特性

唤醒过程为唤醒线程选择了CPU后需要将task放入到选择的CPU的运行队列中。若当前线程所在的CPU与选择CPU为不同核时,需要在当前CPU上增加选择CPU的rq->lock,在当前CPU上执行active_task()。在唤醒过程较多时,获取rq->lock的时间可能会增加,导致唤醒过程时间增加。
为了降低rq->lock的竞争,TTWU特性会将active_task()的任务添加到选择CPU的wakelist中,通过IPI中断让选择CPU执行active_task()任务。
举个例子,CPU3上线程A唤醒线程B,在disable TTWU和enable TTWU两种情况下执行过程如下:
image
对于disable TTWU,在CPU3上执行select_task_rq()进行选核(假定选择了CPU0),在执行active_task()之前需要获取CPU0的rq->lock。
对于enable TTWU,同样在CPU3上执行select_task_rq()进行选核(假定选择了CPU0),将active_task()任务放到CPU0的wakelist队列中,然后通过IPI中断让CPU0执行wakelist中的active_task()。
可以看出TTWU特性是通过IPI中断来减少rq->lock的竞争,在rq->lock竞争激烈的场景有优化效果。

posted @ 2026-01-07 11:22  耳朵一样  阅读(73)  评论(0)    收藏  举报