[rCore学习笔记 021]多道程序与分时任务

[rCore学习笔记 021]多道程序与分时任务

写在前面

本随笔是非常菜的菜鸡写的。如有问题请及时提出。

可以联系:1160712160@qq.com

GitHhub:https://github.com/WindDevil(目前啥也没有

导读

这里就是第三章的开头了,由于我的巨菜,导致天天半天理解不了关键点所在,唉,实在是太折磨人.

遵照上一章开头的时候的优良传统,我个人感觉每次手册给出feature都要想一想上一章对于这个功能我们是怎么实现的,现在的功能是有什么好处.这样可以加深印象.

提高系统的性能和效率是操作系统的核心目标之一,本章展现了操作系统在性能上的一系列功能改进:

通过提前加载应用程序到内存,减少应用程序切换开销

通过协作机制支持程序主动放弃处理器,提高系统执行效率

通过抢占机制支持程序被动放弃处理器,保证不同程序对处理器资源使用的公平性,也进一步提高了应用对 I/O 事件的响应效率

同样地,一定要去阅读官方文档,可能我关注的点并不够全面.

这里进行自己的头脑风暴,思考实现方式:

提前加载应用程序到内存的方法:

使用更多的内存,把所有的应用程序一股脑地加载进去,然后把在内存中的地址返回

如果我不是把所有的应用程序全部都加载在内存中,那么我们是怎么知道等一下要运行哪个应用程序的呢?

实现协作机制和抢占机制的方法,感觉它写的是应用程序主动放弃处理器,但是实际上做实现的时候我又想利用类似于中断的方式解决问题,就是保存上下文然后跳转那一套东西,至于如何计算时间,就很难想到其内部实现,我感觉这时候一定要使用到定时器了.

总而言之,脑子里还是之前使用RT-Thread和FreeRTOS的时候的幼稚的.APP1->delay->抢占->APP2->APP1这种想法.

这时候就需要更深入的了解.

可以在这里了解到,在协作式模式下,需要程序员主动在程序中写一个主动放弃处理器的调用请求.

而对于抢占式, 则是使用中断直接打断程序运行,从而保证一个应用程序在执行完一段时间以后一定会让出处理器,这里截取一段官方文档的描述:

操作系统可进一步利用某种以固定时长为时间间隔的外设中断(比如时钟中断)来强制打断一个程序的执行,这样一个程序只能运行一段时间(可以简称为一个时间片, Time Slice)就一定会让出处理器,且操作系统可以在处理外设的 I/O 响应后,让不同应用程序分时占用处理器执行,并可通过统计程序占用处理器的总执行时间,来评估运行的程序对处理器资源的消耗。我们把这种运行方式称为 分时共享(Time Sharing) 或 抢占式多任务(Multitasking) ,也可合并在一起称为 分时多任务 。

这里就从脑海的深处想起来关于裸机编程的东西,就是使用定时器中断来实现分时复用,那么和使用抢占式的分时复用有什么区别呢?

定时器的数量有限

使用软定时器解决问题对于固定行为固定时长的程序有效,但是对于含有各种复杂分支的程序就比较难办

这里还有一个问题,就是对于波形采样这样时间敏感型的任务,可以放心把它交给OS吗?还是说需要结合定时器中断和OS调度.那么怎么结合呢?

最后截取官方文档对这章实现的定位和分类:

本章所介绍的多道程序和分时多任务系统都有一些共同的特点:在内存中同一时间可以驻留多个应用,而且所有的应用都是在系统启动的时候分别加载到内存的不同区域中。由于目前计算机系统中只有一个处理器核,所以同一时间最多只有一个应用在执行(即处于运行状态),剩下的应用处于就绪状态或等待状态,需要内核将处理器分配给它们才能开始执行。一旦应用开始执行,它就处于运行状态了。

本章主要是设计和实现建立支持 多道程序 的二叠纪“锯齿螈” 1 初级操作系统、支持 多道程序 的三叠纪“始初龙” 2 协作式操作系统和支持 分时多任务 的三叠纪“腔骨龙” 3 抢占式操作系统,从而对可支持运行一批应用程序的多种执行环境有一个全面和深入的理解,并可归纳抽象出 任务 、 任务切换 等操作系统的概念。

