中断屏蔽 (IntrGuard)

IntrGuard 是一个基于RAII模式的工具,用于在代码的特定作用域内安全地禁用和恢复CPU中断。它是实现其他同步原语(如 SpinLock)的底层基石。

源码链接: os/src/sync/intr_guard.rs

1. 工作原理

在单核或不考虑多核并发的场景下,禁用中断是实现原子操作的最简单有效的方法。当中断被禁用时,当前CPU核心不会响应任何外部中断(如时钟中断),因此当前执行的代码流不会被中断处理程序打断,从而保证了操作的原子性。

IntrGuard 的实现非常直接:

  1. 创建 (new): 当一个 IntrGuard 对象被创建时,它会读取 sstatus 寄存器中当前的中断使能位(SIE),将其保存起来,然后清除 SIE 位以禁用中断。
  2. 销毁 (drop): 当 IntrGuard 对象离开作用域时,其 Drop 实现会自动被调用。它会根据创建时保存的原始状态,恢复 sstatus 寄存器中的 SIE 位,从而恢复中断。

2. 核心接口

  • pub fn new() -> Self: 创建一个 IntrGuard 实例,立即禁用中断。

3. 适用场景

  • 作为其他锁的构件: SpinLock 在获取锁时会创建一个 IntrGuard,以防止在持有自旋锁的同时被本地中断打断,这是一种标准的组合用法。
  • 临时的、短小的临界区: 在某些非常底层的代码中,如果可以确定操作极快且不会与其他核心冲突,可以临时使用 IntrGuard 来保证原子性。

警告:

  • IntrGuard 无法阻止来自其他CPU核心的并发访问。在多核环境下,它必须与自旋锁等其他机制结合使用,才能保证真正的互斥。
  • 滥用中断屏蔽会导致系统响应延迟(例如,无法及时响应时钟中断和I/O中断),因此应尽可能缩短禁用中断的时间。