Chinaunix首页 | 论坛 | 博客
  • 博客访问: 90476
  • 博文数量: 16
  • 博客积分: 1113
  • 博客等级: 少尉
  • 技术积分: 170
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-31 13:36
文章分类

全部博文(16)

文章存档

2011年(4)

2010年(12)

分类: LINUX

2010-08-21 15:43:50

现在进程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();

}

 

好,下面进入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并不参与调度!

       

static inline int need_resched(void)

{

        return unlikely(test_thread_flag(TIF_NEED_RESCHED));

}

 

static inline int test_thread_flag(int flag)

{

        return test_bit(flag,¤t_thread_info()->flags);

}

检测当前进程描述符中thread_info字段指向的thread_info结构中flags字段是否设置

TIF_NEED_RESCHED标志

 

            void (*idle)(void);

            定义一个函数指针

 

            if (__get_cpu_var(cpu_idle_state))

                __get_cpu_var(cpu_idle_state) = 0;

 

static DEFINE_PER_CPU(unsigned int, cpu_idle_state)

 

#define DEFINE_PER_CPU(type, name) \

    __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name

 

声明了一个每处理器变量per_cpu_cpu_idle_state ,类型为unsigned int!负责记录每个cpuidle进程的状态信息!

 

            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_statidle_timestamp字段值为系统时钟中断次数!此字段好像表示进程执行idle()函数也就是default_idle()函数的时间?(不确定)

 

            idle();

            若当前进程一直没设置TIF_NEED_RESCHED 标志,则就一直循环调用idle()函数,直到设置了为止!

        }

        schedule();

        进行进程调度,此时目的调度进程1的执行!

    }

}

 

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指令时,CSIP指向HLT之后要执行的一条指令的地址,而CPU则处于“空操作”的暂停状态。此时,如果发生外部硬件中断,在CPU响应中断执行中断服务程序后,将返回到HLT后面的一条指令。所以,简要地说,HLT指令的执行实际上是用软件方法使CPU处于暂停状态等待硬件中断,而硬件中断的发生又使CPU退出暂停状态。

 

除了外部硬件中断会使CPU退出暂停状态外,对系统进行复位操作,也会使CPU退出暂停状态。

#define safe_halt()             __asm__ __volatile__("sti; hlt": : :"memory")

 

                else

                        local_irq_enable();

                        若此时终于设置了此标志则开中断,返回执行调度程序!

        } else {

                cpu_relax();

                执行一些空操作

 

#define cpu_relax()     rep_nop()

 

static inline void rep_nop(void)

{

        __asm__ __volatile__("rep;nop": : :"memory");

}

        }

}

 

 

接下来我们就应该分析schedule() 函数了,个人认为此函数非常难懂,我们下回分析吧!

阅读(1938) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-08-23 14:58:21

Download More than 1000 free IT eBooks: http://free-ebooks.appspot.com