- 論壇徽章:
- 0
|
>>>
關(guān)于schedule和cpu_idle的一些問題:
1. schedule會從一系列進程中選擇最合適的進程來運行,假設(shè)某一時刻沒有合適的進程(在尋找待切換入進程時next時,先將next設(shè)置為 init_task,然后在runqueue_head運行隊列中找合適的進程,找到,就將其賦給next,注意,init_task不會在 runqueue_head隊列中,沒找到,則就是init_task了),則只能選擇 init_task,這樣便回到了init_task在cpu_idle->schedule()中被換出時的點,由于此時 init_task.need_resched==0,故進入idle(一般為poll_idle函數(shù),在此函數(shù)中, init_task.need_resched被設(shè)置為-1),此時CPU halt了,直到中斷的到來,CPU才會停止halt;
2. 如果此時來了個中斷,則中斷處理完畢后返回前,發(fā)現(xiàn)current(也就是init_task)的need_resched為-1(!=0),又會主動調(diào)用 schedule,在schedule中,首先將current(也就是init_task)的need_resched清零,然后選擇合適的進程來運行,如果找不到合適的,則schedule直接就返回了,此時也就是從中斷處理中返回,這樣又回到了cpu_idle->idle-> halt被中斷時的點,再次進行1->2這樣的循環(huán);如果schedule找到了另一個合適的進程,則就切換到該進程去運行了, init_task則被掛起在idle->halt被中斷時點的那個位置;
>>>
lz說的似乎有點復(fù)雜了,
任何arch啟動第一個cpu都是start_kernel(),然后
start_kernel()
{
.......
rest_init()
}
static void rest_init(void)
{
kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
unlock_kernel();
current->need_resched = 1;
cpu_idle();
}
在kernel_thread()之后, init 進程才被fork出來,當(dāng)前進程還是boot進程(即init_task,0號進程),之后,boot進程 設(shè)置need->resched =1,然后初始化idle,進入循環(huán),
void cpu_idle (void)
{
while (1) {
........
while (!current->need_resched)
idle();
schedule();
check_pgt_cache();
}
}
由于current->need_resched==0,第一次,就會調(diào)度,這是就會選擇 fork出的init了,而init的起始執(zhí)行點就是ret_from_fork,然后回到用戶空間,
而init()里面就是 open console..execve "/sbin/init"....... |
|