From 74d29cf8649dda5726c875f07ecffaf06f897ff0 Mon Sep 17 00:00:00 2001 From: ligd Date: Fri, 7 May 2021 17:55:24 +0800 Subject: [PATCH] sched_critmon: add thread run time to critmonitor Change-Id: Ib44e45f0f9a1b249b4067db324c9dbdf0cf3f288 Signed-off-by: ligd (cherry picked from commit 08aeeb5981aeb8787a9d259506185650638b9970) --- fs/procfs/fs_procfsproc.c | 37 +++++++++++++++++++++++++++++++-- include/nuttx/sched.h | 2 ++ sched/sched/sched_critmonitor.c | 29 ++++++++++++++++++-------- 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c index 0b7bc45d7ee..87d008de569 100644 --- a/fs/procfs/fs_procfsproc.c +++ b/fs/procfs/fs_procfsproc.c @@ -803,7 +803,7 @@ static ssize_t proc_critmon(FAR struct proc_file_s *procfile, linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu,", (unsigned long)maxtime.tv_sec, (unsigned long)maxtime.tv_nsec); - copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen, + copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, &offset); totalsize += copysize; @@ -833,10 +833,43 @@ static ssize_t proc_critmon(FAR struct proc_file_s *procfile, /* Generate output for maximum time in a critical section */ + linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu,", + (unsigned long)maxtime.tv_sec, + (unsigned long)maxtime.tv_nsec); + copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, + &offset); + + totalsize += copysize; + buffer += copysize; + remaining -= copysize; + + if (totalsize >= buflen) + { + return totalsize; + } + + /* Convert and generate output for maximum time thread running */ + + if (tcb->run_max > 0) + { + up_critmon_convert(tcb->run_max, &maxtime); + } + else + { + maxtime.tv_sec = 0; + maxtime.tv_nsec = 0; + } + + /* Reset the maximum */ + + tcb->run_max = 0; + + /* Generate output for maximum time thread running */ + linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu\n", (unsigned long)maxtime.tv_sec, (unsigned long)maxtime.tv_nsec); - copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen, + copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, &offset); totalsize += copysize; diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 4f7f647a27b..7250d20d8c5 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -708,6 +708,8 @@ struct tcb_s uint32_t premp_max; /* Max time preemption disabled */ uint32_t crit_start; /* Time critical section entered */ uint32_t crit_max; /* Max time in critical section */ + uint32_t run_start; /* Time when thread begin run */ + uint32_t run_max; /* Max time thread run */ #endif /* State save areas ***********************************************************/ diff --git a/sched/sched/sched_critmonitor.c b/sched/sched/sched_critmonitor.c index 89113666b6a..3ae0e0d4e98 100644 --- a/sched/sched/sched_critmonitor.c +++ b/sched/sched/sched_critmonitor.c @@ -207,10 +207,14 @@ void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state) void nxsched_resume_critmon(FAR struct tcb_s *tcb) { - uint32_t elapsed; + uint32_t current = up_critmon_gettime(); int cpu = this_cpu(); + uint32_t elapsed; - DEBUGASSERT(tcb->premp_start == 0 && tcb->crit_start == 0); + DEBUGASSERT(tcb->premp_start == 0 && tcb->crit_start == 0 && + tcb->run_start == 0); + + tcb->run_start = current; /* Did this task disable pre-emption? */ @@ -218,7 +222,7 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb) { /* Yes.. Save the start time */ - tcb->premp_start = up_critmon_gettime(); + tcb->premp_start = current; DEBUGASSERT(tcb->premp_start != 0); /* Zero means that the timer is not ready */ @@ -232,7 +236,7 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb) { /* Check for the global max elapsed time */ - elapsed = up_critmon_gettime() - g_premp_start[cpu]; + elapsed = current - g_premp_start[cpu]; g_premp_start[cpu] = 0; if (elapsed > g_premp_max[cpu]) @@ -247,7 +251,7 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb) { /* Yes.. Save the start time */ - tcb->crit_start = up_critmon_gettime(); + tcb->crit_start = current; DEBUGASSERT(tcb->crit_start != 0); if (g_crit_start[cpu] == 0) @@ -259,7 +263,7 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb) { /* Check for the global max elapsed time */ - elapsed = up_critmon_gettime() - g_crit_start[cpu]; + elapsed = current - g_crit_start[cpu]; g_crit_start[cpu] = 0; if (elapsed > g_crit_max[cpu]) @@ -284,7 +288,14 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb) void nxsched_suspend_critmon(FAR struct tcb_s *tcb) { - uint32_t elapsed; + uint32_t current = up_critmon_gettime(); + uint32_t elapsed = current - tcb->run_start; + + tcb->run_start = 0; + if (elapsed > tcb->run_max) + { + tcb->run_max = elapsed; + } /* Did this task disable preemption? */ @@ -292,7 +303,7 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb) { /* Possibly re-enabling.. Check for the max elapsed time */ - elapsed = up_critmon_gettime() - tcb->premp_start; + elapsed = current - tcb->premp_start; tcb->premp_start = 0; if (elapsed > tcb->premp_max) @@ -307,7 +318,7 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb) { /* Possibly leaving .. Check for the max elapsed time */ - elapsed = up_critmon_gettime() - tcb->crit_start; + elapsed = current - tcb->crit_start; tcb->crit_start = 0; if (elapsed > tcb->crit_max)