//锁住bh
static inline void lock_buffer(struct buffer_head * bh)
{
if (bh->b_lock)
printk("hd.c: buffer multiply locked\n");
bh->b_lock=1;
}
static inline void unlock_buffer(struct buffer_head * bh)
{
if (!bh->b_lock)
printk("hd.c: free buffer being unlocked\n");
bh->b_lock=0;
wake_up(&bh->b_wait);
}
static inline void wait_on_buffer(struct buffer_head * bh)
{
cli(); //禁止中断
while (bh->b_lock)
sleep_on(&bh->b_wait);
sti(); //恢复中断
}
//Linux 0.99.15的sleep和wake_up的实现(支持等待队列):
static inline void __sleep_on(struct wait_queue **p, int state)
{
unsigned long flags;
struct wait_queue wait = { current, NULL };
if (!p)
return;
if (current == task[0])
panic("task[0] trying to sleep");
current->state = state;
add_wait_queue(p, &wait); //将当前进程加入等待队列
save_flags(flags); //保存中断掩码
sti(); //屏蔽中断
schedule(); //上下文切换
remove_wait_queue(p, &wait); //从等待队列中移除当前进程
restore_flags(flags); //恢复中断掩码
}
void wake_up(struct wait_queue **q)
{
struct wait_queue *tmp;
struct task_struct * p;
if (!q || !(tmp = *q))
return;
do {//将等待队列中唤醒队首进程
if ((p = tmp->task) != NULL) {
if ((p->state == TASK_UNINTERRUPTIBLE) ||
(p->state == TASK_INTERRUPTIBLE)) {
p->state = TASK_RUNNING;
if (p->counter > current->counter)
need_resched = 1;
}
}
if (!tmp->next) {
printk("wait_queue is bad (eip = %08lx)\n",((unsigned long *) q)[-1]);
printk(" q = %p\n",q);
printk(" *q = %p\n",*q);
printk(" tmp = %p\n",tmp);
break;
}
tmp = tmp->next;
} while (tmp != *q);
} |