Linux时间管理(7)

在freerun_clocksource_init函数中向系统注册新的时钟源,但没有切换时钟源。

freerun_clocksource_init

       clocksource_mmio_init

              clocksource_register_hz

                     __clocksource_register_scale

                            clocksource_select  // finished_booting没有被设置为1,在这里是直接返回

clocksource_done_booting函数中将finished_booting1,接着调用clocksource_select切换系统的时钟源。

clocksource_done_booting

       clocksource_select

              timekeeping_notify(curr_clocksource);

stop_machine(change_clocksource, clock, NULL);

                            __stop_machine(fn, data, cpus);   

当调用clocksource_done_booting时,系统会通过clocksource_select选择系统中最好的时钟源作为系统的时钟源。下面分析一下clocksource_select的代码:

static void clocksource_select(void)

{

       struct clocksource *best, *cs;

 

       if (!finished_booting || list_empty(&clocksource_list))

              return;

       /* First clocksource on the list has the best rating. */

       best = list_first_entry(&clocksource_list, struct clocksource, list);

       /* Check for the override clocksource. */

       list_for_each_entry(cs, &clocksource_list, list) {

              if (strcmp(cs->name, override_name) != 0)

                     continue;

              /*

               * Check to make sure we don't switch to a non-highres

               * capable clocksource if the tick code is in oneshot

               * mode (highres or nohz)

               */

              if (!(cs->flags & CLOCK_SOURCE_VALID_FOR_HRES) &&

                  tick_oneshot_mode_active()) {

                     /* Override clocksource cannot be used. */

                     printk(KERN_WARNING "Override clocksource %s is not "

                            "HRT compatible. Cannot switch while in "

                            "HRT/NOHZ mode\n", cs->name);

                     override_name[0] = 0;

              } else

                     /* Override clocksource can be used. */

                     best = cs;

              break;

       }

       if (curr_clocksource != best) {

              printk(KERN_INFO "Switching to clocksource %s\n", best->name);

              curr_clocksource = best;

              timekeeping_notify(curr_clocksource);

       }

}

 

/*

 * clocksource_done_booting - Called near the end of core bootup

 *

 * Hack to avoid lots of clocksource churn at boot time.

 * We use fs_initcall because we want this to start before

 * device_initcall but after subsys_initcall.

 */

static int __init clocksource_done_booting(void)

{

       mutex_lock(&clocksource_mutex);

       curr_clocksource = clocksource_default_clock();

       mutex_unlock(&clocksource_mutex);

 

       finished_booting = 1;

 

       /*

        * Run the watchdog first to eliminate unstable clock sources

        */

       clocksource_watchdog_kthread(NULL);

 

       mutex_lock(&clocksource_mutex);

       clocksource_select();

       mutex_unlock(&clocksource_mutex);

       return 0;

}

fs_initcall(clocksource_done_booting);

__stop_machine实际上调用change_clocksource完成了对时钟源的切换,具体的代码如下:

static inline int __stop_machine(int (*fn)(void *), void *data,

                             const struct cpumask *cpus)

{

       int ret;

       local_irq_disable();

       //调用的函数是实际是change_clocksource(clock);

       ret = fn(data);

       local_irq_enable();

       return ret;

}

从而切换到我们注册的时钟上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值