Linux-0.11核心源碼分析系列:進程調度sleep_on()函數分析,linux-0.11sleep_on
</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.程式碼片段可以相同,在不同記憶體執行。