linux-011中休眠函数以及唤醒函数的分析(sleep_on,wake_up)

来源:互联网 发布:python range函数 编辑:程序博客网 时间:2024/05/16 14:36

先看一下代码:

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=0;}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=0;goto repeat;}*p=NULL;if (tmp)tmp->state=0;}void wake_up(struct task_struct **p){if (p && *p) {(**p).state=0;*p=NULL;}}
先看函数,函数实现很简单。原理有一些抽象,这里先说一下sleep_on函数的应用。
sleep_on函数中只要涉及了:*p,*tmp,current三个人物指针操作。
其中*p表示等待队列头指针,如文件系统i节点的i_wait指针,内存缓冲区操作中的buffer_wait指针;*tmp是临时指针,current代表当前任务指针。
sleep_on函数操作后就形成了一个队列:

tmp指向前一个任务,p指向当前等待队列头,而且每个任务的状态为可中断状态。

注意了,接下来就是我觉得抽象的地方了:
执行wake_up(buffer_wait)时,是怎么唤醒任务的呢?
看函数:
wake_up的操作:

if (p && *p) {(**p).state=0;}
把任务状态设置为就绪,之后schedule()函数就会返回到sleep_on函数的最后部分,执行操作如下:
    if (tmp)        tmp->state=0;
因为tmp为前一个任务的指针,而且,每次sleep任务时,都创建了tmp指针,所以只要tmp指针不为空,就会把tmp指针指向的任务状态置为就绪。这样就实现了任务的唤醒,从代码看来每次唤醒都是把一个队列中的所有任务唤醒。

interruptible_sleep_on函数类似:
repeat:current->state = TASK_INTERRUPTIBLE;schedule();if (*p && *p != current) {(**p).state=0;goto repeat;}*p=tmp;if (tmp)tmp->state=0;



当任务唤醒时,*p指针中有等待任务并且不是当前任务,表示当当前任务放入队列后又有其他任务放入队列中,之后就把当前任务置为就绪,并重新调度。当是当前任务时,也把其他就绪任务也唤醒,同sleep_on函数。

以上就是自己看a代码整理出来了,有任何不对地方,还请留言指正。