Skip to content

Commit

Permalink
sched: fix the inaccurate cpuload statistics issue
Browse files Browse the repository at this point in the history
Non-fixed clock source will lead to inaccurate cpuload statistics

before:
5     5 253 RR       Task      - Waiting  Signal    0000000000000000 0002000 0000624  31.2%   2.5% cpuload -p 50
6     6 253 RR       Task      - Waiting  Signal    0000000000000000 0002000 0000624  31.2%   0.7% cpuload -p 10
7     7 253 RR       Task      - Waiting  Signal    0000000000000000 0002000 0000624  31.2%   2.2% cpuload -p 20
after:
5     5 253 RR       Task      - Waiting  Signal    0000000000000000 0002000 0000624  31.2%  50.8% cpuload -p 50
6     6 253 RR       Task      - Waiting  Signal    0000000000000000 0002000 0000624  31.2%  10.8% cpuload -p 10
7     7 253 RR       Task      - Waiting  Signal    0000000000000000 0002000 0000624  31.2%  20.0% cpuload -p 20
Signed-off-by: yinshengkai <[email protected]>
  • Loading branch information
Gary-Hobson authored and xiaoxiang781216 committed Oct 11, 2024
1 parent f88afa5 commit 4685175
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 24 deletions.
14 changes: 6 additions & 8 deletions sched/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,6 @@ config SCHED_CPULOAD_NONE

config SCHED_CPULOAD_SYSCLK
bool "Use system clock"
depends on !SCHED_TICKLESS
---help---
If this option is enabled, the system clock is used for cpu load
measurement by default.
Expand Down Expand Up @@ -1077,19 +1076,18 @@ config SCHED_CPULOAD_CRITMONITOR

endchoice

if SCHED_CPULOAD_EXTCLK

config SCHED_CPULOAD_TICKSPERSEC
int "External clock rate"
int "CPU load sampling clock frequency(HZ)"
default 100
---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 interrupts in units of ticks per
second. The default value of 100 corresponds to a 100Hz clock. NOTE:
CPU load sampling clock frequency, in HZ. Use sysclk clock source,
use wdt, EXTCLK clock source, use an external timer.
The default value of 100 corresponds to a 100Hz clock. NOTE:
that 100Hz is the default frequency of the system time and, hence,
the worst possible choice in most cases.

if SCHED_CPULOAD_EXTCLK

choice
prompt "Select CPU load timer"
default CPULOAD_ONESHOT
Expand Down
4 changes: 4 additions & 0 deletions sched/clock/clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,8 @@ void clock_timer(void);

void perf_init(void);

#ifdef CONFIG_SCHED_CPULOAD_SYSCLK
void cpuload_init(void);
#endif

#endif /* __SCHED_CLOCK_CLOCK_H */
4 changes: 4 additions & 0 deletions sched/clock/clock_initialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@ void clock_initialize(void)

perf_init();

#ifdef CONFIG_SCHED_CPULOAD_SYSCLK
cpuload_init();
#endif

sched_trace_end();
}

Expand Down
57 changes: 57 additions & 0 deletions sched/sched/sched_cpuload.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include <nuttx/clock.h>
#include <nuttx/irq.h>
#include <nuttx/wdog.h>

#include "sched/sched.h"

Expand Down Expand Up @@ -61,6 +62,11 @@
CONFIG_SCHED_CPULOAD_TIMECONSTANT * \
CPULOAD_TICKSPERSEC)

/* The sampling period in system timer ticks */

#define CPULOAD_SAMPLING_PERIOD \
(TICK_PER_SEC / CONFIG_SCHED_CPULOAD_TICKSPERSEC)

/****************************************************************************
* Public Data
****************************************************************************/
Expand All @@ -80,6 +86,34 @@

volatile clock_t g_cpuload_total;

/****************************************************************************
* Private Functions
****************************************************************************/

/****************************************************************************
* Name: cpuload_callback
*
* Description:
* This is the callback function that will be invoked when the watchdog
* timer expires.
*
* Input Parameters:
* argc - the argument passed with the timer when the timer was started.
*
* Returned Value:
* None
*
****************************************************************************/

#ifdef CONFIG_SCHED_CPULOAD_SYSCLK
static void cpuload_callback(wdparm_t arg)
{
FAR struct wdog_s *wdog = (FAR struct wdog_s *)arg;
nxsched_process_cpuload_ticks(CPULOAD_SAMPLING_PERIOD);
wd_start(wdog, CPULOAD_SAMPLING_PERIOD, cpuload_callback, arg);
}
#endif

/****************************************************************************
* Public Functions
****************************************************************************/
Expand Down Expand Up @@ -221,3 +255,26 @@ int clock_cpuload(int pid, FAR struct cpuload_s *cpuload)
leave_critical_section(flags);
return ret;
}

/****************************************************************************
* Name: cpuload_init
*
* Description:
* Initialize the CPU load measurement logic.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/

#ifdef CONFIG_SCHED_CPULOAD_SYSCLK
void cpuload_init(void)
{
static struct wdog_s g_cpuload_wdog;
wd_start(&g_cpuload_wdog, CPULOAD_SAMPLING_PERIOD, cpuload_callback,
(wdparm_t)&g_cpuload_wdog);
}
#endif
8 changes: 0 additions & 8 deletions sched/sched/sched_processtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,6 @@ void nxsched_process_timer(void)

clock_timer();

#ifdef CONFIG_SCHED_CPULOAD_SYSCLK
/* Perform CPU load measurements (before any timer-initiated context
* switches can occur)
*/

nxsched_process_cpuload();
#endif

/* Check if the currently executing task has exceeded its
* timeslice.
*/
Expand Down
8 changes: 0 additions & 8 deletions sched/sched/sched_timerexpiration.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,14 +339,6 @@ static clock_t nxsched_timer_process(clock_t ticks, clock_t elapsed,
clock_update_wall_time();
#endif

#ifdef CONFIG_SCHED_CPULOAD_SYSCLK
/* Perform CPU load measurements (before any timer-initiated context
* switches can occur)
*/

nxsched_process_cpuload_ticks(elapsed);
#endif

/* Check for operations specific to scheduling policy of the currently
* active task.
*/
Expand Down

0 comments on commit 4685175

Please sign in to comment.