为什么在内核中同步代码时需要禁用中断?
例如,在以下代码中取自linux schedule()函数:
need_resched:
prev = current;
rq = this_rq();
**spin_lock_irq(&rq->lock);** //disables interrupts
switch (prev->state) {
case TASK_INTERRUPTIBLE:
if (unlikely(signal_pending(prev))) {
prev->state = TASK_RUNNING;
break;
}
default:
deactivate_task(prev, rq);
case TASK_RUNNING:
;
}
spin_lock_irq()函数禁用中断,但为什么需要它? 假设我没有禁用中断,并且中断到来,所以我只是处理它并回到调度程序并恢复我正在做的事情。
答案 0 :(得分:2)
这是必要的,因为可以通过软件和硬件中断输入调度程序。
软件中断,例如。 sleep()调用和线程间通信调用(例如,信号量,condvar或事件信号)可能会更改正在运行的线程集,因此将请求调度程序运行。这些调用具有线程/进程上下文,并且只要它们调用内核就会发生。
硬件中断,例如。 KB,鼠标,磁盘,NIC导致驱动程序运行,并且驱动程序可能希望通过运行调度程序来更改正在运行的线程集,例如。使线程准备好被阻止等待磁盘读取。硬件中断没有线程/进程上下文,并且可以在启用中断的任何时候发生。
调度程序代码/数据的某些部分不可重入。如果没有为这些部分短暂禁用中断,则当调度程序被硬件中断并从驱动程序重新进入时,将发生混乱。