</pre><pre name="code" class="cpp">/* *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内核源码分析系列:进程调度sleep_on()函数分析
原文地址:http://blog.csdn.net/linpeng12358/article/details/41855803