屏蔽与使能中断

根据操作系统原理的知识,我们知道如果没有在硬件级保证读内存-修改值-写回内存的原子性,我们只能通过复杂的软件来实现同步互斥操作。但由于有开关中断和 test_and_set_bit 等原子操作机器指令的存在,使得我们在实现同步互斥原语上可以大大简化。

在 ucore 中提供的底层机制包括中断屏蔽/使能控制等。kern/sync.c 中实现的开关中断的控制函数 local_intr_save(x)和 local_intr_restore(x),它们是基于 kern/driver 文件下的 intr_enable()、intr_disable()函数实现的。具体调用关系为:

关中断:local_intr_save --> __intr_save --> intr_disable --> cli
开中断:local_intr_restore--> __intr_restore --> intr_enable --> sti

最终的 cli 和 sti 是 x86 的机器指令,最终实现了关(屏蔽)中断和开(使能)中断,即设置了 eflags 寄存器中与中断相关的位。通过关闭中断,可以防止对当前执行的控制流被其他中断事件处理所打断。既然不能中断,那也就意味着在内核运行的当前进程无法被打断或被重新调度,即实现了对临界区的互斥操作。所以在单处理器情况下,可以通过开关中断实现对临界区的互斥保护,需要互斥的临界区代码的一般写法为:

local_intr_save(intr_flag);
{
  临界区代码
}
local_intr_restore(intr_flag);
……

由于目前 ucore 只实现了对单处理器的支持,所以通过这种方式,就可简单地支撑互斥操作了。在多处理器情况下,这种方法是无法实现互斥的,因为屏蔽了一个 CPU 的中断,只能阻止本地 CPU 上的进程不会被中断或调度,并不意味着其他 CPU 上执行的进程不能执行临界区的代码。所以,开关中断只对单处理器下的互斥操作起作用。在本实验中,开关中断机制是实现信号量等高层同步互斥原语的底层支撑基础之一。

results matching ""

    No results matching ""