diff --git a/sched/sched/sched.h b/sched/sched/sched.h index edc287f75f6..d8ffdf2accb 100644 --- a/sched/sched/sched.h +++ b/sched/sched/sched.h @@ -415,6 +415,7 @@ void nxsched_process_cpuload_ticks(clock_t ticks); #ifdef CONFIG_SCHED_CRITMONITOR void nxsched_resume_critmon(FAR struct tcb_s *tcb); void nxsched_suspend_critmon(FAR struct tcb_s *tcb); +void nxsched_update_critmon(FAR struct tcb_s *tcb); #endif #if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0 diff --git a/sched/sched/sched_cpuload.c b/sched/sched/sched_cpuload.c index 1044fbd2b73..a5b5b81eaa2 100644 --- a/sched/sched/sched_cpuload.c +++ b/sched/sched/sched_cpuload.c @@ -224,6 +224,12 @@ int clock_cpuload(int pid, FAR struct cpuload_s *cpuload) DEBUGASSERT(cpuload); +#ifdef CONFIG_SCHED_CPULOAD_CRITMONITOR + /* Update critmon in case of the target thread busyloop */ + + nxsched_update_critmon(nxsched_get_tcb(pid)); +#endif + /* Momentarily disable interrupts. We need (1) the task to stay valid * while we are doing these operations and (2) the tick counts to be * synchronized when read. diff --git a/sched/sched/sched_critmonitor.c b/sched/sched/sched_critmonitor.c index 15a5d479c88..b7a59d3ed5b 100644 --- a/sched/sched/sched_critmonitor.c +++ b/sched/sched/sched_critmonitor.c @@ -445,3 +445,27 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb) } #endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION */ } + +void nxsched_update_critmon(FAR struct tcb_s *tcb) +{ + clock_t current = perf_gettime(); + clock_t elapsed = current - tcb->run_start; + + if (tcb->task_state != TSTATE_TASK_RUNNING) + { + return; + } + +#ifdef CONFIG_SCHED_CPULOAD_CRITMONITOR + clock_t tick = elapsed * CLOCKS_PER_SEC / perf_getfreq(); + nxsched_process_taskload_ticks(tcb, tick); +#endif + + tcb->run_start = current; + tcb->run_time += elapsed; + if (elapsed > tcb->run_max) + { + tcb->run_max = elapsed; + CHECK_THREAD(tcb->pid, elapsed); + } +}