This is an automated email from the ASF dual-hosted git repository. ligd pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit b2a69ba781603fc7e1d477ea087b3e2f312a6858 Author: guoshengyuan1 <[email protected]> AuthorDate: Thu Sep 25 20:10:45 2025 +0800 sched: merge nxsched_suspend/resume_critmon Merge suspend and resume into one switch to optimize performance Co-authored-by: yinshengkai <[email protected]> Signed-off-by: guoshengyuan1 <[email protected]> --- sched/sched/sched.h | 3 +- sched/sched/sched_critmonitor.c | 129 +++++++++++++++++--------------------- sched/sched/sched_switchcontext.c | 5 +- 3 files changed, 59 insertions(+), 78 deletions(-) diff --git a/sched/sched/sched.h b/sched/sched/sched.h index 3d414f1e3fd..2ce145d1db7 100644 --- a/sched/sched/sched.h +++ b/sched/sched/sched.h @@ -416,8 +416,7 @@ void nxsched_process_cpuload_ticks(clock_t ticks); void nxsched_switch_context(FAR struct tcb_s *from, FAR struct tcb_s *to); #ifdef CONFIG_SCHED_CRITMONITOR -void nxsched_resume_critmon(FAR struct tcb_s *tcb); -void nxsched_suspend_critmon(FAR struct tcb_s *tcb); +void nxsched_switch_critmon(FAR struct tcb_s *from, FAR struct tcb_s *to); void nxsched_update_critmon(FAR struct tcb_s *tcb); #endif diff --git a/sched/sched/sched_critmonitor.c b/sched/sched/sched_critmonitor.c index 9d8dc7d0379..610b07e35cd 100644 --- a/sched/sched/sched_critmonitor.c +++ b/sched/sched/sched_critmonitor.c @@ -262,99 +262,56 @@ void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state, #endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 */ /**************************************************************************** - * Name: nxsched_resume_critmon + * Name: nxsched_switch_critmon * * Description: - * Called when a thread resumes execution, perhaps re-establishing a - * critical section or a non-pre-emptible state. + * Called when a thread is switched, update the critical monitor data. * - * Assumptions: - * - Called within a critical section. - * - Might be called from an interrupt handler - * - ****************************************************************************/ - -void nxsched_resume_critmon(FAR struct tcb_s *tcb) -{ - clock_t current = perf_gettime(); - - 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 (nxsched_islocked_tcb(tcb)) - { - /* Yes.. Save the start time */ - - tcb->preemp_start = current; - } -#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION */ - -#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 - /* Was this task in a critical section? */ - - if (tcb->irqcount > 0) - { - /* Yes.. Save the start time */ - - tcb->crit_start = current; - } -#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION */ -} - -/**************************************************************************** - * Name: nxsched_suspend_critmon - * - * Description: - * Called when a thread suspends execution, perhaps terminating a - * critical section or a non-preemptible state. + * Input Parameters: + * from - The thread that is being switched out. + * to - The thread that is being switched in. * - * Assumptions: - * - Called within a critical section. - * - Might be called from an interrupt handler + * Returned Value: + * None * ****************************************************************************/ -void nxsched_suspend_critmon(FAR struct tcb_s *tcb) +void nxsched_switch_critmon(FAR struct tcb_s *from, FAR struct tcb_s *to) { clock_t current = perf_gettime(); - clock_t elapsed = current - tcb->run_start; - int cpu = this_cpu(); + clock_t elapsed = current - from->run_start; #ifdef CONFIG_SCHED_CPULOAD_CRITMONITOR clock_t tick = elapsed * CLOCKS_PER_SEC / perf_getfreq(); - nxsched_critmon_cpuload(tcb, current, tick); + nxsched_critmon_cpuload(from, current, tick); #endif - UNUSED(cpu); - #if CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD >= 0 - tcb->run_time += elapsed; - if (elapsed > tcb->run_max) + from->run_time += elapsed; + to->run_time = current; + if (elapsed > from->run_max) { - tcb->run_max = elapsed; - CHECK_THREAD(tcb->pid, elapsed); + from->run_max = elapsed; + CHECK_THREAD(from->pid, elapsed); } #endif #if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 + /* Did this task disable preemption? */ - if (nxsched_islocked_tcb(tcb)) + if (nxsched_islocked_tcb(from)) { + int cpu = this_cpu(); + /* Possibly re-enabling.. Check for the max elapsed time */ - elapsed = current - tcb->preemp_start; - if (elapsed > tcb->preemp_max) + elapsed = current - from->preemp_start; + if (elapsed > from->preemp_max) { - tcb->preemp_max = elapsed; - tcb->preemp_max_caller = tcb->preemp_caller; - CHECK_PREEMPTION(tcb->pid, elapsed); + from->preemp_max = elapsed; + from->preemp_max_caller = from->preemp_caller; + CHECK_PREEMPTION(from->pid, elapsed); } /* Suspend percore preemptible statistic and if necessary will @@ -366,21 +323,29 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb) g_preemp_max[cpu] = elapsed; } } + + if (to->lockcount > 0) + { + to->premp_start = current; + } #endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION */ #if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 + /* Is this task in a critical section? */ - if (tcb->irqcount > 0) + if (from->irqcount > 0) { + int cpu = this_cpu(); + /* Possibly leaving .. Check for the max elapsed time */ - elapsed = current - tcb->crit_start; - if (elapsed > tcb->crit_max) + elapsed = current - from->crit_start; + if (elapsed > from->crit_max) { - tcb->crit_max = elapsed; - tcb->crit_max_caller = tcb->crit_caller; - CHECK_CSECTION(tcb->pid, elapsed); + from->crit_max = elapsed; + from->crit_max_caller = from->crit_caller; + CHECK_CSECTION(from->pid, elapsed); } /* Check for the global max elapsed time */ @@ -390,7 +355,25 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb) g_crit_max[cpu] = elapsed; } } + + if (to->irqcount > 0) + { + to->crit_start = current; + } + #endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION */ + +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 + + /* Did this task disable pre-emption? */ + + if (to->lockcount > 0) + { + /* Yes.. Save the start time */ + + to->premp_start = current; + } +#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION */ } void nxsched_update_critmon(FAR struct tcb_s *tcb) diff --git a/sched/sched/sched_switchcontext.c b/sched/sched/sched_switchcontext.c index 9b866272a27..0db4e01b984 100644 --- a/sched/sched/sched_switchcontext.c +++ b/sched/sched/sched_switchcontext.c @@ -28,7 +28,6 @@ #include <nuttx/sched_note.h> - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -72,6 +71,7 @@ void nxsched_switch_context(FAR struct tcb_s *from, FAR struct tcb_s *to) { DEBUGVERIFY(nxsched_suspend_sporadic(from)); } + if ((to->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC) { DEBUGVERIFY(nxsched_resume_sporadic(to)); @@ -81,8 +81,7 @@ void nxsched_switch_context(FAR struct tcb_s *from, FAR struct tcb_s *to) /* Indicate that the task has been suspended */ #ifdef CONFIG_SCHED_CRITMONITOR - nxsched_suspend_critmon(from); - nxsched_resume_critmon(to); + nxsched_switch_critmon(from, to); #endif #ifdef CONFIG_SCHED_INSTRUMENTATION