实践体验

同样地,我们可以很方便地利用rCore-Tutorial-v3,体验这两种操作系统的实现.

首先我们需要切换到文件夹下cd ~/App/rCore-Tutorial-v3.

体验多道程序操作系统

切换到多道操作系统并且运行:

git checkout ch3-coop

cd os

make run

这里注意,如果你修改了分支的内容导致不能切换分支,你可以使用git checkout -- .来丢弃所有的更改,这样就可以切换到新的分支.

运行结果:

[rustsbi] RustSBI version 0.3.1, adapting to RISC-V SBI v1.0.0

.______ __ __ _______.___________. _______..______ __

| _ \ | | | | / | | / || _ \ | |

| |_) | | | | | | (----`---| |----`| (----`| |_) || |

| / | | | | \ \ | | \ \ | _ < | |

| |\ \----.| `--' |.----) | | | .----) | | |_) || |

| _| `._____| \______/ |_______/ |__| |_______/ |______/ |__|

[rustsbi] Implementation : RustSBI-QEMU Version 0.2.0-alpha.2

[rustsbi] Platform Name : riscv-virtio,qemu

[rustsbi] Platform SMP : 1

[rustsbi] Platform Memory : 0x80000000..0x88000000

[rustsbi] Boot HART : 0

[rustsbi] Device Tree Region : 0x87000000..0x87000f02

[rustsbi] Firmware Address : 0x80000000

[rustsbi] Supervisor Address : 0x80200000

[rustsbi] pmp01: 0x00000000..0x80000000 (-wr)

[rustsbi] pmp02: 0x80000000..0x80200000 (---)

[rustsbi] pmp03: 0x80200000..0x88000000 (xwr)

[rustsbi] pmp04: 0x88000000..0x00000000 (-wr)

[kernel] Hello, world!

AAAAAAAAAA [1/5]

BBBBBBBBBB [1/2]

CCCCCCCCCC [1/3]

AAAAAAAAAA [2/5]

BBBBBBBBBB [2/2]

CCCCCCCCCC [2/3]

AAAAAAAAAA [3/5]

Test write_b OK!

[kernel] Application exited with code 0

CCCCCCCCCC [3/3]

AAAAAAAAAA [4/5]

Test write_c OK!

[kernel] Application exited with code 0

AAAAAAAAAA [5/5]

Test write_a OK!

[kernel] Application exited with code 0

All applications completed!

这个运行结果是这样的 [ 1/5 ]的意思是执行到了第五次执行中的第一次,这样就很容易理解这个程序的结果了,也就是轮流在执行都已经被加载到内存中的分别能输出一串A,B,C的三个程序.

然后执行到限制的次数为止.

体验分时多任务操作系统

cd ~/App/rCore-Tutorial-v3,再次回到根文件下,切换到分时多任务操作系统并运行:

git checkout ch3

cd os

make run

运行结果:

[rustsbi] RustSBI version 0.3.1, adapting to RISC-V SBI v1.0.0

.______ __ __ _______.___________. _______..______ __

| _ \ | | | | / | | / || _ \ | |

| |_) | | | | | | (----`---| |----`| (----`| |_) || |

| / | | | | \ \ | | \ \ | _ < | |

| |\ \----.| `--' |.----) | | | .----) | | |_) || |

| _| `._____| \______/ |_______/ |__| |_______/ |______/ |__|

[rustsbi] Implementation : RustSBI-QEMU Version 0.2.0-alpha.2

[rustsbi] Platform Name : riscv-virtio,qemu

[rustsbi] Platform SMP : 1

[rustsbi] Platform Memory : 0x80000000..0x88000000

[rustsbi] Boot HART : 0

[rustsbi] Device Tree Region : 0x87000000..0x87000f02

[rustsbi] Firmware Address : 0x80000000

[rustsbi] Supervisor Address : 0x80200000

[rustsbi] pmp01: 0x00000000..0x80000000 (-wr)

[rustsbi] pmp02: 0x80000000..0x80200000 (---)

[rustsbi] pmp03: 0x80200000..0x88000000 (xwr)

[rustsbi] pmp04: 0x88000000..0x00000000 (-wr)

[kernel] Hello, world!

power_3 [10000/200000]

power_3 [20000/200000]

power_3 [30000/200000]

power_3 [40000/200000]

power_3 [50000/200000]

power_3 [60000/200000]

power_3 [70000/200000]

power_3 [80000/200000]

power_3 [90000/200000]

power_3 [100000/200000]

power_3 [110000/200000]

power_3 [120000/200000]

power_3 [130000/200000]

power_3 [140000/200000]

power_3 [150000/200000]

power_3 [160000/200000]

power_3 [170000/200000]

power_3 [180000/200000]

power_3 [190000/200000]

power_3 [200000/200000]

3^200000 = 871008973(MOD 998244353)

Test power_3 OK!

[kernel] Application exited with code 0

power_5 [10000/140000]

power_5 [20000/140000]

power_5 [30000/140000]

power_5 [40000/140000]

power_5 [50000/140000]

power_5 [60000/140000]

power_5 [70000/140000]

power_5 [80000/140000]

power_5 [90000/140000]

power_5 [100000/140000]

power_5 [110000/140000]

power_5 [120000/140000]

power_7 [10000/160000]

power_7 [20000/160000]

power_7 [30000/160000]

power_7 [40000/160000]

power_7 [50000/160000]

power_7 [60000/160000]

power_7 [70000/160000]

power_7 [80000/160000]

power_7 [90000/160000]

power_7 [100000/160000]

power_7 [110000/160000]

power_7 [120000/160000]

power_7 [130000/160000]

power_7 [140000/160000]

power_7 [150000/160000]

power_7 [160000/160000]

7^160000 = 667897727(MOD 998244353)

Test power_7 OK!

[kernel] Application exited with code 0

power_5 [130000/140000]

power_5 [140000/140000]

5^140000 = 386471875(MOD 998244353)

Test power_5 OK!

[kernel] Application exited with code 0

Test sleep OK!

[kernel] Application exited with code 0

All applications completed!

官方文档对它的解析为:

分时多任务系统应用分为两种。编号为 00/01/02 的应用分别会计算质数 3/5/7 的幂次对一个大质数取模的余数,并会将结果阶段性输出。编号为 03 的应用则会等待三秒钟之后再退出。以 k210 平台为例,我们将会看到 00/01/02 三个应用分段完成它们的计算任务,而应用 03 由于等待时间过长总是最后一个结束执行。

代码结构

这是本章多道程序操作系统的代码结构:

这是上一章的代码结构,可以看到本章的多道任务是多了几个APP的框图在U-Mode:

这是更进一步的协作式分时操作系统的框图:

首先先说我自己看到这张图的感受,

在原本的多道系统的基础上为每个APP都增加了一个保存上下文的栈.

把AppManager拆分成Loader和TaskManager.

增加了任务状态和任务上下文的概念,应该是用于分时复用,但是不知道具体怎么实现的.

为CPU增加了一条时间线,应该是用于分时复用,但是不知道具体怎么实现的.

通过查看官方文档,我们可以另外补充到一些我们不知道的东西:

如果当前应用程序正在运行,则该应用对应的任务处于运行(Running)状态;如果该应用主动放弃处理器,则该应用对应的任务处于就绪(Ready)状态。操作系统进行任务切换时,需要把要暂停任务的上下文(即任务用到的通用寄存器)保存起来,把要继续执行的任务的上下文恢复为暂停前的内容,这样就能让不同的应用协同使用处理器了。

这是更进一步的抢占式多任务操作系统的框图:

同样地,先观察这个图讲出自己的感受:

初看和协作式没有什么不同之处

细看发现在Trap_handler,里边增加了Timer的调度,可能和我想得一样是用定时器来触发中断然后实现时间片的轮转.

实际上官方文档的描述也大致如此.

本章代码导读

这一部分的作者写得太好了,我直接无话可说.直接点击观看吧.

本章的重点是实现对应用之间的协作式和抢占式任务切换的操作系统支持。与上一章的操作系统实现相比,有如下一些不同的情况导致实现上也有差异:

多个应用同时放在内存中,所以他们的起始地址是不同的,且地址范围不能重叠

应用在整个执行过程中会暂停或被抢占,即会有主动或被动的任务切换

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛马程序员24

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值