4

我正在研究 Linux 内核,并试图弄清楚循环调度算法是如何工作的。在该kernel\sched_rt.c文件中,有一个名为task_tick_rt如下定义的方法:

static void task_tick_rt(struct rq *rq, struct task_struct *p, int queued)
{
    update_curr_rt(rq);

    watchdog(rq, p);

    /*
     * RR tasks need a special form of timeslice management.
     * FIFO tasks have no timeslices.
     */
    if (p->policy != SCHED_RR)
            return;

    if (--p->rt.time_slice)
            return;

    p->rt.time_slice = DEF_TIMESLICE;

    /*
     * Requeue to the end of queue if we are not the only element
     * on the queue:
     */
    if (p->rt.run_list.prev != p->rt.run_list.next) {
            requeue_task_rt(rq, p, 0);
            set_tsk_need_resched(p);
    }

}

我不明白的是(除了有一个无用的queued参数之外)代码试图通过if (--p->rt.time_slice)检查来实现什么。我不明白为什么任务列表指针p减1,换句话说,为什么该方法检查的是前一个任务而不是当前任务?对此的任何澄清表示赞赏。

4

1 回答 1

7

查看 c 运算符优先级http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence

运算符的->优先级高于 prefix ++,所以这个特定的条件可以写成:

if (--(p->rt.time_slice))

换句话说,递减的是时间片,而不是指针。


queued参数在这里可能看起来无用,但它有一个理由存在。特别注意task_tick_rt()从哪里调用。它的唯一参考是当它被分配给实例中的.task_tick函数指针时:http : //lxr.free-electrons.com/source/kernel/sched/rt.c#L1991rt_sched_classstruct sched_class

所以我们看到每个调度算法都有自己的struct sched_class函数向量,内核会调用它来进行调度服务。如果我们查看其他算法,我们会看到 CFS(完全公平调度)算法也有自己的实例struct sched_class,命名为:http fair_sched_class: //lxr.free-electrons.com/source/kernel/sched/fair.c#L6179

CFS 案例中的.task_tick成员指向task_tick_fair(): http: //lxr.free-electrons.com/source/kernel/sched/fair.c#L5785

注意task_tick_fair() 确实使用了queued参数。因此,当.task_tick成员被调用(此处此处)时,会为queued参数传入 0 或 1。因此,虽然task_tick_rt()不使用它,但queued参数必须仍然是它们,因此struct sched_class函数向量中的函数指针类型都匹配。

简而言之,struct sched_class函数向量指定了调度算法和内核其余部分之间的接口。该queued参数应该存在于给定算法选择使用它的情况下,但在循环的情况下,它会被简单地忽略。

于 2013-10-11T21:12:40.583 回答