中断屏蔽 (IntrGuard)
IntrGuard 是一个基于RAII模式的工具,用于在代码的特定作用域内安全地禁用和恢复CPU中断。它是实现其他同步原语(如 SpinLock)的底层基石。
源码链接: os/src/sync/intr_guard.rs
1. 工作原理
在单核或不考虑多核并发的场景下,禁用中断是实现原子操作的最简单有效的方法。当中断被禁用时,当前CPU核心不会响应任何外部中断(如时钟中断),因此当前执行的代码流不会被中断处理程序打断,从而保证了操作的原子性。
IntrGuard 的实现非常直接:
- 创建 (
new): 当一个IntrGuard对象被创建时,它会读取sstatus寄存器中当前的中断使能位(SIE),将其保存起来,然后清除SIE位以禁用中断。 - 销毁 (
drop): 当IntrGuard对象离开作用域时,其Drop实现会自动被调用。它会根据创建时保存的原始状态,恢复sstatus寄存器中的SIE位,从而恢复中断。
2. 核心接口
pub fn new() -> Self: 创建一个IntrGuard实例,立即禁用中断。
3. 适用场景
- 作为其他锁的构件:
SpinLock在获取锁时会创建一个IntrGuard,以防止在持有自旋锁的同时被本地中断打断,这是一种标准的组合用法。 - 临时的、短小的临界区: 在某些非常底层的代码中,如果可以确定操作极快且不会与其他核心冲突,可以临时使用
IntrGuard来保证原子性。
警告:
IntrGuard无法阻止来自其他CPU核心的并发访问。在多核环境下,它必须与自旋锁等其他机制结合使用,才能保证真正的互斥。- 滥用中断屏蔽会导致系统响应延迟(例如,无法及时响应时钟中断和I/O中断),因此应尽可能缩短禁用中断的时间。