--- zzzz-none-000/linux-2.6.19.2/arch/arm/kernel/process.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/arch/arm/kernel/process.c 2007-06-28 13:54:53.000000000 +0000 @@ -131,6 +131,76 @@ } } +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +#if defined(CONFIG_CHECK_IDLE) +#include + +static struct _check_idle_action { + signed start_idle; + signed end_idle; + unsigned long run_time; + unsigned long idle_time; + signed last_report; + signed schwelle; + signed shift; + atomic_t idle; /* >0 if we are in idle */ + void (*report_function)(unsigned long, unsigned long); + signed int (*timer_function)(void); +} idle_action; + +void begin_check_idle(void) { + signed int time; + if(idle_action.report_function == NULL) + return; + idle_action.start_idle = (*idle_action.timer_function)(); + time = idle_action.start_idle - idle_action.end_idle; + idle_action.run_time += time > 0 ? time : -time; + atomic_set(&idle_action.idle, 1); +} + +void end_check_idle(void) { + signed int time; + if(atomic_read(&idle_action.idle) == 0) { + return; + } + if(idle_action.report_function == NULL) + return; + idle_action.end_idle = (*idle_action.timer_function)(); + time = idle_action.end_idle - idle_action.start_idle; + idle_action.idle_time += time > 0 ? time : -time; + + if(((signed)jiffies - idle_action.last_report) > idle_action.schwelle) { + idle_action.last_report = jiffies; + if(idle_action.report_function) + (*idle_action.report_function)(idle_action.idle_time, idle_action.run_time); + if(idle_action.shift == 0) { + idle_action.idle_time = 0; + idle_action.run_time = 0; + } else { + idle_action.idle_time >>= idle_action.shift; + idle_action.run_time >>= idle_action.shift; + } + } + atomic_set(&idle_action.idle, 0); +} + +void init_check_idle(int shift, int schwelle, void (*report_function)(unsigned long, unsigned long), signed int (*timer_function)(void)) { + if(report_function && timer_function) { + idle_action.shift = shift; + idle_action.schwelle = schwelle; + idle_action.idle_time = 0; + idle_action.run_time = 0; + idle_action.timer_function = timer_function; + idle_action.report_function = report_function; + idle_action.end_idle = (*idle_action.timer_function)(); + idle_action.last_report = jiffies; + return; + } + idle_action.report_function = NULL; +} +#endif /*--- #if CONFIG_CHECK_IDLE ---*/ + /* * The idle thread. We try to conserve power, while trying to keep * overall latency low. The architecture specific idle is passed @@ -154,8 +224,12 @@ if (!idle) idle = default_idle; leds_event(led_idle_start); - while (!need_resched()) + while (!need_resched()) { +#if defined(CONFIG_CHECK_IDLE) + begin_check_idle(); +#endif /*--- #if CONFIG_CHECK_IDLE ---*/ idle(); + } leds_event(led_idle_end); preempt_enable_no_resched(); schedule();