Linux-0.11内核源码分析系列:进程调度sleep_on()函数分析

</pre><pre name="code" class="cpp">/*     
 *Author  : DavidLin     
 *Date    : 2014-12-10pm     
 *Email   : [email protected] or [email protected]     
 *world   : the city of SZ, in China     
 *Ver     : 000.000.001     
 *history :     editor      time            do     
 *          1)LinPeng       2014-12-10      created this file!     
 *          2)     
 */  

/* author : linus */
void sleep_on(struct task_struct **p)
{
    struct task_struct *tmp;
    
    if(!p)
        return;
    if(current == &(init_task.task))    //init进程不可睡眠
        panic("task[0] trying to sleep");
    tmp = *p;   //tmp指向上一个当前进程
    *p  = current;    //链表头执行当前进程
    current->state = TASK_UNINTERRUPTIBLE;    //睡眠进程不可中断
    schedule();    //进程调度,以下代码进程被唤醒之后才会继续执行
    if(tmp)  //如果链表next不为空
        tmp->state = 0;  //唤醒next进程
}

        sleep_on函数可以在sched.c文件中找到,这是一个小函数,不过,

它暗含了如下几个知识点,所以理解起来比schedule()函数更加困难:

1.用户栈与内核栈的区别;

2.内核栈保存在哪里,与用户栈共享?

3.几个进程同时为同一个资源而sleep_on,具体流程?

4.sleep之后如何唤醒?

5.不同进程使用相同的sleep代码,而不同的数据,这个概念的理解。


答:以下基于0.12内核,2.6内核会有所不同,不过基本概念一致

1.用户栈保存在进程数据段,内核栈保存在进程pcb所在的物理页;

fork.c中
p->tss.esp0 = PAGE_SIZE + (long)p;    //2.6内核保存在thread_info所在物理页
p->tss.ss0   = 0x10;    //进程内核栈保存在内核数据段
2.不共享,原因如上;

3.tmp相当于单链表next指针, 把等待同一个资源的进程链接在一起,头指针永远指向最新插入的进程;

4.唤醒之后从schedule()函数之后执行,通过内核唤醒;

6.代码段可以相同,在不同内存执行。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。