首页 > 代码库 > Linux-0.11内核源码分析系列:进程调度

Linux-0.11内核源码分析系列:进程调度

/*     
 *Author  : DavidLin     
 *Date    : 2014-12-10pm     
 *Email   : linpeng1577@163.com or linpeng1577@gmail.com     
 *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.代码段可以相同,在不同内存执行。


Linux-0.11内核源码分析系列:进程调度