Fix lab6
This commit is contained in:
parent
bd716e0b99
commit
fccd40f1ac
|
@ -9,41 +9,41 @@
|
|||
* 为了保证调度器接口的通用性,ucore调度框架定义了如下接口,该接口中,几乎全部成员变量均为函数指针。具体的功能会在后面的框架说明中介绍。
|
||||
|
||||
```
|
||||
1 struct sched_class {
|
||||
2 // 调度器的名字
|
||||
3 const char *name;
|
||||
4 // 初始化运行队列
|
||||
5 void (*init) (struct run_queue *rq);
|
||||
6 // 将进程 p 插入队列 rq
|
||||
7 void (*enqueue) (struct run_queue *rq, struct proc_struct *p);
|
||||
8 // 将进程 p 从队列 rq 中删除
|
||||
9 void (*dequeue) (struct run_queue *rq, struct proc_struct *p);
|
||||
10 // 返回 运行队列 中下一个可执行的进程
|
||||
11 struct proc_struct* (*pick_next) (struct run_queue *rq);
|
||||
12 // timetick 处理函数
|
||||
13 void (*proc_tick)(struct run_queue* rq, struct proc_struct* p);
|
||||
14 };
|
||||
1 struct sched_class {
|
||||
2 // 调度器的名字
|
||||
3 const char *name;
|
||||
4 // 初始化运行队列
|
||||
5 void (*init) (struct run_queue *rq);
|
||||
6 // 将进程 p 插入队列 rq
|
||||
7 void (*enqueue) (struct run_queue *rq, struct proc_struct *p);
|
||||
8 // 将进程 p 从队列 rq 中删除
|
||||
9 void (*dequeue) (struct run_queue *rq, struct proc_struct *p);
|
||||
10 // 返回 运行队列 中下一个可执行的进程
|
||||
11 struct proc_struct* (*pick_next) (struct run_queue *rq);
|
||||
12 // timetick 处理函数
|
||||
13 void (*proc_tick)(struct run_queue* rq, struct proc_struct* p);
|
||||
14 };
|
||||
```
|
||||
|
||||
* 此外,proc.h 中的 struct proc\_struct 中也记录了一些调度相关的信息:
|
||||
|
||||
```
|
||||
1 struct proc_struct {
|
||||
2 // . . .
|
||||
3 // 该进程是否需要调度,只对当前进程有效
|
||||
4 volatile bool need_resched;
|
||||
5 // 该进程的调度链表结构,该结构内部的连接组成了 运行队列 列表
|
||||
6 list_entry_t run_link;
|
||||
7 // 该进程剩余的时间片,只对当前进程有效
|
||||
8 int time_slice;
|
||||
9 // round-robin 调度器并不会用到以下成员
|
||||
10 // 该进程在优先队列中的节点,仅在 LAB6 使用
|
||||
11 skew_heap_entry_t lab6_run_pool;
|
||||
12 // 该进程的调度优先级,仅在 LAB6 使用
|
||||
13 uint32_t lab6_priority;
|
||||
14 // 该进程的调度步进值,仅在 LAB6 使用
|
||||
15 uint32_t lab6_stride;
|
||||
16 };
|
||||
1 struct proc_struct {
|
||||
2 // . . .
|
||||
3 // 该进程是否需要调度,只对当前进程有效
|
||||
4 volatile bool need_resched;
|
||||
5 // 该进程的调度链表结构,该结构内部的连接组成了 运行队列 列表
|
||||
6 list_entry_t run_link;
|
||||
7 // 该进程剩余的时间片,只对当前进程有效
|
||||
8 int time_slice;
|
||||
9 // round-robin 调度器并不会用到以下成员
|
||||
10 // 该进程在优先队列中的节点,仅在 LAB6 使用
|
||||
11 skew_heap_entry_t lab6_run_pool;
|
||||
12 // 该进程的调度优先级,仅在 LAB6 使用
|
||||
13 uint32_t lab6_priority;
|
||||
14 // 该进程的调度步进值,仅在 LAB6 使用
|
||||
15 uint32_t lab6_stride;
|
||||
16 };
|
||||
```
|
||||
|
||||
在此次实验中,你需要了解 default\_sched.c中的实现RR调度算法的函数。在该文件中,你可以看到ucore 已经为 RR 调度算法创建好了一个名为 RR\_sched\_class 的调度策略类。
|
||||
|
@ -51,16 +51,16 @@
|
|||
通过数据结构 struct run\_queue 来描述完整的 run\_queue(运行队列)。它的主要结构如下:
|
||||
|
||||
```
|
||||
1 struct run_queue {
|
||||
2 //其运行队列的哨兵结构,可以看作是队列头和尾
|
||||
3 list_entry_t run_list;
|
||||
4 //优先队列形式的进程容器,只在 LAB6 中使用
|
||||
5 skew_heap_entry_t *lab6_run_pool;
|
||||
6 //表示其内部的进程总数
|
||||
7 unsigned int proc_num;
|
||||
8 //每个进程一轮占用的最多时间片
|
||||
9 int max_time_slice;
|
||||
10 };
|
||||
1 struct run_queue {
|
||||
2 //其运行队列的哨兵结构,可以看作是队列头和尾
|
||||
3 list_entry_t run_list;
|
||||
4 //优先队列形式的进程容器,只在 LAB6 中使用
|
||||
5 skew_heap_entry_t *lab6_run_pool;
|
||||
6 //表示其内部的进程总数
|
||||
7 unsigned int proc_num;
|
||||
8 //每个进程一轮占用的最多时间片
|
||||
9 int max_time_slice;
|
||||
10 };
|
||||
```
|
||||
|
||||
在 ucore 框架中,运行队列存储的是当前可以调度的进程,所以,只有状态为runnable的进程才能够进入运行队列。当前正在运行的进程并不会在运行队列中,这一点需要注意。
|
||||
|
|
|
@ -42,11 +42,12 @@ stride溢出以后,基于stride的比较可能会出现错误。比如假设
|
|||
|
||||
![image](../lab6_figs/image002.png)
|
||||
|
||||
可以看到由于溢出的出现,进程间stride的理论比较和实际比较结果出现了偏差。我们首先在理论上分析这个问题:令PASS\_MAX为当前所有进程里最大的步进值。则我们可以证明如下结论:对每次Stride调度器的调度步骤中,有其最大的步进值STRIDE\_MAX和最小的步进值STRIDE\_MIN
|
||||
之差:
|
||||
可以看到由于溢出的出现,进程间stride的理论比较和实际比较结果出现了偏差。我们首先在理论上分析这个问题:令PASS\_MAX为当前所有进程里最大的步进值。则我们可以证明如下结论:对每次Stride调度器的调度步骤中,有其最大的步进值STRIDE\_MAX和最小的步进值STRIDE\_MIN之差:
|
||||
|
||||
STRIDE\_MAX – STRIDE\_MIN <= PASS\_MAX
|
||||
提问 1:如何证明该结论? 有了该结论,在加上之前对优先级有Priority \> 1限制,我们有STRIDE\_MAX – STRIDE\_MIN <= BIG\_STRIDE,于是我们只要将BigStride取在某个范围之内,即可保证对于任意两个 Stride 之差都会在机器整数表示的范围之内。而我们可以通过其与0的比较结构,来得到两个
|
||||
Stride的大小关系。在上例中,虽然在直接的数值表示上 98 < 65535,但是 98 - 65535 的结果用带符号的 16位整数表示的结果为99,与理论值之差相等。所以在这个意义下 98 \> 65535。
|
||||
基于这种特殊考虑的比较方法,即便Stride有可能溢出,我们仍能够得到理论上的当前最小Stride,并做出正确的调度决定。
|
||||
|
||||
提问 1:如何证明该结论?
|
||||
|
||||
有了该结论,在加上之前对优先级有Priority \> 1限制,我们有STRIDE\_MAX – STRIDE\_MIN <= BIG\_STRIDE,于是我们只要将BigStride取在某个范围之内,即可保证对于任意两个 Stride 之差都会在机器整数表示的范围之内。而我们可以通过其与0的比较结构,来得到两个Stride的大小关系。在上例中,虽然在直接的数值表示上 98 < 65535,但是 98 - 65535 的结果用带符号的 16位整数表示的结果为99,与理论值之差相等。所以在这个意义下 98 \> 65535。基于这种特殊考虑的比较方法,即便Stride有可能溢出,我们仍能够得到理论上的当前最小Stride,并做出正确的调度决定。
|
||||
|
||||
提问 2:在 ucore 中,目前Stride是采用无符号的32位整数表示。则BigStride应该取多少,才能保证比较的正确性?
|
||||
|
|
Loading…
Reference in New Issue