linux的可中断sleep_on函数分析

Posted on 2018-03-08 20:50  王将军之武库  阅读(1075)  评论(0)    收藏  举报
void interruptible_sleep_on (struct task_struct **p)// **p是个全局变量
{
    struct task_struct *tmp;

    if (!p)#没有进程等待就返回
        return;
    if (current == &(init_task.task))
        panic ("task[0] trying to sleep");
    tmp = *p;#在自己的内核堆栈中,暂时保存原来保存在**p中的进程,因为调度时,还没有退出interruptible_sleep_on函数
    *p = current;#**p保存当前进程
repeat:
    current->state = TASK_INTERRUPTIBLE;#改变当前进程状态
    schedule ();
// 如果等待队列中还有等待任务,并且队列头指针所指向的任务不是当前任务时,则将该等待任务置为
// 可运行的就绪状态,并重新执行调度程序。当指针*p 所指向的不是当前任务时,表示在当前任务被放
// 入队列后,又有新的任务被插入等待队列中,因此,既然本任务是可中断的,就应该首先执行所有
// 其它的等待任务。
    if (*p && *p != current)#可能有其他进程调用该函数
    {
        (**p).state = 0;
        goto repeat;
    }
// 下面一句代码有误,应该是*p = tmp,让队列头指针指向其余等待任务,否则在当前任务之前插入
// 等待队列的任务均被抹掉了。参见图4.3。
    *p = NULL;
    if (tmp)
        tmp->state = 0;
}
sleep_if_full (struct tty_queue *queue)
{
// 若队列缓冲区不满,则返回退出。
    if (!FULL (*queue))
        return;
    cli ();            // 关中断。
// 如果进程没有信号需要处理并且队列缓冲区中空闲剩余区长度<128,则让进程进入可中断睡眠状态,
// 并让该队列的进程等待指针指向该进程。
    while (!current->signal && LEFT (*queue) < 128)
        interruptible_sleep_on (&queue->proc_list);//队列的进程列表,保存的是pcb指针
    sti ();            // 开中断。
}

//// 等待按键。
// 如果控制台的读队列缓冲区空则让进程进入可中断的睡眠状态。
void wait_for_keypress (void)
{
    sleep_if_empty (&tty_table[0].secondary);
}

 

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3