📄 idle.c
字号:
/* * idle.c * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */#include <linux/config.h>#include <linux/errno.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/smp.h>#include <linux/smp_lock.h>#include <linux/stddef.h>#include <linux/unistd.h>#include <linux/ptrace.h>#include <linux/slab.h>#include <asm/pgtable.h>#include <asm/uaccess.h>#include <asm/system.h>#include <asm/io.h>#include <asm/processor.h>#include <asm/mmu.h>#include <asm/cache.h>#include <asm/time.h>#ifdef CONFIG_PPC_ISERIES#include <asm/iSeries/LparData.h>#include <asm/iSeries/HvCall.h>#include <asm/iSeries/ItLpQueue.h>unsigned long maxYieldTime = 0;unsigned long minYieldTime = 0xffffffffffffffffUL;static void yield_shared_processor(void){ unsigned long tb; unsigned long yieldTime; HvCall_setEnabledInterrupts(HvCall_MaskIPI | HvCall_MaskLpEvent | HvCall_MaskLpProd | HvCall_MaskTimeout); tb = get_tb(); /* Compute future tb value when yield should expire */ HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy); yieldTime = get_tb() - tb; if (yieldTime > maxYieldTime) maxYieldTime = yieldTime; if (yieldTime < minYieldTime) minYieldTime = yieldTime; /* * The decrementer stops during the yield. Force a fake decrementer * here and let the timer_interrupt code sort out the actual time. */ get_paca()->xLpPaca.xIntDword.xFields.xDecrInt = 1; process_iSeries_events();}int cpu_idle(void){ struct Paca *paca; long oldval; unsigned long CTRL; /* ensure iSeries run light will be out when idle */ current->thread.flags &= ~PPC_FLAG_RUN_LIGHT; CTRL = mfspr(CTRLF); CTRL &= ~RUNLATCH; mtspr(CTRLT, CTRL); paca = get_paca(); while (1) { if (paca->xLpPaca.xSharedProc) { if (ItLpQueue_isLpIntPending(paca->lpQueuePtr)) process_iSeries_events(); if (!need_resched()) yield_shared_processor(); } else { oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); if (!oldval) { set_thread_flag(TIF_POLLING_NRFLAG); while (!need_resched()) { HMT_medium(); if (ItLpQueue_isLpIntPending(paca->lpQueuePtr)) process_iSeries_events(); HMT_low(); } HMT_medium(); clear_thread_flag(TIF_POLLING_NRFLAG); } else { set_need_resched(); } } if (need_resched()) schedule(); } return 0;}#else /* CONFIG_PPC_ISERIES */int cpu_idle(void){ long oldval; while (1) { oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); if (!oldval) { set_thread_flag(TIF_POLLING_NRFLAG); while (!need_resched()) { barrier(); HMT_low(); } HMT_medium(); clear_thread_flag(TIF_POLLING_NRFLAG); } else { set_need_resched(); } schedule(); } return 0;}#endif /* CONFIG_PPC_ISERIES */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -