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 <yinshengkai@xiaomi.com>
Signed-off-by: buxiasen <buxiasen@xiaomi.com>
This commit is contained in:
yinshengkai 2024-01-26 15:50:18 +08:00 committed by Xiang Xiao
parent 6b07284c61
commit e28b311b78
11 changed files with 104 additions and 50 deletions

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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 \

View File

@ -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);

View File

@ -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

View File

@ -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
#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
/* 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;

View File

@ -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