Jos - lab4 (Part A) Round-Robin Scheduling
来源:互联网 发布:最小中文linux操作系统 编辑:程序博客网 时间:2024/06/05 10:14
Exercise 6.Implement round-robin scheduling in sched_yield()
as described above. Don't forget to modifysyscall()
to dispatchsys_yield()
.
这段code不算太多,不过一直碰到一个问题,每次sys_halt()以后就出现Gerneral Protection的exception:
HLT—Halt
Opcode Instruction Description
F4 HLT Halt
Description
Stops instruction execution and places the processor in a HALT state. An enabled interrupt
(including NMI and SMI), a debug exception, the BINIT# signal, the INIT# signal, or the
RESET# signal will resume execution. If an interrupt (including NMI) is used to resume execu-
tion after a HLT instruction, the saved instruction pointer (CS:EIP) points to the instruction
following the HLT instruction.
The HLT instruction is a privileged instruction. When the processor is running in protected or
virtual-8086 mode, the privilege level of a program or procedure must be 0 to execute the HLT
instruction.
看起来是发生的权限问题,而根据打出的栈信息来看,cs[bit1][bit0] = 00, 已经是最高级别了,所以看到权限访问上是没有问题的。
trap 0x0000000d General Protection
err 0x00000102
eip 0xf0105499
cs 0x----0008
flag 0x00000246
继续追踪,发现在原来的算法中如果当前指向的envs[0]是RUNNABLE状态的话,就会永远处于被忽略的状态,在原来的轮询中永远排不上,结果就导致了改进入monitor()的循环,却进了halt。至于最后为什么导致generation protection的问题,还没有完全搞清楚。粗线部分是后加的补丁。
32 int i, pos = 0;
33 struct Env *thisenv = thiscpu->cpu_env;
34 if (thisenv == NULL)
35 thisenv = &envs[0];
37 // find the position of thisenv in envs[]
38 for (i = 0; i < NENV; i++) {
39 if (&envs[i] == thisenv) {
40 pos = i;
41 break;
42 }
43 }
45 for (i = (pos+1)%NENV; i != pos; i = (i+1)%NENV) {
46 if (envs[i].env_status == ENV_RUNNABLE) {
47 // Following are all done in env_run()
48 //c->cpu_env->env_status = ENV_RUNNABLE;
49 //c->cpu_env = &envs[i];
50 //unlock_kernel();
52 env_run(&envs[i]);
53 }
54 }
55 //if ((i == pos) && (thisenv->env_status == ENV_RUNNING)) {
56 if ((thisenv->env_status == ENV_RUNNING) || (thisenv->env_status == ENV_RUNNABLE)) {
59 env_run(thisenv);
60 }
62 // sched_halt never returns
63 sched_halt();
可是在cpu数目多的情况下还是会出现一定概率的page fault,从user在执行env_destroy的时候。
根据trap_init_percpu()的提示应该是设置某个cpu的TSS时出问题了。观察过几个log,发现enviroment[1000]在free后又被调用了,仔细review上面的代码逻辑,就会发现还是有问题的,如果thisenv为NULL的情况下默认把它设置成env[0],会造成一定概率下它被两个以上的cpu同时run起来(见56行),因此最后的版本如下:
32 int i, pos = 0;
33 struct Env *thisenv = thiscpu->cpu_env;
63 if (thisenv != NULL) {
65 // find the position of thisenv in envs[]
66 for (i = 0; i < NENV; i++) {
67 if (&envs[i] == thisenv) {
68 pos = i;
69 break;
70 }
71 }
73 }
74 for (i = (pos+1)%NENV; i != pos; i = (i+1)%NENV) {
75 if (envs[i].env_status == ENV_RUNNABLE) {
77 env_run(&envs[i]);
78 }
79 }
80 if (envs[i].env_status == ENV_RUNNABLE) { // envs[pos] will be exclusive by above loop
82 env_run(&envs[i]);
83 }
84 if (thisenv != NULL) {
85 if (thisenv->env_status == ENV_RUNNING) {
87 env_run(thisenv);
88 }
89 }
92 // sched_halt never returns
93 sched_halt();
最后再回头稍微提一下hlt造成的General Protection fault:
General Protection Fault
A General Protection Fault may occur for various reasons. The most common are:
- Segment error (privilege, type, limit, read/write rights).
- Executing a privileged instruction while CPL != 0.
- Writing a 1 in a reserved register field.
- Referencing or accessing a null-descriptor.
The saved instruction pointer points to the instruction which caused the exception.
Error code: The General Protection Fault sets an error code, which is thesegment selector index when the exception is segment related. Otherwise, 0.
Selector Error Code
31 16 15 3 2 1 0+---+-- --+---+---+-- --+---+---+---+---+| Reserved | Index | Tbl | E |+---+-- --+---+---+-- --+---+---+---+---+
我们发现halt的error code 是102,根据上文的信息,这个异常还是和segment相关,并非halt的权限访问问题,并且tbl=0x01(IDT), Index = 0x102>>3 = 0x20, 可是idt[20]并不存在!!!到了这个份上,我只想怀疑是qemu模拟器的bug -_-|||
Question
3. In your implementation of env_run()
you should havecalled lcr3()
. Before and after the call tolcr3()
, your code makes references (at least it should)to the variablee
, the argument to env_run
.Upon loading the %cr3
register, the addressing contextused by the MMU is instantly changed. But a virtualaddress (namelye
) has meaning relative to a givenaddress context--the address context specifies the physical address towhich the virtual address maps. Why can the pointere
bedereferenced both before and after the addressing switch?
- Jos - lab4 (Part A) Round-Robin Scheduling
- MIT JOS # RoundRobin Scheduling#
- Jos - lab4 (Part A) Multiprocessor support
- Jos - lab4 (Part A) System Calls for Environment Creation
- Round-Robin Scheduling
- Round Robin Scheduling
- JOS-lab4
- [MIT6.828] LAB4 PART A
- 轮叫调度(Round-Robin Scheduling
- 轮询调度算法(Round-Robin Scheduling)
- 轮询调度算法(Round-Robin Scheduling)
- 轮询调度算法(Round-Robin Scheduling)
- 轮询调度算法(Round-Robin Scheduling)
- 轮询调度算法(Round-Robin Scheduling)
- RR调度(Round-robin scheduling)简介
- 轮询调度算法(Round-Robin Scheduling)
- 轮询调度算法(Round-Robin Scheduling)
- 加权轮叫调度(Weighted Round-Robin Scheduling)
- MediaPlayer播放网络音频
- 【最小生成树】+【并查集】-HDU-1879-继续畅通工程
- JS——元素、事件对象属性详解
- 用C#编程的一些建议(规范写法,使用技巧,少走弯路)ZZ
- 2.8 python中的if...elif...else语句 [python入门教程]
- Jos - lab4 (Part A) Round-Robin Scheduling
- c语言复习整理1
- Unity 3D插件大全
- 赚钱和爱情
- uva 608 - Counterfeit Dollar(枚举)
- Coursera 《机器学习》(Lecture 07)
- 学一点Git--20分钟git快速上手
- jsp/asp/html/php/js/javascript/python脚本语言/开发 设计 定制 升级
- ApacheBench 测试性能并使用GnuPlot绘制图表