1. 程式人生 > >linux 程序排程 pick_next_task()函式

linux 程序排程 pick_next_task()函式

pick_next_task是程序排程的關鍵步驟,主要功能是從發生排程的CPU的執行佇列中選擇一個程序執行。本文主要介紹該函式的實現過程。系統中的排程順序是:實時程序------->普通程序------>空閒程序。分別從屬於三個排程類:rt_sched_class,fair_sched_class和 idle_sched_class。

下面介紹函式的具體細節

static inline struct task_struct *
pick_next_task(struct rq *rq, struct task_struct *prev)
{
    const struct sched_class *class = &fair_sched_class;
    struct task_struct *p;

    /*
     * Optimization: we know that if all tasks are in
     * the fair class we can call that function directly:
     */
    if (likely(prev->sched_class == class &&
           rq->nr_running == rq->cfs.h_nr_running)) {
        p = fair_sched_class.pick_next_task(rq, prev);
        if (unlikely(p == RETRY_TASK))
            goto again;

        /* assumes fair_sched_class->next == idle_sched_class */
        if (unlikely(!p))
            p = idle_sched_class.pick_next_task(rq, prev);

        return p;
    }

again:
    for_each_class(class) {
        p = class->pick_next_task(rq, prev);
        if (p) {
            if (unlikely(p == RETRY_TASK))
                goto again;
            return p;
        }
    }

    BUG(); /* the idle class will always have a runnable task */
}

pick_next_task()的執行過程大致可以分成兩個步驟:

步驟1.檢查執行佇列中是否含有實時程序,if語句中判斷了當前cpu就緒佇列中的程序數目是否與普通程序的就緒佇列中的程序數目相同,如果相同就說明了系統中全是普通程序,直接通過cfs演算法(完全公平排程演算法)的排程類的pick_next_task_fair函式來從普通程序的就緒佇列中尋找程序即可。  

cfs演算法(完全公平排程演算法)的排程類的pick_next_task_fair函式返回值有三種情況

  • RETRY_TASK:表示有從屬於更高優先順序排程類的程序被喚醒------------>跳轉到步驟2。
  • 空指標:表示沒有cfs排程類的程序處於就緒態------------------->在idle排程類中尋找程序。(idle排程類永遠非空)
  • struct task 結構體指標:表示選擇到一個程序--------------->返回指標

步驟2.遍歷排程類的連結串列,並從中選擇一個優先順序最高的程序。

示意圖