linux0.11有一段对缓冲块上锁的代码,定义在ll_rw_blk.c文件中:
static inline void lock_buffer(struct buffer_head * bh)
{
cli();
while (bh->b_lock)
sleep_on(&bh->b_wait);
bh->b_lock=1;
sti();
}
可以看到,函数先关闭中断,然后缓冲块被锁定的话就跑去睡眠。直到该缓冲块解锁的时候唤醒所有等待该缓冲块的进程(包括此进程)。这里有个矛盾,假设缓冲块上锁的原因是正在进行磁盘读写,那么解锁必然发生在磁盘中断的中断处理程序中,但是这个时候中断被关闭了,磁盘中断不能被处理,那么这个缓冲块不是永远得不到解锁了吗?
想了好久没想通,是不是我哪里理解错误了?
问题解决了:原因是中断许可标志位在EFLAGS寄存器中,而这个寄存器是进程上下文的一部分,也就是说每个进程都有各自的中断许可状态。所以如果一个进程关闭中断并跑去睡眠,并不影响其后进程的中断位状态。