c - Linux 源代码 - 任务交换开/关 CPU 以运行队列的位置

标签 c linux linux-kernel operating-system

我试图找到 Linux 的调度程序,并在其中找到将下一个进程添加到运行队列的函数(交换 CPU 的控制权)。

环顾四周,我“认为”这将是 sched.c,并且根据其描述,我“认为”prepare_task_switch 是此函数,但我不是100% 确定。

概述定义是有道理的,但是我似乎无法找到有关其内部方法的任何其他信息:fire_sched_out_preempt_notifiers(prev, next)prepare_lock_switch(rq, next)prepare_arch_switch(next),所以我怀疑的根源在于这些函数是否是导致任务交换发生(改变 CPU 所有权)的原因。

如果我在正确的代码位置,有人可以让我清楚地了解这三个函数的作用吗?否则,有人可以提供一些关于我应该在哪里寻找调度程序切换任务对运行队列的 CPU 控制的见解吗?

位置:/source/linux/kernel/sched.c

/**
* prepare_task_switch - prepare to switch tasks
* @rq: the runqueue preparing to switch
* @prev: the current task that is being switched out
* @next: the task we are going to switch to.
*
* This is called with the rq lock held and interrupts off. It must
* be paired with a subsequent finish_task_switch after the context
* switch.
*
* prepare_task_switch sets up locking and calls architecture specific
* hooks.
*/
2770 static inline void
2771 prepare_task_switch(struct rq *rq, struct task_struct *prev,
2772                     struct task_struct *next)
2773 {
2774         fire_sched_out_preempt_notifiers(prev, next);
2775         prepare_lock_switch(rq, next);
2776         prepare_arch_switch(next);
2777 }

最佳答案

在 C 中,函数被标记为“静态”这一事实告诉您它只能在同一个文件中调用。因此,如果您在 kernel/sched.c 中搜索 prepare_task_switch,您会发现它是从 context_switch 调用的。 (prepare_task_switch 本身并没有做有趣的事情:它只是“准备”。)

如果您依次搜索 context_switch(也标记为“静态”),您会发现它是从 __schedule 调用的,它是调度程序的实际核心。事实上,在调用 context_switch 时,__schedule 已经计算出下一个要运行的任务,因为它作为参数传递给 context_switch。

请注意,要运行的任务实际上是在 context_switch(从技术上讲是在 switch_to() 中,从此处调用)中获得 CPU 的控制权。确切的工作原理有点棘手,因为当 switch_to 返回时,您不再执行同一个任务。 CPU 现在实际上正在运行一个不同的任务。堆栈指针和整个调用堆栈与进入 context_switch 时不同,因此“当前”调用堆栈中的每个局部变量都可能与原来不同。

至于选择要运行的下一个任务,pick_next_task 会这样做。 __schedule() 的关键位是:

   put_prev_task(rq, prev);    /* Put old task at end of queue */
   next = pick_next_task(rq);  /* Get next task to run */
   ...
   if (prev != next) {         /* Nothing to do if it's the same task */
      ...
      context_switch(rq, prev, next);  /* Switch to new task */
      [now running in new task]
   }

剩下的就是锁定细节和簿记(尽管非常重要)。

关于c - Linux 源代码 - 任务交换开/关 CPU 以运行队列的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26341120/

相关文章:

c++ - future 选择哪一个,c++还是python2.x/3.x

c - 为什么局部变量没有默认类型而全局变量在 C 中有?

c - 致力于对链表进行排序,用 c 编写,然后为内核输出

ios - 如何将原始类型的 3D 数组包装在 NSArray 中?

linux - 从父目录在同一上下文中调用 bash 脚本

linux-kernel - 我可以知道在 Linux 内核中 GFP_HARDWALL 标志的目的是什么?

linux - 类似 FUSE 的文件系统

linux - 没有主编号的设备

linux - 打印第二个命令行参数

c - clock_gettime 和 getrusage 有什么关系?