首页 > 系统相关 >Linux0.11 sleep_on wake_up函数理解和纠正

Linux0.11 sleep_on wake_up函数理解和纠正

时间:2022-09-01 17:57:10浏览次数:76  
标签:tmp task struct up current state wake Linux0.11 sleep

/*
 * 将当前进程设置为不可中断的睡眠状态
 * 只有明确进程唤醒才可以
 */
void sleep_on(struct task_struct **p)
{
    struct task_struct *tmp;

    if (!p)
        return;
    if (current == &(init_task.task))
        panic("task[0] trying to sleep");
    tmp = *p;
    *p = current;
    current->state = TASK_UNINTERRUPTIBLE;
    schedule();
    if (tmp)
        tmp->state=TASK_RUNNING;
}

void interruptible_sleep_on(struct task_struct **p)
{
    struct task_struct *tmp;

    if (!p)
        return;
    if (current == &(init_task.task))
        panic("task[0] trying to sleep");
    tmp=*p;
    *p=current;
repeat:    
    current->state = TASK_INTERRUPTIBLE;
    schedule();
    if (*p && *p != current) {
        (*p)->state = TASK_RUNNING;
        goto repeat;
    }
    /* Linux完全注释有如下
     * 原来的代码中*p = NULL
     * 也会导致等待的进程可能没法唤醒,在嵌套的情况下
     * 因此修改为*p = tmp
     * 
     * 本人认为是错的,将*p = tmp不合适,因为在后面的代码中tmp已经被唤醒
     * 设置为*p = NULL也不合适,因为当使用wake_up后设置*p为NULL,这个时候别的进程刚好掉用sleep_on函数
     * 这样也会导致丢失,
     * 最好就是不管它就像sleep_on函数那样处理
     */
    //*p = tmp;
    if (tmp)
        tmp->state = TASK_RUNNING;
}

void wake_up(struct task_struct **p)
{
    if (p && *p) {
        (*p)->state = TASK_RUNNING;
        /*
         * 原来的代码有*p = NULL,linux内核完全注释说是要删除掉
         * 但是本人不认为要删掉
         * 但是觉得应该保留
         * 因为*p存放的是等待的第一个进程,第二个等待进程是存放在第一个堆栈中的
         * 当第二个进程唤醒时,就会通过堆栈获取原来*p,并将其唤醒
         * 以此类推唤醒所有进程
         * 如果注释掉,可能导致多次唤醒,没有意义
         */
        *p = NULL;
    }
}

代码如上修改,进行测试,运行不出错

标签:tmp,task,struct,up,current,state,wake,Linux0.11,sleep
From: https://www.cnblogs.com/sudochen/p/16647372.html

相关文章