核心调度器,其实就是schedule这一个函数,当一个进程觉得自己无事可做了,可以调用该函数释放CPU,让其他进程占用CPU完成任务。粗略看下代码,做了一些注释。
asmlinkage __visible void __sched schedule(void)
{
struct task_struct *tsk = current;
sched_submit_work(tsk);
do {
preempt_disable();//禁止抢占
__schedule(false);
sched_preempt_enable_no_resched();//开抢占
} while (need_resched());//如果当前进程需要被抢占,那就再执行一次
}
EXPORT_SYMBOL(schedule);
可以看到,schedule在做了一些准备之后就把任务交给了__schedule,调用它的地方有很多,是真正执行调度的地方:
static void __sched notrace __schedule(bool preempt)
{
struct task_struct *prev, *next;
unsigned long *switch_count;
struct rq_flags rf;
struct rq *rq;
int cpu;
u64 wallclock;
//获取当前CPUID,per_cpu中的runqueues,列队中当前运行的进程
cpu = smp_processor_id();
rq = cpu_rq(cpu);
prev = rq->curr;
schedule_debug(prev);//一些调度前的debug feature,当前有栈越界检查&