Location of task swap on/off CPU for run que

I am trying to locate Linux's scheduler, and within there find the function that adds the next process to the run que (swaps control of the CPU).

From looking around I "think" this would be sched.c , and I "think" that prepare_task_switch is this function based on its description, but I am not 100% sure.

The overview definition makes sense, however I cannot seem to find any additional information on its inside methods: fire_sched_out_preempt_notifiers(prev, next) , prepare_lock_switch(rq, next) , prepare_arch_switch(next) , and so my root of doubt comes from whether or not these functions are what causes the task swap to occur(changing CPU ownership).

If I am in the right code location, can someone offer me some clarity on what these three functions do? Otherwise, can someone offer some insight on where I should be looking for where the scheduler switches a task's control of the CPU for the run que?

Location: /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 }

In C, the fact that the function is marked as 'static' tells you that it can only be called from within the same file. So if you search for prepare_task_switch within kernel/sched.c, you'll find that it gets called from context_switch. (prepare_task_switch itself is not doing the interesting stuff: it's only "preparing" to.)

If you search for context_switch in turn (also marked 'static'), you'll find it gets called from __schedule which is the actual heart of the scheduler. In fact, by the time context_switch is called, __schedule has already calculated the next task to run, as that is passed to context_switch as an argument.

Note that the task to be run is actually given control of the CPU in context_switch (technically in switch_to(), called from here). The exact workings are a bit tricky to wrap your head around, in that when switch_to returns, you're no longer executing in the same task. The CPU now is actually running a different task. The stack pointer and indeed the entire call stack is different than it was when context_switch was entered, and hence every local variable in the "current" call stack is potentially different than it was.

As for choosing the next task to run, pick_next_task does that. The key bits from __schedule() are:

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] }

The rest is locking details and bookkeeping (albeit very important).

链接地址: http://www.djcxy.com/p/43626.html

上一篇: 为什么MPC5554电路板不需要RTOS? 它是否带有内置的

下一篇: 任务交换开/关CPU运行队列的位置