diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-02-27 14:13:53 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-02-27 14:13:53 -0600 |
commit | 4253771d12771c6beb157d4ebc530931d489eae8 (patch) | |
tree | d1ef697901e4090b9e80084c59f804faa549e53c | |
parent | b663158cea2f68ed101f569a7fe08ddf7a7dfa32 (diff) | |
download | nuttx-4253771d12771c6beb157d4ebc530931d489eae8.tar.gz nuttx-4253771d12771c6beb157d4ebc530931d489eae8.tar.bz2 nuttx-4253771d12771c6beb157d4ebc530931d489eae8.zip |
Support an asynchronous, 'external' clock to get better CPU load measurements
-rw-r--r-- | nuttx/ChangeLog | 4 | ||||
-rw-r--r-- | nuttx/sched/Kconfig | 41 | ||||
-rw-r--r-- | nuttx/sched/sched_cpuload.c | 16 | ||||
-rw-r--r-- | nuttx/sched/sched_processtimer.c | 4 |
4 files changed, 60 insertions, 5 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 400173b4e..d71a05a1e 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -6680,3 +6680,7 @@ * fs/procfs/fs_procfscpuload.c and fs_procfsproc.c: Remove the newline at the end of the percentage so that the returned strings can be printed on the same line as other values (2014-2-27). + * sched/Kconfig, sched_cpuload.c, and nuttx/sched/sched_processtimer.c: + An asynchronous, "external" clock may now be used to drive the CPU + load calculations for more accurate load measurements when needed + (2014-2-27). diff --git a/nuttx/sched/Kconfig b/nuttx/sched/Kconfig index a6b661e05..cd6b200e7 100644 --- a/nuttx/sched/Kconfig +++ b/nuttx/sched/Kconfig @@ -75,12 +75,51 @@ config SCHED_CPULOAD if SCHED_CPULOAD +config SCHED_CPULOAD_EXTCLK + bool "Use external clock" + default n + ---help--- + 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. + + 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 solution is to use some other clock that runs at a different + rate and has timer expirations that are asynchronous with the + system timer. Then truly accurate load measurements can be + achieved. This option enables use of such an "external" clock. The + implementation of the clock must be provided by platform-specific + logic; that platform-specific logic must call the system function + sched_process_cpuload() at each timer expiration with interrupts + disabled. + +config SCHED_CPULOAD_TICKSPERSEC + int "External clock rate" + default 100 + depends on SCHED_CPULOAD_EXTCLK + ---help--- + If an external clock is used to drive the sampling for the CPU load + calculations, then this value must be provided. This value provides + the rate of the external clock in units of ticks per second. The + default value of 100 corresponds to 100Hz clock. NOTE: that 100Hz + is the default frequency of the system time and, hence, the worst + possible choice in most cases. + config SCHED_CPULOAD_TIMECONSTANT int "CPU load time constant" default 2 ---help--- The accumulated CPU count is divided by two when the accumulated - tick count exceeds this time constant. + tick count exceeds this time constant. This time constant is in + units of seconds. endif # SCHED_CPULOAD diff --git a/nuttx/sched/sched_cpuload.c b/nuttx/sched/sched_cpuload.c index 0f5495750..95a8b59e2 100644 --- a/nuttx/sched/sched_cpuload.c +++ b/nuttx/sched/sched_cpuload.c @@ -52,7 +52,19 @@ /************************************************************************ * Pre-processor Definitions ************************************************************************/ - +/* Are we using the system timer, or an external clock? Get the rate + * of the sampling in ticks per second for the selected timer. + */ + +#ifdef CONFIG_SCHED_CPULOAD_EXTCLK +# ifndef CONFIG_SCHED_CPULOAD_TICKSPERSEC +# error CONFIG_SCHED_CPULOAD_TICKSPERSEC is not defined +# endif +# define CPULOAD_TICKSPERSEC CONFIG_SCHED_CPULOAD_TICKSPERSEC +#else +# define CPULOAD_TICKSPERSEC CLOCKS_PER_SEC +#endif + /************************************************************************ * Private Type Declarations ************************************************************************/ @@ -119,7 +131,7 @@ void weak_function sched_process_cpuload(void) * constant, then shift the accumulators. */ - if (++g_cpuload_total > (CONFIG_SCHED_CPULOAD_TIMECONSTANT * CLOCKS_PER_SEC)) + if (++g_cpuload_total > (CONFIG_SCHED_CPULOAD_TIMECONSTANT * CPULOAD_TICKSPERSEC)) { uint32_t total = 0; diff --git a/nuttx/sched/sched_processtimer.c b/nuttx/sched/sched_processtimer.c index d65112948..6ca5981fb 100644 --- a/nuttx/sched/sched_processtimer.c +++ b/nuttx/sched/sched_processtimer.c @@ -182,9 +182,9 @@ static inline void sched_process_timeslice(void) void sched_process_timer(void) { +#ifndef CONFIG_DISABLE_CLOCK /* Increment the system time (if in the link) */ -#ifndef CONFIG_DISABLE_CLOCK #ifdef CONFIG_HAVE_WEAKFUNCTIONS if (clock_timer != NULL) #endif @@ -193,11 +193,11 @@ void sched_process_timer(void) } #endif +#if defined(CONFIG_SCHED_CPULOAD) && !defined(CONFIG_SCHED_CPULOAD_EXTCLK) /* Perform CPU load measurements (before any timer-initiated context switches * can occur) */ -#ifdef CONFIG_SCHED_CPULOAD #ifdef CONFIG_HAVE_WEAKFUNCTIONS if (sched_process_cpuload != NULL) #endif |