调度子系统2_核心调度器
来源:互联网 发布:淘宝女装宣传视频 编辑:程序博客网 时间:2024/05/18 21:42
//核心调度器//当进程决定让出cpu时调用//函数任务://1.禁止内核抢占//2.获取本cpu的rq//3.取消为当前进程运行的hrtimer//4.获取队列锁//5.更新队列时钟//6.清除当前进程need resched标志//7.如果当前进程为非运行状态,并且当前非内核抢占路径//7.1 如果当前进程有信号待处理,设置当前进程为就绪状态//7.2 否则进程出队rq//8.如果当前rq没有可运行进程//8.1 通过load balance从其他进程搬进程//9.通知调度器类用另一个进程代替当前进程//10.通知调度器类选择下一个可运行进程//11.如果下一个运行的进程非当前进程//11.1 执行进程切换//12.否则释放队列锁//13.开启内核抢占//14.如果当前进程被设置need resched,重复1 1.1 asmlinkage void __sched schedule(void){struct task_struct *prev, *next;unsigned long *switch_count;struct rq *rq;int cpu;need_resched://禁止抢占preempt_disable();cpu = smp_processor_id();//本cpu的rqrq = cpu_rq(cpu);//当前rq上正在运行的进程prev = rq->curr;//进程被切换的次数switch_count = &prev->nivcsw;//取消为当前进程运行的hrtimerif (sched_feat(HRTICK))hrtick_clear(rq);//获取队列锁raw_spin_lock_irq(&rq->lock);//更新队列时钟update_rq_clock(rq);//清除当前进程need resched标志clear_tsk_need_resched(prev);//当前进程非运行状态,并且非内核抢占if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {//当前进程有信号待处理,设置进程为运行态if (unlikely(signal_pending_state(prev->state, prev))){prev->state = TASK_RUNNING;}else{//进程出队rqdeactivate_task(rq, prev, 1);}switch_count = &prev->nvcsw;}//通知调度器类,即将发生进程切换pre_schedule(rq, prev);//当前rq没有可运行进程,通过loadbalance从其他cpu的rq搬进程过来if (unlikely(!rq->nr_running))idle_balance(cpu, rq);//通知调度器类用另一个进程代替当前进程put_prev_task(rq, prev);//通知调度器类选择下一个可运行进程next = pick_next_task(rq);//切换当前进程if (likely(prev != next)) {//统计rq切换次数rq->nr_switches++;rq->curr = next;++*switch_count;//切换进程上下文context_switch(rq, prev, next); //现在已经是另一个进程在运行cpu = smp_processor_id();rq = cpu_rq(cpu);} elseraw_spin_unlock_irq(&rq->lock);//通知调度器类,完成了进程切换post_schedule(rq);//开启内核抢占preempt_enable_no_resched();//如果当前进程需要切换,则再次切换if (need_resched())goto need_resched;}//通知调度器类,即将进程切换2.1 static inline void pre_schedule(struct rq *rq, struct task_struct *prev){if (prev->sched_class->pre_schedule)prev->sched_class->pre_schedule(rq, prev);}//通知调度器,完成了进程切换2.2 static inline void post_schedule(struct rq *rq){if (rq->post_schedule) {unsigned long flags;//获取队列锁raw_spin_lock_irqsave(&rq->lock, flags);if (rq->curr->sched_class->post_schedule)rq->curr->sched_class->post_schedule(rq);raw_spin_unlock_irqrestore(&rq->lock, flags);rq->post_schedule = 0;}}//通知调度器类,用另一个进程替换当前进程3.1 static void put_prev_task(struct rq *rq, struct task_struct *prev){....prev->sched_class->put_prev_task(rq, prev);}//通知调度器类,选择下一个运行的进程4.1 static inline struct task_struct *pick_next_task(struct rq *rq){const struct sched_class *class;struct task_struct *p;//如果rq中进程数等于cfs中进程数,说明没有rt进程,由cfs选出下一个运行的进程if (likely(rq->nr_running == rq->cfs.nr_running)) {p = fair_sched_class.pick_next_task(rq);if (likely(p))return p;}//否则由最高优先级的调度类class = sched_class_highest;for ( ; ; ) {//选择下一个运行进程p = class->pick_next_task(rq);if (p)return p;//下一个优先级的调度类class = class->next;}}//最高优先级调度器类4.2 #define sched_class_highest (&rt_sched_class)
0 0
- 调度子系统2_核心调度器
- 进程调度子系统(2)核心调度器
- 调度子系统3_周期调度器
- 调度子系统1_调度子系统初始化
- 进程调度子系统(1)调度器数据结构
- struts--ActionInvocation--核心调度器
- 调度子系统4_负载均衡(一)
- 调度子系统5_负载均衡(二)
- 调度子系统6_负载均衡(三)
- 调度子系统7_负载均衡(四)
- 调度子系统8_负载均衡(五)
- 调度子系统阅读
- [进程管理] linux核心调度器
- linux进程管理 - 核心调度器
- Linux内核之核心调度器
- JBPM核心调度过程
- spark 核心作业调度和任务调度
- linux cfs调度器_理论模型
- Linux代码性能检测利器(三)-控制分析器opcontrol使用说明
- MFC文本编程(插入符的使用)
- java中float/double浮点数的计算失精度问题
- 软工总结系列3——软件设计
- asp.net 中生成验证码
- 调度子系统2_核心调度器
- X265编译中C2220错误的解决办法
- 在macbook下安装mysql
- 二叉树输出
- HandBrake界面簡單說明
- JSP元素和标签
- java web 随笔
- STM32串行通讯采用中断方式发送,接收
- Part 02 对话框(Qt)