现在进程 1 已经创建完成!但还没有执行,此时运行的仍然是进程 0

回到rest_init()函数:

static void noinline rest_init(void)
    __releases(kernel_lock)
{
    kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
    此函数已执行完毕!

    numa_default_policy();
    空函数

    unlock_kernel();
    解锁大内核锁

    preempt_enable_no_resched();
    由于没有开启内核抢占,此函数为空!

    cpu_idle();
}</pre>
<p></p>


好,下面进入cpu_idle() 函数的分析,分析这个有去无回的函数!


    
    void cpu_idle (void)
    {
        /* endless idle loop with no priority at all */
        while (1) {
    
            while (!need_resched()) {
            首先检测当前进程,也就是进程0有没有设置 TIF_NEED_RESCHED 标志。表示当前进程需要立刻被调度!若设置则立刻调用下面的 schedule() 函数进行调度,否则进入循环!
    
            在此时进程0已经设置了 TIF_NEED_RESCHED 标志!还记得在哪设置的吗?没错就在 init_idle() 函数中:set_tsk_need_resched(idle) 此函数设置的!在 init_idle() 函数中还设置了进程0的优先级(最小)等等……
    
            注意进程0描述符不在 cpu 的运行队列中,所以进程0并不参与调度!
    
                void (*idle)(void);
                定义一个函数指针
     
                if (__get_cpu_var(cpu_idle_state))
                    __get_cpu_var(cpu_idle_state) = 0;
                声明了一个每处理器变量 per_cpu_cpu_idle_state ,类型为 unsigned int!负责记录每个 cpu 的 idle 进程的状态信息!
    
                rmb();
                内存屏障原语
    
                idle = pm_idle;
                idle应该为NULL
    
                if (!idle)
                    idle = default_idle;
                此时idle指向函数default_idle     
    
                __get_cpu_var(irq_stat).idle_timestamp = jiffies;
                更新每 cpu 变量 per_cpu_irq_stat 中 idle_timestamp 字段值为系统时钟中断次数!此字段好像表示进程执行idle() 函数也就是 default_idle() 函数的时间?(不确定)
    
                idle();
                若当前进程一直没设置TIF_NEED_RESCHED 标志,则就一直循环调用idle()函数,直到设置了为止!
    
            }
    
            schedule();
            进行进程调度,此时目的调度进程1的执行!
        }
    }</pre>
    <p></p>
    
    
        
        static inline int need_resched(void)
        {
                return unlikely(test_thread_flag(TIF_NEED_RESCHED));
        }</pre>
        <p></p>
        
        
            
            static inline int test_thread_flag(int flag)
            {
                    return test_bit(flag,&current_thread_info()->flags);
            }</pre>
            <p>  
            检测当前进程描述符中 thread_info 字段指向的 thread_info 结构中 flags 字段是否设置 TIF_NEED_RESCHED 标志</p>
            
            
                
                static DEFINE_PER_CPU(unsigned int, cpu_idle_state)
                
                #define DEFINE_PER_CPU(type, name) \
                    __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name </pre>
                <p></p>
                
                
                    
                    void default_idle(void)
                    {
                            if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
                    
                                    local_irq_disable();
                                    禁止中断!
                    
                                    if (!need_resched())
                                    再次判断当前进程是否设置需要调度标志
                    
                                            safe_halt();
                                            若还没设置此标志则执行开中断和 hlt 指令!
                                            对于hlt指令本人并不是很清楚,也从来没用过。Google一下:
                    
                                            当 CPU 执行 HLT 指令时,CS 和 IP 指向 HLT 之后要执行的一条指令的地址,而CPU则处于“空操作”的暂停状态。此时,如果发生外部硬件中断,在CPU响应中断执行中断服务程序后,将返回到 HLT 后面的一条指令。所以,简要地说,HLT 指令的执行实际上是用软件方法使CPU处于暂停状态等待硬件中断,而硬件中断的发生又使CPU退出暂停状态。
                    
                    除了外部硬件中断会使CPU退出暂停状态外,对系统进行复位操作,也会使CPU退出暂停状态。
                    
                                    else
                    
                                            local_irq_enable();
                                            若此时终于设置了此标志则开中断,返回执行调度程序!
                    
                            } else {
                    
                                    cpu_relax();
                                    执行一些空操作
                            }
                    }</pre>
                    <p></p>
                    
                    
                        
                        #define safe_halt()             __asm__ __volatile__("sti; hlt": : :"memory")\
                        
                        #define cpu_relax()     rep_nop()
                        
                        static inline void rep_nop(void)
                        {
                                __asm__ __volatile__("rep;nop": : :"memory");
                        }</pre>
                        <p></p>
                        
                        
                        接下来我们就应该分析schedule() 函数了,个人认为此函数非常难懂,我们下回分析吧!