没有合适的资源?快使用搜索试试~ 我知道了~
81-教学课件-示例-Linux的进程调度算法1
需积分: 0 0 下载量 98 浏览量
2022-08-04
14:16:30
上传
评论
收藏 170KB PDF 举报
温馨提示
试读
12页
81-教学课件-示例-Linux的进程调度算法1
资源详情
资源评论
资源推荐
Linux 2.4 版的 schedule() 函数的流程图
s c h e d u l e s t a r t
前 所 指 的 内 存 是 否 为 空 出 错 返 回
是
p r e v = c u r r e n t ;
t h i s _ c p u =
p r e v - > p r o c e s s o r ;
是 否 被 中 断 处 理 调 用
否
s c h e d u l i n g _ i n _
i n t e r r u p t
是
释 放 全 局 内 核 锁
否
是 否 有 软 中 断 请 求
是
对 c o u n t e r = 0 情
况 的 处 理
保 存 当 前 c p u 调 度 进 程 的 数 据 区 ;
对 运 行 对 列 加 s p i n l o c k
否
是 否 采 用 轮 转 法 进 行 调 度
是
d o _ s o f t i r q ( )
否
检 测 进 程 状 态 ;
对 n e e d _ r e s c h e d 置 0
将 n e x t 设 置 为 当 前 c p u 的 i d l e t a s k 。 将
当 前 g o o d n e s s 变 量 c 赋 值 。
当 前 的 进 程 是 T A S K _ R U N N I N G状 态
是
变 量 c 赋 值 为 当
前 进 程 的
g o o d n e s s 函 数 的
返 回 值
搜 索 运 行 队 列 , 计 算 出 每 一 个 进 程 的
g o o d n e s s 并 与 当 前 的
g o o d n e s s 相 比 较 , g o o d n e s s 值 最 高 的 进 程
将 获 取 c p u .
c = = 0 ?
是
整 个 运 行 队 列 中
的 进 程 将 重 新
计 算 优 先 权
s c h e d _ d a t a - > c u r r = n e x t ;
对 S MP 的 处 理
下 一 个 进 程 与 当 前 进 程 是 否 相 同
重 新 获 取
g l o b a l k e r n e l
l o c k
c u r r e n t - > n e e d
_ r e s c h e d = = 0 ?
返 回
是
准 备 进 行 进 程 转 换
切 换 至 新 的 进 程
kernel/sched.c
498 /*
499 * 'schedule()' is the scheduler function. It's a very simple and nice
500 * scheduler: it's not perfect, but certainly works for most things.
501 *
502 * The goto is "interesting".
503 *
504 * NOTE!! Task 0 is the 'idle' task, which gets called when no other
505 * tasks can run. It can not be killed, and it cannot sleep. The 'state'
506 * information in task[0] is never used.
507 */
508 asmlinkage void schedule(void)
509 {
510 struct schedule_data * sched_data;
511 struct task_struct *prev, *next, *p;
512 struct list_head *tmp;
513 int this_cpu, c;
514
515 if (!current->active_mm) BUG();
如果 current->active_mm == NULL 那么进程必定有问题.任何进程都有一
个确定的 active_mm.
516 need_resched_back:
517 prev = current;
518 this_cpu = prev->processor;
准备交出 CPU 的进程,它的 PCB 由 current 指示。将局部变量 prev 指向
当前进程,this_cpu 指向当前进程拥有的 CPU(考虑对称多 CPU 的架
构)。
519
520 if (in_interrupt())
521 goto scheduling_in_interrupt;
检查一下,调用 schedule()函数时是否处于中断处理过程。若是,则打印
提示信息后,直接返回。
522
523 release_kernel_lock(prev, this_cpu);
释放全局内核锁.
524
525 /* Do "administrative" work here while we don't hold any locks */
526 if (softirq_active(this_cpu) & softirq_mask(this_cpu))
527 goto handle_softirq;
如果有些工作需要由 softirq 机制完成的,那么立刻执行 do_softirq()
(kernel/softirq.c)
528 handle_softirq_back:
529
530 /*
531 * 'sched_data' is protected by the fact that we can run
532 * only one process per CPU.
533 */
534 sched_data = & aligned_data[this_cpu].schedule_data;
用局部变量 sched_data 保存当前 CPU 的调度进程的数据区。因为任一时
刻,每个 CPU 只能运行一个 schedule()。schedule_data 结构包含一个指向
当前进程 task_struct 结构的指针和最后一个调度进程的 TSC 值(Time
Stamp Counter,CPU 附带一个 64 位的时间戳寄存器)。
535
536 spin_lock_irq(&runqueue_lock);
对就绪队列加 spinlock。之所以用 spinlock,是因为 schedule()是允许中断
的。这样在就绪队列解锁之后,我们可以直接使中断有效,而不必做一些
保存标志、恢复标志的操作。
537
538 /* move an exhausted RR process to be last.. */
539 if (prev->policy == SCHED_RR)
540 goto move_rr_last;
如果采用轮转法进行调度,则要重新检查一下 counter 是否为 0。若是 0,
则将其挂到就绪队列的最后。
541 move_rr_back:
542
543 switch (prev->state) {
544 case TASK_INTERRUPTIBLE:
545 if (signal_pending(prev)) {
546 prev->state = TASK_RUNNING;
547 break;
548 }
剩余11页未读,继续阅读
航知道
- 粉丝: 25
- 资源: 302
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0