- 论坛徽章:
- 0
|
>>>
关于schedule和cpu_idle的一些问题:
1. schedule会从一系列进程中选择最合适的进程来运行,假设某一时刻没有合适的进程(在寻找待切换入进程时next时,先将next设置为 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函数,在此函数中, init_task.need_resched被设置为-1),此时CPU halt了,直到中断的到来,CPU才会停止halt;
2. 如果此时来了个中断,则中断处理完毕后返回前,发现current(也就是init_task)的need_resched为-1(!=0),又会主动调用 schedule,在schedule中,首先将current(也就是init_task)的need_resched清零,然后选择合适的进程来运行,如果找不到合适的,则schedule直接就返回了,此时也就是从中断处理中返回,这样又回到了cpu_idle->idle-> halt被中断时的点,再次进行1->2这样的循环;如果schedule找到了另一个合适的进程,则就切换到该进程去运行了, init_task则被挂起在idle->halt被中断时点的那个位置;
>>>
lz说的似乎有点复杂了,
任何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出来,当前进程还是boot进程(即init_task,0号进程),之后,boot进程 设置need->resched =1,然后初始化idle,进入循环,
void cpu_idle (void)
{
while (1) {
........
while (!current->need_resched)
idle();
schedule();
check_pgt_cache();
}
}
由于current->need_resched==0,第一次,就会调度,这是就会选择 fork出的init了,而init的起始执行点就是ret_from_fork,然后回到用户空间,
而init()里面就是 open console..execve "/sbin/init"....... |
|