From e28b311b78420a821d6509b4edd91750b7af60e8 Mon Sep 17 00:00:00 2001 From: yinshengkai Date: Fri, 26 Jan 2024 15:50:18 +0800 Subject: [PATCH] Make each function of SCHED_CRITMONITOR independent There will be a large performance loss after SCHED_CRITMONITOR is enabled. By isolating thread running time-related functions, CPU load can be run with less overhead. Signed-off-by: yinshengkai Signed-off-by: buxiasen --- fs/procfs/fs_procfscritmon.c | 6 +++++ fs/procfs/fs_procfsproc.c | 8 +++++- include/nuttx/sched.h | 23 ++++++++++++----- sched/Kconfig | 4 +-- sched/clock/clock_gettime.c | 4 +-- sched/irq/irq_csection.c | 8 +++--- sched/irq/irq_dispatch.c | 4 --- sched/sched/sched.h | 34 +++++++++++++++++++++++-- sched/sched/sched_critmonitor.c | 45 +++++++++++++++++++++------------ sched/sched/sched_lock.c | 14 +++------- sched/sched/sched_unlock.c | 4 +-- 11 files changed, 104 insertions(+), 50 deletions(-) diff --git a/fs/procfs/fs_procfscritmon.c b/fs/procfs/fs_procfscritmon.c index 8884babb3a..c6f533dc3d 100644 --- a/fs/procfs/fs_procfscritmon.c +++ b/fs/procfs/fs_procfscritmon.c @@ -186,6 +186,10 @@ static ssize_t critmon_read_cpu(FAR struct critmon_file_s *attr, size_t copysize; size_t totalsize; + UNUSED(maxtime); + UNUSED(linesize); + UNUSED(copysize); + totalsize = 0; /* Generate output for CPU Serial Number */ @@ -234,7 +238,9 @@ static ssize_t critmon_read_cpu(FAR struct critmon_file_s *attr, { return totalsize; } +#endif +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 /* Convert and generate output for maximum time in a critical section */ if (g_crit_max[cpu] > 0) diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c index 2c7f8b6a9b..4a45f1ed9c 100644 --- a/fs/procfs/fs_procfsproc.c +++ b/fs/procfs/fs_procfsproc.c @@ -775,6 +775,7 @@ static ssize_t proc_critmon(FAR struct proc_file_s *procfile, /* Convert the for maximum time pre-emption disabled */ +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 if (tcb->premp_max > 0) { perf_convert(tcb->premp_max, &maxtime); @@ -805,9 +806,11 @@ static ssize_t proc_critmon(FAR struct proc_file_s *procfile, { return totalsize; } +#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPT >= 0 */ /* Convert and generate output for maximum time in a critical section */ +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 if (tcb->crit_max > 0) { perf_convert(tcb->crit_max, &maxtime); @@ -838,9 +841,10 @@ static ssize_t proc_critmon(FAR struct proc_file_s *procfile, { return totalsize; } +#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 */ /* Convert and generate output for maximum time thread running */ - +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD >= 0 if (tcb->run_max > 0) { perf_convert(tcb->run_max, &maxtime); @@ -870,6 +874,8 @@ static ssize_t proc_critmon(FAR struct proc_file_s *procfile, &offset); totalsize += copysize; +#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD >= 0 */ + return totalsize; } #endif diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 4d35f36229..e78a16ce80 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -654,16 +654,22 @@ struct tcb_s /* Pre-emption monitor support ********************************************/ -#ifdef CONFIG_SCHED_CRITMONITOR - clock_t premp_start; /* Time when preemption disabled */ - clock_t premp_max; /* Max time preemption disabled */ - clock_t crit_start; /* Time critical section entered */ - clock_t crit_max; /* Max time in critical section */ +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD >= 0 clock_t run_start; /* Time when thread begin run */ clock_t run_max; /* Max time thread run */ clock_t run_time; /* Total time thread run */ #endif +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 + clock_t premp_start; /* Time when preemption disabled */ + clock_t premp_max; /* Max time preemption disabled */ +#endif + +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 + clock_t crit_start; /* Time critical section entered */ + clock_t crit_max; /* Max time in critical section */ +#endif + /* State save areas *******************************************************/ /* The form and content of these fields are platform-specific. */ @@ -799,12 +805,15 @@ extern "C" #define EXTERN extern #endif -#ifdef CONFIG_SCHED_CRITMONITOR /* Maximum time with pre-emption disabled or within critical section. */ +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 EXTERN clock_t g_premp_max[CONFIG_SMP_NCPUS]; +#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 */ + +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 EXTERN clock_t g_crit_max[CONFIG_SMP_NCPUS]; -#endif /* CONFIG_SCHED_CRITMONITOR */ +#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 */ EXTERN const struct tcbinfo_s g_tcbinfo; diff --git a/sched/Kconfig b/sched/Kconfig index 9ca5496a70..35c74bf33a 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -941,7 +941,7 @@ config SCHED_CRITMONITOR_MAXTIME_THREAD config SCHED_CRITMONITOR_MAXTIME_WQUEUE int "WORK queue max execution time" - default SCHED_CRITMONITOR_MAXTIME_THREAD + default -1 ---help--- Worker execution time should be smaller than SCHED_CRITMONITOR_MAXTIME_WQUEUE, or system will give a warning. @@ -1062,7 +1062,7 @@ config SCHED_CPULOAD_EXTCLK config SCHED_CPULOAD_CRITMONITOR bool "Use critical monitor" - depends on SCHED_CRITMONITOR + depends on SCHED_CRITMONITOR_MAXTIME_THREAD >= 0 ---help--- Use the perfcounter in the core of the chip as a counter, no need to use an external timer. Need to depend on SCHED_CRITMONITOR. diff --git a/sched/clock/clock_gettime.c b/sched/clock/clock_gettime.c index 351a2e970a..f3ee59d135 100644 --- a/sched/clock/clock_gettime.c +++ b/sched/clock/clock_gettime.c @@ -47,7 +47,7 @@ * Private Functions ****************************************************************************/ -#ifdef CONFIG_SCHED_CRITMONITOR +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD >= 0 static clock_t clock_process_runtime(FAR struct tcb_s *tcb) { # ifdef HAVE_GROUP_MEMBERS @@ -118,7 +118,7 @@ void nxclock_gettime(clockid_t clock_id, FAR struct timespec *tp) } else { -#ifdef CONFIG_SCHED_CRITMONITOR +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD >= 0 clockid_t clock_type = clock_id & CLOCK_MASK; pid_t pid = clock_id >> CLOCK_SHIFT; FAR struct tcb_s *tcb; diff --git a/sched/irq/irq_csection.c b/sched/irq/irq_csection.c index d4b71cfc61..7209ddc87b 100644 --- a/sched/irq/irq_csection.c +++ b/sched/irq/irq_csection.c @@ -382,7 +382,7 @@ try_again_in_irq: /* Note that we have entered the critical section */ -#ifdef CONFIG_SCHED_CRITMONITOR +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 nxsched_critmon_csection(rtcb, true); #endif #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION @@ -422,7 +422,7 @@ irqstate_t enter_critical_section(void) { /* Note that we have entered the critical section */ -#ifdef CONFIG_SCHED_CRITMONITOR +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 nxsched_critmon_csection(rtcb, true); #endif #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION @@ -523,7 +523,7 @@ void leave_critical_section(irqstate_t flags) { /* No.. Note that we have left the critical section */ -#ifdef CONFIG_SCHED_CRITMONITOR +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 nxsched_critmon_csection(rtcb, false); #endif #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION @@ -577,7 +577,7 @@ void leave_critical_section(irqstate_t flags) { /* Note that we have left the critical section */ -#ifdef CONFIG_SCHED_CRITMONITOR +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 nxsched_critmon_csection(rtcb, false); #endif #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION diff --git a/sched/irq/irq_dispatch.c b/sched/irq/irq_dispatch.c index 9ac3883082..2e9bb602d6 100644 --- a/sched/irq/irq_dispatch.c +++ b/sched/irq/irq_dispatch.c @@ -51,10 +51,6 @@ * interrupt request */ -#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_IRQ -# define CONFIG_SCHED_CRITMONITOR_MAXTIME_IRQ 0 -#endif - #ifdef CONFIG_SCHED_IRQMONITOR # define CALL_VECTOR(ndx, vector, irq, context, arg) \ do \ diff --git a/sched/sched/sched.h b/sched/sched/sched.h index 8dc6a0a878..64abe7ba98 100644 --- a/sched/sched/sched.h +++ b/sched/sched/sched.h @@ -107,6 +107,30 @@ # define TLIST_BLOCKED(t) __TLIST_HEAD(t) #endif +#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD +# define CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD -1 +#endif + +#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_WQUEUE +# define CONFIG_SCHED_CRITMONITOR_MAXTIME_WQUEUE -1 +#endif + +#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION +# define CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION -1 +#endif + +#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION +# define CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION -1 +#endif + +#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_IRQ +# define CONFIG_SCHED_CRITMONITOR_MAXTIME_IRQ -1 +#endif + +#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_WDOG +# define CONFIG_SCHED_CRITMONITOR_MAXTIME_WDOG -1 +#endif + #ifdef CONFIG_SCHED_CRITMONITOR_MAXTIME_PANIC # define CRITMONITOR_PANIC(fmt, ...) \ do \ @@ -418,12 +442,18 @@ void nxsched_process_cpuload_ticks(clock_t ticks); /* Critical section monitor */ #ifdef CONFIG_SCHED_CRITMONITOR -void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state); -void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state); void nxsched_resume_critmon(FAR struct tcb_s *tcb); void nxsched_suspend_critmon(FAR struct tcb_s *tcb); #endif +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 +void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state); +#endif + +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 +void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state); +#endif + /* TCB operations */ bool nxsched_verify_tcb(FAR struct tcb_s *tcb); diff --git a/sched/sched/sched_critmonitor.c b/sched/sched/sched_critmonitor.c index 948e1dac87..72b9cf1669 100644 --- a/sched/sched/sched_critmonitor.c +++ b/sched/sched/sched_critmonitor.c @@ -34,24 +34,10 @@ #include "sched/sched.h" -#ifdef CONFIG_SCHED_CRITMONITOR - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION -# define CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION 0 -#endif - -#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION -# define CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION 0 -#endif - -#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD -# define CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD 0 -#endif - #if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION > 0 # define CHECK_PREEMPTION(pid, elapsed) \ do \ @@ -106,8 +92,13 @@ /* Start time when pre-emption disabled or critical section entered. */ +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 static clock_t g_premp_start[CONFIG_SMP_NCPUS]; +#endif + +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 static clock_t g_crit_start[CONFIG_SMP_NCPUS]; +#endif /**************************************************************************** * Public Data @@ -115,8 +106,13 @@ static clock_t g_crit_start[CONFIG_SMP_NCPUS]; /* Maximum time with pre-emption disabled or within critical section. */ +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 clock_t g_premp_max[CONFIG_SMP_NCPUS]; +#endif + +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 clock_t g_crit_max[CONFIG_SMP_NCPUS]; +#endif /**************************************************************************** * Private Functions @@ -187,6 +183,7 @@ static void nxsched_critmon_cpuload(FAR struct tcb_s *tcb, clock_t current, * ****************************************************************************/ +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state) { int cpu = this_cpu(); @@ -222,6 +219,7 @@ void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state) } } } +#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 */ /**************************************************************************** * Name: nxsched_critmon_csection @@ -235,6 +233,7 @@ void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state) * ****************************************************************************/ +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state) { int cpu = this_cpu(); @@ -270,6 +269,7 @@ void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state) } } } +#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 */ /**************************************************************************** * Name: nxsched_resume_critmon @@ -290,10 +290,16 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb) int cpu = this_cpu(); clock_t elapsed; + UNUSED(cpu); + UNUSED(elapsed); + +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD >= 0 tcb->run_start = current; +#endif /* Did this task disable pre-emption? */ +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 if (tcb->lockcount > 0) { /* Yes.. Save the start time */ @@ -312,7 +318,9 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb) CHECK_PREEMPTION(tcb->pid, elapsed); } } +#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION */ +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 /* Was this task in a critical section? */ if (tcb->irqcount > 0) @@ -333,6 +341,7 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb) CHECK_CSECTION(tcb->pid, elapsed); } } +#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION */ } /**************************************************************************** @@ -358,15 +367,18 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb) nxsched_critmon_cpuload(tcb, current, tick); #endif +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD >= 0 tcb->run_time += elapsed; if (elapsed > tcb->run_max) { tcb->run_max = elapsed; CHECK_THREAD(tcb->pid, elapsed); } +#endif /* Did this task disable preemption? */ +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 if (tcb->lockcount > 0) { /* Possibly re-enabling.. Check for the max elapsed time */ @@ -378,9 +390,10 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb) CHECK_PREEMPTION(tcb->pid, elapsed); } } +#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION */ /* Is this task in a critical section? */ - +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 if (tcb->irqcount > 0) { /* Possibly leaving .. Check for the max elapsed time */ @@ -392,6 +405,6 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb) CHECK_CSECTION(tcb->pid, elapsed); } } +#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION */ } -#endif diff --git a/sched/sched/sched_lock.c b/sched/sched/sched_lock.c index 94e28bd420..692eaa0d8e 100644 --- a/sched/sched/sched_lock.c +++ b/sched/sched/sched_lock.c @@ -152,22 +152,19 @@ int sched_lock(void) rtcb->lockcount++; -#if defined(CONFIG_SCHED_INSTRUMENTATION_PREEMPTION) || \ - defined(CONFIG_SCHED_CRITMONITOR) /* Check if we just acquired the lock */ if (rtcb->lockcount == 1) { /* Note that we have pre-emption locked */ -#ifdef CONFIG_SCHED_CRITMONITOR - nxsched_critmon_preemption(rtcb, true); +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 + nxsched_critmon_preemption(rtcb, true); #endif #ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION - sched_note_premption(rtcb, true); + sched_note_premption(rtcb, true); #endif } -#endif /* Move any tasks in the ready-to-run list to the pending task list * where they will not be available to run until the scheduler is @@ -209,22 +206,19 @@ int sched_lock(void) rtcb->lockcount++; -#if defined(CONFIG_SCHED_INSTRUMENTATION_PREEMPTION) || \ - defined(CONFIG_SCHED_CRITMONITOR) /* Check if we just acquired the lock */ if (rtcb->lockcount == 1) { /* Note that we have pre-emption locked */ -#ifdef CONFIG_SCHED_CRITMONITOR +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 nxsched_critmon_preemption(rtcb, true); #endif #ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION sched_note_premption(rtcb, true); #endif } -#endif } return OK; diff --git a/sched/sched/sched_unlock.c b/sched/sched/sched_unlock.c index d845a66227..2f53774f34 100644 --- a/sched/sched/sched_unlock.c +++ b/sched/sched/sched_unlock.c @@ -92,7 +92,7 @@ int sched_unlock(void) { /* Note that we no longer have pre-emption disabled. */ -#ifdef CONFIG_SCHED_CRITMONITOR +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 nxsched_critmon_preemption(rtcb, false); #endif #ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION @@ -249,7 +249,7 @@ int sched_unlock(void) { /* Note that we no longer have pre-emption disabled. */ -#ifdef CONFIG_SCHED_CRITMONITOR +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 nxsched_critmon_preemption(rtcb, false); #endif #ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION