cpu_idle()的调用位置:
1. init/main.c
start_kernel-->rest_init
2. arch/arm/kernel/smp.c
secondary_start_kernel()
{
...
cpu_idle();
}
arch/arm/kernel/process.c
/*
* The idle thread, has rather strange semantics for calling pm_idle,
* but this is what x86 does and we need to do the same, so that
* things like cpuidle get called in the same way. The only difference
* is that we always respect 'hlt_counter' to prevent low power idle. */
void
cpu_idle(void)
{
local_fiq_enable();
/* endless idle loop with no priority at all */
while (1) {
idle_notifier_call_chain(IDLE_START);
tick_nohz_idle_enter();
rcu_idle_enter();
while (!need_resched()) {
#ifdef CONFIG_HOTPLUG_CPU
if (cpu_is_offline(smp_processor_id()))
cpu_die();
#endif
/*
* We need to disable interrupts here
* to ensure we don't miss a wakeup call.
*/
local_irq_disable();
#ifdef CONFIG_PL310_ERRATA_769419
wmb();
#endif
if (hlt_counter) {
local_irq_enable();
cpu_relax();
} else if (!need_resched()) {
stop_critical_timings();
if (cpuidle_idle_call())
pm_idle();
start_critical_timings();
/*
* pm_idle functions must always
* return with IRQs enabled.
*/
WARN_ON(irqs_disabled());
} else
local_irq_enable();
}
rcu_idle_exit();
tick_nohz_idle_exit();
idle_notifier_call_chain(IDLE_END);
schedule_preempt_disabled();
}
}
阅读(1045) | 评论(0) | 转发(0) |