void sleep_on(struct task_struct **p)
{
struct task_struct *tmp;
if (!p) //若指针无效,则退出
return;
if (current == &(init_task.task)) //若当前任务是任务0则死机
panic("task[0] trying to sleep");
tmp = *p; //让tmp指向已经在等待队列上的任务
*p = current; //将睡眠队列头的等待指针指向当前任务
current->state = TASK_UNINTERRUPTIBLE; //将当前任务置为不可中断的等待状态
schedule(); //重新调度
// 只有当这个等待任务被唤醒时,调度程序才又返回到这里,则表示进程已被明确地唤醒。
if (tmp)
{
struct task_struct *tmp;
if (!p) //若指针无效,则退出
return;
if (current == &(init_task.task)) //若当前任务是任务0则死机
panic("task[0] trying to sleep");
tmp = *p; //让tmp指向已经在等待队列上的任务
*p = current; //将睡眠队列头的等待指针指向当前任务
current->state = TASK_UNINTERRUPTIBLE; //将当前任务置为不可中断的等待状态
schedule(); //重新调度
// 只有当这个等待任务被唤醒时,调度程序才又返回到这里,则表示进程已被明确地唤醒。
if (tmp)
tmp->state=0; // 若在其前还存在等待的任务,则也将其置为就绪状态(唤醒)。
}
在几个进程为等待同一资源而多次调用该函数时,程序就隐式地构筑出一个等待队列。
在插入等待队列后,sleep_on()函数就会调用schedule()函数去执行别的进程。当进程被唤醒而重新
执行时就会执行后续的语句,把比它早进入等待队列的一个进程唤醒。
例如,当task1,task2,task3因为资源暂时不可用而先后调用sleep_on()函数时,