Squashed commit of the following:

fs/procfs/fs_procfsproc:  Extended the process ID ProcFS output to show per-thread maximum time for pre-emption disabled and maximum time within a critical section.

    sched/sched/sched_critmonitor.c:  Adds data collection logic in support of monitoring critical sections and pre-emption state.
This commit is contained in:
Gregory Nutt
2018-11-24 10:32:45 -06:00
parent 6d9103b01a
commit fc6084f311
13 changed files with 521 additions and 30 deletions
+124 -1
View File
@@ -53,6 +53,10 @@
#include <errno.h>
#include <debug.h>
#ifdef CONFIG_SCHED_CRITMONITOR
# include <time.h>
#endif
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
@@ -62,7 +66,7 @@
#include <nuttx/fs/procfs.h>
#include <nuttx/fs/dirent.h>
#ifdef CONFIG_SCHED_CPULOAD
#if defined(CONFIG_SCHED_CPULOAD) || defined(CONFIG_SCHED_CRITMONITOR)
# include <nuttx/clock.h>
#endif
@@ -105,6 +109,9 @@ enum proc_node_e
PROC_CMDLINE, /* Task command line */
#ifdef CONFIG_SCHED_CPULOAD
PROC_LOADAVG, /* Average CPU utilization */
#endif
#ifdef CONFIG_SCHED_CRITMONITOR
PROC_CRITMON, /* Critical section monitor */
#endif
PROC_STACK, /* Task stack info */
PROC_GROUP, /* Group directory */
@@ -167,9 +174,24 @@ static FAR const char *g_policy[4] =
"SCHED_FIFO", "SCHED_RR", "SCHED_SPORADIC", "SCHED_OTHER"
};
/****************************************************************************
* External Function Prototypes
****************************************************************************/
#ifdef CONFIG_SCHED_CRITMONITOR
/* If CONFIG_SCHED_CRITMONITOR is selected, then platform-specific logic
* must provide the following interface. This interface simply converts an
* elapsed time into well known units for presentation by the ProcFS file
* system..
*/
void up_critmon_convert(uint32_t starttime, FAR struct timespec *ts);
#endif
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* Helpers */
static FAR const struct proc_node_s *
@@ -185,6 +207,11 @@ static ssize_t proc_loadavg(FAR struct proc_file_s *procfile,
FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen,
off_t offset);
#endif
#ifdef CONFIG_SCHED_CRITMONITOR
static ssize_t proc_critmon(FAR struct proc_file_s *procfile,
FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen,
off_t offset);
#endif
static ssize_t proc_stack(FAR struct proc_file_s *procfile,
FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen,
off_t offset);
@@ -273,6 +300,13 @@ static const struct proc_node_s g_loadavg =
};
#endif
#ifdef CONFIG_SCHED_CRITMONITOR
static const struct proc_node_s g_critmon =
{
"critmon", "critmon", (uint8_t)PROC_CRITMON, DTYPE_FILE /* Critical Section Monitor */
};
#endif
static const struct proc_node_s g_stack =
{
"stack", "stack", (uint8_t)PROC_STACK, DTYPE_FILE /* Task stack info */
@@ -309,6 +343,9 @@ static FAR const struct proc_node_s * const g_nodeinfo[] =
&g_cmdline, /* Task command line */
#ifdef CONFIG_SCHED_CPULOAD
&g_loadavg, /* Average CPU utilization */
#endif
#ifdef CONFIG_SCHED_CRITMONITOR
&g_critmon, /* Critical section Monitor */
#endif
&g_stack, /* Task stack info */
&g_group, /* Group directory */
@@ -329,6 +366,9 @@ static const struct proc_node_s * const g_level0info[] =
&g_cmdline, /* Task command line */
#ifdef CONFIG_SCHED_CPULOAD
&g_loadavg, /* Average CPU utilization */
#endif
#ifdef CONFIG_SCHED_CRITMONITOR
&g_critmon, /* Critical section monitor */
#endif
&g_stack, /* Task stack info */
&g_group, /* Group directory */
@@ -743,6 +783,84 @@ static ssize_t proc_loadavg(FAR struct proc_file_s *procfile,
}
#endif
/****************************************************************************
* Name: proc_critmon
****************************************************************************/
#ifdef CONFIG_SCHED_CRITMONITOR
static ssize_t proc_critmon(FAR struct proc_file_s *procfile,
FAR struct tcb_s *tcb, FAR char *buffer,
size_t buflen, off_t offset)
{
struct timespec maxtime;
size_t remaining;
size_t linesize;
size_t copysize;
size_t totalsize;
remaining = buflen;
totalsize = 0;
/* Convert the for maximum time pre-emption disabled */
if (tcb->premp_max > 0)
{
up_critmon_convert(tcb->premp_max, &maxtime);
}
else
{
maxtime.tv_sec = 0;
maxtime.tv_nsec = 0;
}
/* Reset the maximum */
tcb->premp_max = 0;
/* Generate output for maximum time pre-emption disabled */
linesize = 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, &offset);
totalsize += copysize;
buffer += copysize;
remaining -= copysize;
if (totalsize >= buflen)
{
return totalsize;
}
/* Convert and generate output for maximum time in a critical section */
if (tcb->crit_max > 0)
{
up_critmon_convert(tcb->crit_max, &maxtime);
}
else
{
maxtime.tv_sec = 0;
maxtime.tv_nsec = 0;
}
/* Reset the maximum */
tcb->crit_max = 0;
/* Generate output for maximum time in a critical section */
linesize = 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, &offset);
totalsize += copysize;
return totalsize;
}
#endif
/****************************************************************************
* Name: proc_stack
****************************************************************************/
@@ -1324,6 +1442,11 @@ static ssize_t proc_read(FAR struct file *filep, FAR char *buffer,
case PROC_LOADAVG: /* Average CPU utilization */
ret = proc_loadavg(procfile, tcb, buffer, buflen, filep->f_pos);
break;
#endif
#ifdef CONFIG_SCHED_CRITMONITOR
case PROC_CRITMON: /* Critical section monitor */
ret = proc_critmon(procfile, tcb, buffer, buflen, filep->f_pos);
break;
#endif
case PROC_STACK: /* Task stack info */
ret = proc_stack(procfile, tcb, buffer, buflen, filep->f_pos);
+6 -3
View File
@@ -1,7 +1,8 @@
/****************************************************************************
* include/nuttx/irq.h
*
* Copyright (C) 2007-2011, 2013, 2016-2017 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2011, 2013, 2016-2017 Gregory Nutt. All rights
* reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -196,7 +197,8 @@ int irqchain_detach(int irq, xcpt_t isr, FAR void *arg);
*
****************************************************************************/
#if defined(CONFIG_SMP) || defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION)
#if defined(CONFIG_SMP) || defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) || \
defined(CONFIG_SCHED_CRITMONITOR)
irqstate_t enter_critical_section(void);
#else
# define enter_critical_section(f) up_irq_save(f)
@@ -223,7 +225,8 @@ irqstate_t enter_critical_section(void);
*
****************************************************************************/
#if defined(CONFIG_SMP) || defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION)
#if defined(CONFIG_SMP) || defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) || \
defined(CONFIG_SCHED_CRITMONITOR)
void leave_critical_section(irqstate_t flags);
#else
# define leave_critical_section(f) up_irq_restore(f)
+14 -2
View File
@@ -696,6 +696,16 @@ struct tcb_s
FAR void *pthread_data[CONFIG_NPTHREAD_KEYS];
#endif
/* Pre-emption monitor support ************************************************/
#ifdef CONFIG_SCHED_CRITMONITOR
uint32_t crit_flags; /* Flag values used by the monitor */
uint32_t premp_start; /* Time when preemption disabled */
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 */
#endif
/* Library related fields *****************************************************/
int pterrno; /* Current per-thread errno */
@@ -931,7 +941,8 @@ int group_exitinfo(pid_t pid, FAR struct binary_s *bininfo);
********************************************************************************/
#if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC) || \
defined(CONFIG_SCHED_INSTRUMENTATION) || defined(CONFIG_SMP)
defined(CONFIG_SCHED_INSTRUMENTATION) || defined(CONFIG_SCHED_CRITMONITOR) || \
defined(CONFIG_SMP)
void sched_resume_scheduler(FAR struct tcb_s *tcb);
#else
# define sched_resume_scheduler(tcb)
@@ -953,7 +964,8 @@ void sched_resume_scheduler(FAR struct tcb_s *tcb);
*
********************************************************************************/
#if defined(CONFIG_SCHED_SPORADIC) || defined(CONFIG_SCHED_INSTRUMENTATION)
#if defined(CONFIG_SCHED_SPORADIC) || defined(CONFIG_SCHED_INSTRUMENTATION) || \
defined(CONFIG_SCHED_CRITMONITOR)
void sched_suspend_scheduler(FAR struct tcb_s *tcb);
#else
# define sched_suspend_scheduler(tcb)
+33
View File
@@ -700,6 +700,39 @@ config SCHED_IRQMONITOR
counts will be available in the mounted procfs file systems at the
top-level file, "irqs".
config SCHED_CRITMONITOR
bool "Enable Critical Section monitoring"
default n
depends on FS_PROCFS
---help---
Enables logic that monitors the duration of time that a thread keeps
interrupts or pre-emption disabled. These global locks can have
negative consequences to real timer performance: Disabling interrupts
adds jitter in the time when a interrupt request is asserted until
the hardware can responds with the interrupt. Disabling pre-emption
adds jitter in the timer from when the event is posted in the
interrupt handler until the task that responds to the event can run.
If this option is selected, then the following interfaces must be
provided by platform-specific logic:
uint32_t up_critmon_gettime(void);
void up_critmon_convert(uint32_t starttime, FAR struct timespec *ts);
The first interface simply provides the current time value in unknown
units. NOTE: This function may be called early before the timer has
been initialized. In that event, the function should just return a
start time of zero.
Nothing is assumed about the units of this time value. The following
are assumed, however: (1) The time is an unsigned is an unsigned integer
value, (2) is is monotonically increasing, and (3) the elapsed time
(also in unknown units) can be obtained by subtracting a start time
from the current time.
The second interface simple converts an elapsed time into well known
units for presentation by the ProcFS file system..
config SCHED_CPULOAD
bool "Enable CPU load monitoring"
default n
+2
View File
@@ -44,6 +44,8 @@ endif
endif
else ifeq ($(CONFIG_SCHED_INSTRUMENTATION_CSECTION),y)
CSRCS += irq_csection.c
else ifeq ($(CONFIG_SCHED_CRITMONITOR),y)
CSRCS += irq_csection.c
endif
ifeq ($(CONFIG_SCHED_IRQMONITOR),y)
+28 -6
View File
@@ -49,7 +49,8 @@
#include "sched/sched.h"
#include "irq/irq.h"
#if defined(CONFIG_SMP) || defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION)
#if defined(CONFIG_SMP) || defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) || \
defined(CONFIG_SCHED_CRITMONITOR)
/****************************************************************************
* Public Data
@@ -375,9 +376,12 @@ try_again:
&g_cpu_irqlock);
rtcb->irqcount = 1;
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
/* Note that we have entered the critical section */
#ifdef CONFIG_SCHED_CRITMONITOR
sched_critmon_csection(rtcb, true);
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
sched_note_csection(rtcb, true);
#endif
}
@@ -388,7 +392,8 @@ try_again:
return ret;
}
#else /* defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) */
#else /* defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) || \
* defined(CONFIG_SCHED_CRITMONITOR) */
irqstate_t enter_critical_section(void)
{
irqstate_t ret;
@@ -408,7 +413,12 @@ irqstate_t enter_critical_section(void)
/* Yes.. Note that we have entered the critical section */
#ifdef CONFIG_SCHED_CRITMONITOR
sched_critmon_csection(rtcb, true);
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
sched_note_csection(rtcb, true);
#endif
}
/* Return interrupt status */
@@ -507,9 +517,12 @@ void leave_critical_section(irqstate_t flags)
}
else
{
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
/* No.. Note that we have left the critical section */
#ifdef CONFIG_SCHED_CRITMONITOR
sched_critmon_csection(rtcb, false);
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
sched_note_csection(rtcb, false);
#endif
/* Decrement our count on the lock. If all CPUs have
@@ -563,7 +576,10 @@ void leave_critical_section(irqstate_t flags)
up_irq_restore(flags);
}
#else /* defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) */
#else /* defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) ||
* defined(CONFIG_SCHED_CRITMONITOR) */
void leave_critical_section(irqstate_t flags)
{
/* Check if we were called from an interrupt handler and that the tasks
@@ -577,7 +593,12 @@ void leave_critical_section(irqstate_t flags)
/* Yes.. Note that we have left the critical section */
#ifdef CONFIG_SCHED_CRITMONITOR
sched_critmon_csection(rtcb, false);
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
sched_note_csection(rtcb, false);
#endif
}
/* Restore the previous interrupt state. */
@@ -669,4 +690,5 @@ bool irq_cpu_locked(int cpu)
}
#endif
#endif /* CONFIG_SMP || CONFIG_SCHED_INSTRUMENTATION_CSECTION */
#endif /* CONFIG_SMP || CONFIG_SCHED_INSTRUMENTATION_CSECTION ||
* CONFIG_SCHED_CRITMONITOR */
+12 -4
View File
@@ -73,6 +73,8 @@ ifeq ($(CONFIG_SCHED_SPORADIC),y)
CSRCS += sched_sporadic.c sched_suspendscheduler.c
else ifeq ($(CONFIG_SCHED_INSTRUMENTATION),y)
CSRCS += sched_suspendscheduler.c
else ifeq ($(CONFIG_SCHED_CRITMONITOR),y)
CSRCS += sched_suspendscheduler.c
endif
ifneq ($(CONFIG_RR_INTERVAL),0)
@@ -81,6 +83,8 @@ else ifeq ($(CONFIG_SCHED_SPORADIC),y)
CSRCS += sched_resumescheduler.c
else ifeq ($(CONFIG_SCHED_INSTRUMENTATION),y)
CSRCS += sched_resumescheduler.c
else ifeq ($(CONFIG_SCHED_CRITMONITOR),y)
CSRCS += sched_resumescheduler.c
else ifeq ($(CONFIG_SMP),y)
CSRCS += sched_resumescheduler.c
endif
@@ -101,10 +105,6 @@ else
CSRCS += sched_processtimer.c
endif
ifeq ($(CONFIG_SCHED_INSTRUMENTATION_BUFFER),y)
CSRCS += sched_note.c
endif
ifeq ($(CONFIG_SMP),y)
CSRCS += sched_tasklistlock.c
ifeq ($(CONFIG_ARCH_GLOBAL_IRQDISABLE),y)
@@ -114,6 +114,14 @@ CSRCS += sched_thistask.c
endif
endif
ifeq ($(CONFIG_SCHED_INSTRUMENTATION_BUFFER),y)
CSRCS += sched_note.c
endif
ifeq ($(CONFIG_SCHED_CRITMONITOR),y)
CSRCS += sched_critmonitor.c
endif
# Include sched build support
DEPPATH += --dep-path sched
+9
View File
@@ -496,6 +496,15 @@ void sched_tasklist_unlock(irqstate_t lock);
void weak_function sched_process_cpuload(void);
#endif
/* Critical section monitor */
#ifdef CONFIG_SCHED_CRITMONITOR
void sched_critmon_preemption(FAR struct tcb_s *tcb, bool state);
void sched_critmon_csection(FAR struct tcb_s *tcb, bool state);
void sched_critmon_resume(FAR struct tcb_s *tcb);
void sched_critmon_suspend(FAR struct tcb_s *tcb);
#endif
/* TCB operations */
bool sched_verifytcb(FAR struct tcb_s *tcb);
+249
View File
@@ -0,0 +1,249 @@
/****************************************************************************
* sched/sched/sched_critmonitor.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/types.h>
#include <sched.h>
#include "sched/sched.h"
#ifdef CONFIG_SCHED_CRITMONITOR
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Flags used by the critical section monitor */
#define CRITMON_PREEMPT (1 << 0) /* Bit 0: Pre-emption is disabled */
#define CRITMON_CSECTION (1 << 1) /* Bit 1: In a critical section */
#define DISABLE_PREEMPT(t) do { (t)->flags |= CRITMON_PREEMPT; } while (0)
#define ENTER_CSECTION(t) do { (t)->flags |= CRITMON_PREEMPT; } while (0)
#define ENABLE_PREEMPT(t) do { (t)->flags &= ~CRITMON_PREEMPT; } while (0)
#define LEAVE_CSECTION(t) do { (t)->flags &= ~CRITMON_PREEMPT; } while (0)
#define PREEMPT_DISABLED(t) (((t)->crit_flags & CRITMON_PREEMPT) != 0)
#define IN_CSECTION(t) (((t)->crit_flags & CRITMON_CSECTION) != 0)
/****************************************************************************
* External Function Prototypes
****************************************************************************/
/* If CONFIG_SCHED_CRITMONITOR is selected, then platform-specific logic
* must provide the following interface. This interface simply provides the
* current time value in unknown units. NOTE: This function may be called
* early before the timer has been initialized. In that event, the function
* should just return a start time of zero.
*
* Nothing is assumed about the units of this time value. The following
* are assumed, however: (1) The time is an unsigned is an unsigned integer
* value, (2) is is monotonically increasing, and (3) the elapsed time
* (also in unknown units) can be obtained by subtracting a start time
* from the current time.
*/
uint32_t up_critmon_gettime(void);
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sched_critmon_preemption
*
* Description:
* Called when there is any change in pre-emptible state of a thread.
*
* Assumptions:
* Called within a critical section.
*
****************************************************************************/
void sched_critmon_preemption(FAR struct tcb_s *tcb, bool state)
{
/* Are we enabling or disabling pre-emption */
if (state)
{
DEBUGASSERT(tcb->premp_start == 0 && !PREEMPT_DISABLED(tcb));
/* Disabling.. Save the start time */
tcb->premp_start = up_critmon_gettime();
DISABLE_PREEMPT(tcb);
}
else if (tcb->premp_start != 0)
{
DEBUGASSERT(PREEMPT_DISABLED(tcb));
/* Re-enabling.. Check for the max elapsed time */
uint32_t elapsed = tcb->premp_start - up_critmon_gettime();
tcb->premp_start = 0;
if (elapsed > tcb->premp_max)
{
tcb->premp_max = elapsed;
}
ENABLE_PREEMPT(tcb);
}
}
/****************************************************************************
* Name: sched_critmon_csection
*
* Description:
* Called when a thread enters or leaves a critical section.
*
* Assumptions:
* Called within a critical section.
*
****************************************************************************/
void sched_critmon_csection(FAR struct tcb_s *tcb, bool state)
{
/* Are we entering or leaving the critical section? */
if (state)
{
/* Entering... Save the start time. */
DEBUGASSERT(tcb->crit_start == 0 && !IN_CSECTION(tcb));
tcb->crit_start = up_critmon_gettime();
}
else if (tcb->crit_start != 0)
{
DEBUGASSERT(IN_CSECTION(tcb));
/* Leaving .. Check for the max elapsed time */
uint32_t elapsed = tcb->crit_start - up_critmon_gettime();
tcb->crit_start = 0;
if (elapsed > tcb->crit_max)
{
tcb->crit_max = elapsed;
}
ENTER_CSECTION(tcb);
}
}
/****************************************************************************
* Name: sched_critmon_resume
*
* Description:
* Called when a thread resumes execution, perhaps re-establishing a
* critical section or a non-pre-emptible state.
*
* Assumptions:
* Called within a critical section.
*
****************************************************************************/
void sched_critmon_resume(FAR struct tcb_s *tcb)
{
DEBUGASSERT(tcb->premp_start == 0 && tcb->crit_start == 0);
/* Did this task disable pre-emption? */
if (PREEMPT_DISABLED(tcb))
{
/* Yes.. Save the start time */
tcb->premp_start = up_critmon_gettime();
}
/* Was this task in a critical section? */
if (IN_CSECTION(tcb))
{
/* Yes.. Save the start time */
tcb->crit_start = up_critmon_gettime();
}
}
/****************************************************************************
* Name: sched_critmon_suspend
*
* Description:
* Called when a thread suspends execution, perhaps terminating a
* critical section or a non-pre-emptible state.
*
* Assumptions:
* Called within a critical section.
*
****************************************************************************/
void sched_critmon_suspend(FAR struct tcb_s *tcb)
{
/* Did this task disable pre-emption? */
if (PREEMPT_DISABLED(tcb))
{
/* Re-enabling.. Check for the max elapsed time */
uint32_t elapsed = tcb->premp_start - up_critmon_gettime();
tcb->premp_start = 0;
if (elapsed > tcb->premp_max)
{
tcb->premp_max = elapsed;
}
}
/* Is this task in a critical section? */
if (IN_CSECTION(tcb))
{
/* Leaving .. Check for the max elapsed time */
uint32_t elapsed = tcb->crit_start - up_critmon_gettime();
tcb->crit_start = 0;
if (elapsed > tcb->crit_max)
{
tcb->crit_max = elapsed;
}
}
}
#endif
+14 -2
View File
@@ -250,14 +250,20 @@ int sched_lock(void)
(void)up_fetchsub16(&g_global_lockcount, 1);
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
#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
sched_critmon_premption(rtcb, true);
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
sched_note_premption(rtcb, true);
#endif
}
#endif
@@ -299,14 +305,20 @@ int sched_lock(void)
rtcb->lockcount++;
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
#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
sched_critmon_premption(rtcb, true);
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
sched_note_premption(rtcb, true);
#endif
}
#endif
}
+10 -5
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* sched/sched/sched_resumescheduler.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2015, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,8 @@
#include "sched/sched.h"
#if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC) || \
defined(CONFIG_SCHED_INSTRUMENTATION) || defined(CONFIG_SMP)
defined(CONFIG_SCHED_INSTRUMENTATION) || defined(CONFIG_SCHED_CRITMONITOR) || \
defined(CONFIG_SMP)
/****************************************************************************
* Public Functions
@@ -96,9 +97,12 @@ void sched_resume_scheduler(FAR struct tcb_s *tcb)
}
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Inidicate the task has been resumed */
/* Indicate the task has been resumed */
#ifdef CONFIG_SCHED_CRITMONITOR
sched_critmon_resume(tcb);
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION
sched_note_resume(tcb);
#endif
@@ -142,4 +146,5 @@ void sched_resume_scheduler(FAR struct tcb_s *tcb)
}
#endif /* CONFIG_RR_INTERVAL > 0 || CONFIG_SCHED_SPORADIC || \
* CONFIG_SCHED_INSTRUMENTATION || CONFIG_SMP */
* CONFIG_SCHED_INSTRUMENTATION || CONFIG_SCHED_CRITMONITOR ||
* CONFIG_SMP */
+10 -5
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* sched/sched/sched_suspendscheduler.c
*
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2015-2016, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -50,7 +50,8 @@
#include "clock/clock.h"
#include "sched/sched.h"
#if defined(CONFIG_SCHED_SPORADIC) || defined(CONFIG_SCHED_INSTRUMENTATION)
#if defined(CONFIG_SCHED_SPORADIC) || defined(CONFIG_SCHED_INSTRUMENTATION) || \
defined(CONFIG_SCHED_CRITMONITOR)
/****************************************************************************
* Public Functions
@@ -83,11 +84,15 @@ void sched_suspend_scheduler(FAR struct tcb_s *tcb)
}
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Inidicate the task has been suspended */
/* Indicate that the task has been suspended */
#ifdef CONFIG_SCHED_CRITMONITOR
sched_critmon_suspend(tcb);
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION
sched_note_suspend(tcb);
#endif
}
#endif /* CONFIG_SCHED_SPORADIC || CONFIG_SCHED_INSTRUMENTATION */
#endif /* CONFIG_SCHED_SPORADIC || CONFIG_SCHED_INSTRUMENTATION ||
* CONFIG_SCHED_CRITMONITOR */
+10 -2
View File
@@ -103,11 +103,15 @@ int sched_unlock(void)
if (rtcb->lockcount <= 0)
{
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
/* Note that we no longer have pre-emption disabled. */
#ifdef CONFIG_SCHED_CRITMONITOR
sched_critmon_premption(rtcb, false);
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
sched_note_premption(rtcb, false);
#endif
/* Set the lock count to zero */
rtcb->lockcount = 0;
@@ -254,11 +258,15 @@ int sched_unlock(void)
if (rtcb->lockcount <= 0)
{
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
/* Note that we no longer have pre-emption disabled. */
#ifdef CONFIG_SCHED_CRITMONITOR
sched_critmon_premption(rtcb, false);
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
sched_note_premption(rtcb, false);
#endif
/* Set the lock count to zero */
rtcb->lockcount = 0;