linux0.11学习之schedule
在一个操作系统中,最重要的部分就是任务调度,linux的0.11版本的任务调度函数比较简单,所以学习任务调度的原理非常适用。
下面我们贴出来schedule函数的代码。
12 /*3 * 'schedule()' is the scheduler function. This is GOOD CODE! There4 * probably won't be any reason to change this, as it should work well5 * in all circumstances (ie gives IO-bound processes good response etc).6 * The one thing you might take a look at is the signal-handler code here.7 *8 * NOTE!! Task 0 is the 'idle' task, which gets called when no other9 * tasks can run. It can not be killed, and it cannot sleep. The 'state'10 * information in task[0] is never used.11 */12 void schedule(void)13 {14 int i,next,c;15 struct task_struct ** p;1617 /* check alarm, wake up any interruptible tasks that have got a signal */1819 for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)20 if (*p) {21 if ((*p)->alarm && (*p)->alarm < jiffies) {22 (*p)->signal |= (1<<(SIGALRM-1));23 (*p)->alarm = 0;24 }25 if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) &&26 (*p)->state==TASK_INTERRUPTIBLE)27 (*p)->state=TASK_RUNNING;28 }2930 /* this is the scheduler proper: */3132 while (1) {33 c = -1;34 next = 0;35 i = NR_TASKS;36 p = &task[NR_TASKS];37 while (--i) {38 if (!*--p)39 continue;40 if ((*p)->state == TASK_RUNNING && (*p)->counter > c)41 c = (*p)->counter, next = i;42 }43 if (c) break;44 for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)45 if (*p)46 (*p)->counter = ((*p)->counter >> 1) +47 (*p)->priority;48 }49 switch_to(next);50 }
从代码注释中,我们可以看到linus本人对这段代码是比较推崇的。这段代码可以运行在任何边界,没有理由修改这段代码。有一点需要注意的是信号处理的代码。任务是一个空闲任务,只有在其他任务没有运行时该空闲任务才会被运行。空闲任务不能 被杀死,也不能睡眠。它的tcb即task[0].state,任务状态信息从来不用的。
接下来我们来分析代码。
14,15行定义了一些变量,要说明的是p 这是一个双重指针,双重针指向的类型是任务数据块.数据块里面存放着一个任务的所有信息。
19-28行的代码作用是进行的报警定时值,唤醒任何已经得到信号的可中断任务。
19行开始for循环从最后一个任务开始向前开始遍历所有的任务。
20行判断该任务是否存在,不存在则跳过。
21行判断如果设置过该任务的定时值,且该定时值已经过期则,在信号位图中置位SIGALRM,并清alarm.
要说明的一点是jiffies变量是系统开机开始算起的计时数 10ms/滴答
25.26行如果信号位图中除了被阻塞的信号外还有其它信号,并且任务处于可中断状态,则任务置位就绪态。 ~(_BLOCKABLE & (*p)->blocked)为忽略阻塞信号。
32到48行是调度程序中主要的部分。
先对几个变量进行说明。
(*p)->counter 表示 任务状态的剩余滴答计数。
i表示任务标号,p表示任务数组的地址。
c和next用来保存(*p)->counter和i
这里需要对i和p进行说明。初始
i = NR_TASKS;
p =&task[NR_TASKS]
这两个都是无效值,因为NR_TASKS,用宏定义为64,也就是最多运行64个任务。但因为有任务0,所以任务数只能从0-63.
所以在37,38行判断前对i和p都进行了前减减操作。
39行也是为了判断任务存在,不存在的任务跳过。
40和41行是为了找到当前所有任务中即处于就绪态,且剩余的滴答计时最多的任务。
43行如果找到当前所有任务中即处于就绪态,且剩余的滴答计时最多的任务。跳出循环到49行进行任务切换。
如果当前就绪的所有任务的剩余的滴答数都为0,则重新为所有任务都分配滴答数。
45行为跳过不存在的任务。
46.47行为任务重新分配滴答数。
(*p)->counter = ((*p)->counter >> 1) + (*p)->priority;
算法为counter = counter/2 + priority
44到48行是为所有的任务都重新分配滴答数。因为之前40行判断的时候可能处于非就绪状态的任务滴答数可能不为0,所以本次分配要对那些在40行判断非就绪状态的任务的滴答数加上之前剩余的一半 再加上自己的优先级。
此时系统中就绪态的任务的滴答数已经重新分配,所以循环回32行,可以重新找到就绪态的最大滴答数的任务。
然后在43行通过break退出循环,执行任务切换。
linux0.11学习之schedule相关推荐
- main函数解析(一)——Linux-0.11 学习笔记(五)
main()函数解析(一)--Linux-0.11 学习笔记(五) 经过了前面的各种铺垫,终于来到了main函数.这篇博客的任务是把init/main.c讲清楚.由于牵扯到很多的函数调用,要想一次就说 ...
- main 函数解析(二)—— Linux-0.11 学习笔记(六)
main函数解析(二)--Linux-0.11 学习笔记(六) 4.6 blk_dev_init函数 void blk_dev_init(void) {int i;for (i=0 ; i<NR ...
- kernel_mktime() 详解 —— Linux-0.11 学习笔记(四)
题目:kernel_mktime() 详解 -- Linux-0.11 学习笔记(四) 在init/main.c文件中,有一个函数static void time_init(void) 该函数读取 C ...
- setup.s 分析—— Linux-0.11 学习笔记(二)
更新记录 版本 时间 修订内容 1.0 2018-4-14 增加了"获取显示模式"这一节,AL取值的表格 标题: setup.s 分析-- Linux-0.11 学习笔记(二) 老 ...
- Linux0.11学习研究
Linux0.11 环境搭建: 我参考的是这个博客:http://blog.csdn.net/u014688145/article/details/50575588 下载的文件:点击打开链接http: ...
- linux0.11学习笔记-技术铺垫-简单AB任务切换程序(1)-实现一个简单的bootloader
直接看代码,即使已经理解了代码,但是还是会有种没有学到手的感觉.真正的掌握来自实践,来自己动手做出来."简单AB任务切换程序"系列文章的目的是,在bochs下,实践出简单AB两个任 ...
- head.s 分析——Linux-0.11 学习笔记(三)
题目:head.s 分析 head.s 程序在被编译生成目标文件后会与内核其他程序一起被链接成 system 模块,它位于 system 模块的最开始部分,这也就是为什么称其为"头部(hea ...
- linux0.11学习笔记-技术铺垫-简单AB任务切换程序(3)-调试手段和方法
写底层代码,我们需要特别的手段去调试,去debug.本文针对几种应用场景,介绍几种手段. 1. 查看文件的二进制值 - hexdump命令 以文章(2)中的head程序为例子 ld head.o -m ...
- main() 函数解析(一)——Linux-0.11 剖析笔记(六)
文章目录 1. 宏定义`_syscall0` 2. `setup.s`读取的参数 3. 读取CMOS实时时钟信息 3.1 `outb_p(value,port)` 3.2 `inb_p(port)` ...
最新文章
- 推荐一个 Java 实体映射工具 MapStruct
- 博客搭建攻略(三):创造收益
- VTK:PolyData之Outline
- Nginx中添加gzip_static支持
- Docker中拉取ActiveMQ镜像安装运行网页无法访问已解决
- duliu——思维+线段树
- Facebook又开两处AI实验室,在西雅图和匹兹堡招兵买马
- 压缩UI深度的代码实现
- 浅析C++开发工程师的薪资与发展
- Ubuntu、kubuntu、xUbuntu、lubuntu等版本区别及界面样式
- logstash安装 window版
- html中左三角怎么写,css3三角形怎么写?
- JavaScript学习笔记(25) JavaScript.then()这个方法是什么意思?
- html标签(段落标签,换行标签,文本格式化标签和局部标签)-小白学习中
- java 汉字转换为拼音
- lucas-kanade学习
- matlab课本作业答案,MATLAB 实用教程 课后习题答案
- win7 jdk install and config
- 用Github建立个人主页
- 转:你的领导激情在哪里?发现它并为之而奋斗
热门文章
- 在App Service 透过Html 产生PDF
- Nginx面试!java项目答辩问题及答案
- dubbo的后台管理以及监控中心
- excel教程自学网_Excel自学教程:办公室必备技能——Excel表格的打印技巧
- python回车和换行的区别_回车与换行的区别(转)
- vue 使用orgChart
- 初三开始学计算机能够获奖吗,【喜报】我校初三王泽远同学喜获清华大学自主招生资格...
- 屁精 apple-polisher
- 攻防世界web入门-xff_referer write up
- 关于Drools:kie引擎的rest接口调用学习笔记