我试图找到Linux的调度器,并在其中找到将下一个进程添加到运行que(交换CPU控制)的函数。
环顾四周,我"认为"这将是sched.c
,并且根据其描述"认为"prepare_task_switch
是这个函数,但我不能100%确定。
概述定义是有意义的,但我似乎找不到关于其内部方法的任何其他信息:fire_sched_out_premept_notifiers(prev,next)、prepare_lock_switch(rq,next,因此,我怀疑的根源在于这些功能是否是导致任务交换(改变CPU所有权)的原因。
如果我在正确的代码位置,有人能告诉我这三个函数的作用吗?否则,有人能提供一些见解吗?我应该在哪里寻找调度程序为运行que切换任务对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中,函数被标记为"static"的事实告诉您,它只能从同一文件中调用。因此,如果您在kernel/sched.c中搜索prepare_task_switch,您会发现它是从context_switch调用的。(prepare_task_switch本身并没有做有趣的事情:它只是在"准备"。)
如果你依次搜索context_switch(也标记为"static"),你会发现它是从__schedule调用的,__schedules是调度器的实际核心。事实上,在调用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]
}
剩下的就是锁定细节和记账(尽管非常重要)。