c - 不了解 Linux 内核实时调度程序中某些功能的内部结构

标签 c linux linux-kernel scheduling scheduler

我正在查看 update_curr_rt 的代码实时调度程序的 /kernel/sched/rt.c 中的函数。有人可以解释一下它是如何工作的吗?

static void update_curr_rt(struct rq *rq)
{
    struct task_struct *curr = rq->curr;
    struct sched_rt_entity *rt_se = &curr->rt;
    struct rt_rq *rt_rq = rt_rq_of_se(rt_se);
    u64 delta_exec; // Time difference (???)

    if (curr->sched_class != &rt_sched_class)
        return;
    // check if sched class is Real-Time sched class
    delta_exec = rq->clock_task - curr->se.exec_start;
    if (unlikely((s64)delta_exec <= 0))
        return;
    // ??? 
    schedstat_set(curr->se.statistics.exec_max,
              max(curr->se.statistics.exec_max, delta_exec));
    // I am assuming that se.sum_exec_runtime is total time task ran
    // and we add time difference to 
    curr->se.sum_exec_runtime += delta_exec;
    // can be skipped, has to do with threads
    account_group_exec_runtime(curr, delta_exec);
    // reset start time
    curr->se.exec_start = rq->clock_task;
    cpuacct_charge(curr, delta_exec);
    // I guess it calculates average ran time of the task
    sched_rt_avg_update(rq, delta_exec);
    // can be skipped
    if (!rt_bandwidth_enabled())
        return;
    // ??? Nothing makes sense for code below
    for_each_sched_rt_entity(rt_se) {
        rt_rq = rt_rq_of_se(rt_se);

        if (sched_rt_runtime(rt_rq) != RUNTIME_INF) {
            raw_spin_lock(&rt_rq->rt_runtime_lock);
            rt_rq->rt_time += delta_exec;
            if (sched_rt_runtime_exceeded(rt_rq))
                resched_task(curr);
            raw_spin_unlock(&rt_rq->rt_runtime_lock);
        }
    }
}

最佳答案

我强烈建议您探索 cscope 和/或 grok 的神奇之处。您可以在其中输入或单击标识符并查看定义。

这是经典的 Linux 代码:紧凑、切中要害且可读性强。一些宏的使用使其有点难以理解,但一切都有有意义的名称。

对于您说“没有任何意义”的部分:for_each_sched_rt_entity 是一个扩展为 for 循环的宏。 它使代码更紧凑但更难理解。 基本上,如果我们任务中的任何 rq 已经用完运行时间 然后任务被扔回调度程序以设置它运行 改天再来一次。

简单易行。

关于c - 不了解 Linux 内核实时调度程序中某些功能的内部结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20450147/

相关文章:

linux - 从内核空间向用户空间传递地址

c - C中内核空间遍历祖先的结束标志

读取部分可用数据时Linux tty翻转缓冲区锁定

c - 使用 malloc 和 realloc 动态地将字符串添加到 char 指针

c - 从 : warning: conversion to ‘size_t’ from ‘ssize_t’ may change the sign of the result 接收

c - 为什么像clone()这样的系统调用会失败、恢复和暂停?

php - 创建存档并添加来自与特定类型匹配的特定路径的所有文件

linux - 了解 Chromium 源代码结构

c - 如何使用 scanf 跳过标准输入的一部分?

linux - 计算有多少个文件有字符串