协作式和抢占式
时间:2024-05-02
批处理系统的特性是:在内存中同一时间最多只需驻留一个应用。 只有当一个应用出错或退出之后,批处理系统才会去将另一个应用加载到相同的一块内存区域。
为了提高 CPU 的利用率,操作系统演进成加载多个应用,并发运行这些应用。有两种方式执行这些应用:
- 协作式:让当前执行的应用主动放弃 CPU 的控制权,其他处理器才能执行其他应用
- 缺点:程序无法做到在合适位置放置放弃处理器的系统调用请求,整体利用率仍然无法提高
- 抢占式:利用硬件的中断机制,系统强制中断应用,应用被动放弃 CPU 的控制权,让多个程序交替执行。(重点)
协作式对降低延迟有益(比如减少等待其他程序让出 CPU 控制权),而抢占式对提高吞吐量有益(比如有利于提高单位时间内执行的指令数量)。
分时共享(Time Sharing)或抢占式多任务 (Multitasking) 或分时多任务: 在一个包含多个时间片的时间段上,会有属于不同程序的多个任务片在轮流占用处理器执行。
- 时间片 (time slice):一个程序运行的一段时间
- 任务 (task):一个程序的一次完整执行过程
- 任务片 (task slice):一个程序在一个时间片上占用处理器执行的过程
以固定时长为时间间隔的外设中断(比如时钟中断)来强制打断一个程序的执行。 这样一个程序只能运行一段时间(可以简称为一个时间片, Time Slice)就一定会让出处理器,且操作系统可以在处理外设的 I/O 响应后,让不同应用程序分时占用处理器执行,并可通过统计程序占用处理器的总执行时间,来评估运行的程序对处理器资源的消耗。 这需要两个要素:及时响应和快速执行。具体为:
- 硬件提供中断机制:在必要的时候(用户敲键盘或时间片到了),硬件能通过中断打断当前执行的应用程序,把控制权交给操作系统, 让操作系统切换到需要及时响应用户需求的应用程序
- 计算机要有足够大的主存,这样应用程序都能放到主存中,这是实现快速保存/恢复程序执行状态并能快速持续执行程序的重要条件之一
中断
中断具有三种类型(软件、时钟、外部设备),并在 M/S 两种权级中出现。中断是异步的,与当前执行的指令无关。
中断屏蔽 (Interrupt Masking):指 CPU 将忽略所有非强制的中断请求(即不响应非强制性的中断请求),继续执行当前的程序代码。
判断屏蔽中断:
- 如果中断的特权级低于 CPU 当前的特权级,则该中断会被屏蔽,不会被处理(即程序继续执行);
- 如果中断的特权级高于与 CPU 当前的特权级或相同,则需要通过相应的 CSR 判断该中断是否会被屏蔽。对于 S 模式:
- sstatus.SIE 中断使能,为 1 则能够同时控制三种中断(与 sie CSR 结合),为 0 则将它们全部屏蔽
- sie CSR:当 sstatus.SIE 为 1,还要根据这个 CSR 的 ssie/stie/seie 字段的值才能真正控制响应还是屏蔽中断请求
- 对于非强制性中断请求,即使在上述满足中断被屏蔽的情况下,CPU 也必须立即响应中断,暂停当前执行的指令。这些请求包括:
- 非屏蔽中断(Non-maskable Interrupt, NMI):严重的硬件故障或系统级错
- 机器检查中断(Machine Check Interrupt):由硬件异常条件触发的中断,如内存奇偶校验错误、总线错误或处理器内部错误
- 调试中断:如断点,可能会被视为强制性的,特别是当用于调试目的时
- 实时时钟中断:这通常不是强制性的,但某些实时操作系统中会被它赋予高优先级,以确保时间关键的任务能够按时执行
- 电源故障中断、虚拟化中断、安全异常
中断 i 陷入 S 模式的条件,必须为以下的一种情况
- 当前处于 S 模式,且 sstatus.SIE 为 1,且 i 在 sip 和 sie CSR 中开启
- 当前处于 U 模式,且 i 在 sip 和 sie CSR 中开启
其中 i 为 interrupt cause number(i 为第 1/5/9 位 bit,表示 软件/时钟/外设 中断)。对于 i,以下中断相关的寄存器都用到它:
- scause 寄存器内的中断位 1,异常码位 i 为 1(异常码 x 其实就是第 x 位 bit 为 1)
- sip 和 sie CSR 的第 i 位为 1
- 例如 第 1 位为 1,则在 scause 中表示出现软件中断;sip 和 sie 的 第 5 和 9 位为 1,则表示 S 模式会响应时钟和外设中断请求
中断的状态:
- 触发(Trigger):当某个事件(如定时器溢出、外部信号等)发生时,它可能会触发一个中断。
- 挂起(Pending):一旦中断被触发,它就会处于挂起状态,等待CPU的注意。
- 使能(Enable):中断控制器中有一个或多个寄存器(如sie,Supervisor Interrupt Enable),用于确定哪些中断被使能。只有被使能的中断才能被处理。
- 处理(Handling):当中断被使能,并且处理器处于适当的条件(如适当的特权级别)时,它将响应中断,执行中断处理程序(中断和异常区别见 异常控制流)。
- 清除(Clear):中断处理程序通常会在服务完中断后清除挂起位,以表明中断已经被处理。
┌─────────────────┐ ┌──────┐
(sip) │(sstatus.SIE+sie)│ │(Trap)│ (sip)
Trigger ──► Pending ──►│Enable │──►│Handle│──► Clear
(interrupt │ │ │ └──────┘
occurs) └──────►│Disable │(don't respond to interrupt)
└─────────────────┘
S 模式下的中断处理:
- 当 trap 发生时,sstatus.sie 字段会被保存在 sstatus.spie 字段中,同时把 sstatus.sie 字段置零,这样软件在进行后续的中断处理过程中,所有 S 特权级的中断都会被屏蔽;
- 当软件执行中断处理完毕后,会执行 sret 指令返回到被中断打断的地方继续执行,硬件会把 sstatus.sie 字段恢复为 sstatus.spie 字段内的值。
- 如果不去手动设置 sstatus CSR ,在只考虑 S 特权级中断的情况下,在中断处理的过程中同特权级的中断都会被屏蔽,不会出现 嵌套中断。
嵌套中断 (Nested Interrupt):指在处理一个中断的过程中再一次触发了中断。
- 在处理一个中断的过程中,由于默认情况下,在软件开始响应中断前,硬件会自动禁用所有同特权级中断,自然也就不会再次触发中断导致嵌套中断了, 但高特权级中断则是不可避免的会再次发生。
- 嵌套中断是嵌套 Trap 的一个特例。嵌套 Trap 则是指处理一个 Trap(可能是中断或异常)的过程中又再次发生 Trap。
- 在内核开发时我们需要仔细权衡哪些嵌套 Trap 应当被允许存在,哪些嵌套 Trap 又应该被禁止,这会关系到内核的执行模型。