You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/09/18 19:16:24 UTC
(nuttx) 04/06: critmon: fix context switch critmon pause err.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit b33e20a58631ac2eff9d68acdb484bee51c393bb
Author: buxiasen <bu...@xiaomi.com>
AuthorDate: Mon Jun 3 23:30:44 2024 +0800
critmon: fix context switch critmon pause err.
Elapsed time statistic up to now when sched happen
Signed-off-by: buxiasen <bu...@xiaomi.com>
---
sched/sched/sched_critmonitor.c | 98 +++++++++++++++--------------------------
1 file changed, 36 insertions(+), 62 deletions(-)
diff --git a/sched/sched/sched_critmonitor.c b/sched/sched/sched_critmonitor.c
index 16ae7287fe..69b32a2af6 100644
--- a/sched/sched/sched_critmonitor.c
+++ b/sched/sched/sched_critmonitor.c
@@ -86,20 +86,6 @@
# define CHECK_THREAD(pid, elapsed)
#endif
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* 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
****************************************************************************/
@@ -188,7 +174,7 @@ static void nxsched_critmon_cpuload(FAR struct tcb_s *tcb, clock_t current,
void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state,
FAR void *caller)
{
- int cpu = this_cpu();
+ clock_t current = perf_gettime();
/* Are we enabling or disabling pre-emption */
@@ -196,16 +182,15 @@ void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state,
{
/* Disabling.. Save the thread start time */
- tcb->premp_start = perf_gettime();
- tcb->premp_caller = caller;
- g_premp_start[cpu] = tcb->premp_start;
+ tcb->premp_start = current;
+ tcb->premp_caller = caller;
}
else
{
/* Re-enabling.. Check for the max elapsed time */
- clock_t now = perf_gettime();
- clock_t elapsed = now - tcb->premp_start;
+ clock_t elapsed = current - tcb->premp_start;
+ int cpu = this_cpu();
if (elapsed > tcb->premp_max)
{
@@ -216,7 +201,6 @@ void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state,
/* Check for the global max elapsed time */
- elapsed = now - g_premp_start[cpu];
if (elapsed > g_premp_max[cpu])
{
g_premp_max[cpu] = elapsed;
@@ -242,7 +226,7 @@ void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state,
void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state,
FAR void *caller)
{
- int cpu = this_cpu();
+ clock_t current = perf_gettime();
/* Are we entering or leaving the critical section? */
@@ -250,16 +234,15 @@ void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state,
{
/* Entering... Save the start time. */
- tcb->crit_start = perf_gettime();
- tcb->crit_caller = caller;
- g_crit_start[cpu] = tcb->crit_start;
+ tcb->crit_start = current;
+ tcb->crit_caller = caller;
}
else
{
/* Leaving .. Check for the max elapsed time */
- clock_t now = perf_gettime();
- clock_t elapsed = now - tcb->crit_start;
+ clock_t elapsed = current - tcb->crit_start;
+ int cpu = this_cpu();
if (elapsed > tcb->crit_max)
{
@@ -270,7 +253,6 @@ void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state,
/* Check for the global max elapsed time */
- elapsed = now - g_crit_start[cpu];
if (elapsed > g_crit_max[cpu])
{
g_crit_max[cpu] = elapsed;
@@ -295,36 +277,21 @@ void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state,
void nxsched_resume_critmon(FAR struct tcb_s *tcb)
{
clock_t current = perf_gettime();
- int cpu = this_cpu();
- clock_t elapsed;
- UNUSED(cpu);
- UNUSED(elapsed);
+ UNUSED(current);
#if CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD >= 0
tcb->run_start = current;
#endif
+#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
/* Did this task disable pre-emption? */
-#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
if (tcb->lockcount > 0)
{
/* Yes.. Save the start time */
- tcb->premp_start = current;
- g_premp_start[cpu] = current;
- }
- else
- {
- /* Check for the global max elapsed time */
-
- elapsed = current - g_premp_start[cpu];
- if (elapsed > g_premp_max[cpu])
- {
- g_premp_max[cpu] = elapsed;
- CHECK_PREEMPTION(tcb->pid, elapsed);
- }
+ tcb->premp_start = current;
}
#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION */
@@ -335,19 +302,7 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb)
{
/* Yes.. Save the start time */
- tcb->crit_start = current;
- g_crit_start[cpu] = current;
- }
- else
- {
- /* Check for the global max elapsed time */
-
- elapsed = current - g_crit_start[cpu];
- if (elapsed > g_crit_max[cpu])
- {
- g_crit_max[cpu] = elapsed;
- CHECK_CSECTION(tcb->pid, elapsed);
- }
+ tcb->crit_start = current;
}
#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION */
}
@@ -369,12 +324,15 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
{
clock_t current = perf_gettime();
clock_t elapsed = current - tcb->run_start;
+ int cpu = this_cpu();
#ifdef CONFIG_SCHED_CPULOAD_CRITMONITOR
clock_t tick = elapsed * CLOCKS_PER_SEC / perf_getfreq();
nxsched_critmon_cpuload(tcb, current, tick);
#endif
+ UNUSED(cpu);
+
#if CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD >= 0
tcb->run_time += elapsed;
if (elapsed > tcb->run_max)
@@ -384,9 +342,9 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
}
#endif
+#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
/* 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 */
@@ -398,11 +356,21 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
tcb->premp_max_caller = tcb->premp_caller;
CHECK_PREEMPTION(tcb->pid, elapsed);
}
+
+ /* Suspend percore preemptible statistic and if necessary will
+ * re-open in nxsched_resume_critmon.
+ */
+
+ if (elapsed > g_premp_max[cpu])
+ {
+ g_premp_max[cpu] = elapsed;
+ }
}
#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION */
- /* Is this task in a critical section? */
#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
+ /* Is this task in a critical section? */
+
if (tcb->irqcount > 0)
{
/* Possibly leaving .. Check for the max elapsed time */
@@ -414,7 +382,13 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
tcb->crit_max_caller = tcb->crit_caller;
CHECK_CSECTION(tcb->pid, elapsed);
}
+
+ /* Check for the global max elapsed time */
+
+ if (elapsed > g_crit_max[cpu])
+ {
+ g_crit_max[cpu] = elapsed;
+ }
}
#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION */
}
-