diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 2beb586d50..6293d98de7 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -2351,7 +2351,7 @@ void nxsched_alarm_tick_expiration(clock_t ticks); * ****************************************************************************/ -#if defined(CONFIG_SCHED_CPULOAD) && defined(CONFIG_SCHED_CPULOAD_EXTCLK) +#ifdef CONFIG_SCHED_CPULOAD_EXTCLK void nxsched_process_cpuload_ticks(uint32_t ticks); # define nxsched_process_cpuload() nxsched_process_cpuload_ticks(1) #endif diff --git a/sched/Kconfig b/sched/Kconfig index 41d3fc5b62..f309a11673 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -880,7 +880,6 @@ config SCHED_CRITMONITOR_MAXTIME_PANIC config SCHED_CPULOAD bool "Enable CPU load monitoring" default n - select SCHED_CPULOAD_EXTCLK if SCHED_TICKLESS ---help--- If this option is selected, the timer interrupt handler will monitor if the system is IDLE or busy at the time of that the timer interrupt @@ -898,14 +897,32 @@ config SCHED_CPULOAD if SCHED_CPULOAD -config SCHED_CPULOAD_EXTCLK - bool "Use external clock" - default n +choice + prompt "Select CPU load clock source" + default SCHED_CPULOAD_EXTCLK if SCHED_TICKLESS + +config SCHED_CPULOAD_SYSCLK + bool "Use system clock" ---help--- + If this option is enabled, the system clock is used for cpu load + measurement by default. + + There is a serious issue for the accuracy of measurements if the + system clock is used, however. NuttX threads are often started at + the time of the system timer expiration. Others may be stopped at + the time of the system timer expiration (if round-robin time-slicing + is enabled). Such thread behavior occurs synchronously with the + system timer and, hence, is not randomly sampled. As a consequence, + the CPU load attributed to these threads that run synchronously with + they system timer may be grossly in error. The CPU load measurements are determined by sampling the active tasks periodically at the occurrence to a timer expiration. By default, the system clock is used to do that sampling. +config SCHED_CPULOAD_EXTCLK + bool "Use external clock" + depends on SCHED_TICKLESS + ---help--- There is a serious issue for the accuracy of measurements if the system clock is used, however. NuttX threads are often started at the time of the system timer expiration. Others may be stopped at @@ -924,6 +941,8 @@ config SCHED_CPULOAD_EXTCLK nxsched_process_cpuload_ticks() at each timer expiration with interrupts disabled. +endchoice + if SCHED_CPULOAD_EXTCLK config SCHED_CPULOAD_TICKSPERSEC diff --git a/sched/sched/sched.h b/sched/sched/sched.h index 699a2fc61d..36525fef18 100644 --- a/sched/sched/sched.h +++ b/sched/sched/sched.h @@ -395,17 +395,11 @@ int nxsched_pause_cpu(FAR struct tcb_s *tcb); # define nxsched_islocked_tcb(tcb) ((tcb)->lockcount > 0) #endif -#ifndef CONFIG_SCHED_CPULOAD_EXTCLK - /* CPU load measurement support */ -# ifdef CONFIG_SCHED_CPULOAD +#ifdef CONFIG_SCHED_CPULOAD_SYSCLK void nxsched_process_cpuload_ticks(uint32_t ticks); -# else -# define nxsched_process_cpuload_ticks(ticks) -# endif - -# define nxsched_process_cpuload() nxsched_process_cpuload_ticks(1) +#define nxsched_process_cpuload() nxsched_process_cpuload_ticks(1) #endif /* Critical section monitor */ diff --git a/sched/sched/sched_processtimer.c b/sched/sched/sched_processtimer.c index 3979b1f62c..c4c48ae774 100644 --- a/sched/sched/sched_processtimer.c +++ b/sched/sched/sched_processtimer.c @@ -220,7 +220,7 @@ void nxsched_process_timer(void) clock_timer(); -#ifndef CONFIG_SCHED_CPULOAD_EXTCLK +#ifdef CONFIG_SCHED_CPULOAD_SYSCLK /* Perform CPU load measurements (before any timer-initiated context * switches can occur) */ diff --git a/sched/sched/sched_timerexpiration.c b/sched/sched/sched_timerexpiration.c index 96ea6b23ff..030ce38f00 100644 --- a/sched/sched/sched_timerexpiration.c +++ b/sched/sched/sched_timerexpiration.c @@ -421,7 +421,7 @@ static unsigned int nxsched_timer_process(unsigned int ticks, clock_update_wall_time(); #endif -#ifndef CONFIG_SCHED_CPULOAD_EXTCLK +#ifdef CONFIG_SCHED_CPULOAD_SYSCLK /* Perform CPU load measurements (before any timer-initiated context * switches can occur) */