mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 00:14:22 +08:00
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:
+124
-1
@@ -53,6 +53,10 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_CRITMONITOR
|
||||||
|
# include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/sched.h>
|
#include <nuttx/sched.h>
|
||||||
@@ -62,7 +66,7 @@
|
|||||||
#include <nuttx/fs/procfs.h>
|
#include <nuttx/fs/procfs.h>
|
||||||
#include <nuttx/fs/dirent.h>
|
#include <nuttx/fs/dirent.h>
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_CPULOAD
|
#if defined(CONFIG_SCHED_CPULOAD) || defined(CONFIG_SCHED_CRITMONITOR)
|
||||||
# include <nuttx/clock.h>
|
# include <nuttx/clock.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -105,6 +109,9 @@ enum proc_node_e
|
|||||||
PROC_CMDLINE, /* Task command line */
|
PROC_CMDLINE, /* Task command line */
|
||||||
#ifdef CONFIG_SCHED_CPULOAD
|
#ifdef CONFIG_SCHED_CPULOAD
|
||||||
PROC_LOADAVG, /* Average CPU utilization */
|
PROC_LOADAVG, /* Average CPU utilization */
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SCHED_CRITMONITOR
|
||||||
|
PROC_CRITMON, /* Critical section monitor */
|
||||||
#endif
|
#endif
|
||||||
PROC_STACK, /* Task stack info */
|
PROC_STACK, /* Task stack info */
|
||||||
PROC_GROUP, /* Group directory */
|
PROC_GROUP, /* Group directory */
|
||||||
@@ -167,9 +174,24 @@ static FAR const char *g_policy[4] =
|
|||||||
"SCHED_FIFO", "SCHED_RR", "SCHED_SPORADIC", "SCHED_OTHER"
|
"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
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* Helpers */
|
/* Helpers */
|
||||||
|
|
||||||
static FAR const struct proc_node_s *
|
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,
|
FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen,
|
||||||
off_t offset);
|
off_t offset);
|
||||||
#endif
|
#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,
|
static ssize_t proc_stack(FAR struct proc_file_s *procfile,
|
||||||
FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen,
|
FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen,
|
||||||
off_t offset);
|
off_t offset);
|
||||||
@@ -273,6 +300,13 @@ static const struct proc_node_s g_loadavg =
|
|||||||
};
|
};
|
||||||
#endif
|
#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 =
|
static const struct proc_node_s g_stack =
|
||||||
{
|
{
|
||||||
"stack", "stack", (uint8_t)PROC_STACK, DTYPE_FILE /* Task stack info */
|
"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 */
|
&g_cmdline, /* Task command line */
|
||||||
#ifdef CONFIG_SCHED_CPULOAD
|
#ifdef CONFIG_SCHED_CPULOAD
|
||||||
&g_loadavg, /* Average CPU utilization */
|
&g_loadavg, /* Average CPU utilization */
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SCHED_CRITMONITOR
|
||||||
|
&g_critmon, /* Critical section Monitor */
|
||||||
#endif
|
#endif
|
||||||
&g_stack, /* Task stack info */
|
&g_stack, /* Task stack info */
|
||||||
&g_group, /* Group directory */
|
&g_group, /* Group directory */
|
||||||
@@ -329,6 +366,9 @@ static const struct proc_node_s * const g_level0info[] =
|
|||||||
&g_cmdline, /* Task command line */
|
&g_cmdline, /* Task command line */
|
||||||
#ifdef CONFIG_SCHED_CPULOAD
|
#ifdef CONFIG_SCHED_CPULOAD
|
||||||
&g_loadavg, /* Average CPU utilization */
|
&g_loadavg, /* Average CPU utilization */
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SCHED_CRITMONITOR
|
||||||
|
&g_critmon, /* Critical section monitor */
|
||||||
#endif
|
#endif
|
||||||
&g_stack, /* Task stack info */
|
&g_stack, /* Task stack info */
|
||||||
&g_group, /* Group directory */
|
&g_group, /* Group directory */
|
||||||
@@ -743,6 +783,84 @@ static ssize_t proc_loadavg(FAR struct proc_file_s *procfile,
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
* 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 */
|
case PROC_LOADAVG: /* Average CPU utilization */
|
||||||
ret = proc_loadavg(procfile, tcb, buffer, buflen, filep->f_pos);
|
ret = proc_loadavg(procfile, tcb, buffer, buflen, filep->f_pos);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SCHED_CRITMONITOR
|
||||||
|
case PROC_CRITMON: /* Critical section monitor */
|
||||||
|
ret = proc_critmon(procfile, tcb, buffer, buflen, filep->f_pos);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case PROC_STACK: /* Task stack info */
|
case PROC_STACK: /* Task stack info */
|
||||||
ret = proc_stack(procfile, tcb, buffer, buflen, filep->f_pos);
|
ret = proc_stack(procfile, tcb, buffer, buflen, filep->f_pos);
|
||||||
|
|||||||
+6
-3
@@ -1,7 +1,8 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* include/nuttx/irq.h
|
* 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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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);
|
irqstate_t enter_critical_section(void);
|
||||||
#else
|
#else
|
||||||
# define enter_critical_section(f) up_irq_save(f)
|
# 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);
|
void leave_critical_section(irqstate_t flags);
|
||||||
#else
|
#else
|
||||||
# define leave_critical_section(f) up_irq_restore(f)
|
# define leave_critical_section(f) up_irq_restore(f)
|
||||||
|
|||||||
+14
-2
@@ -696,6 +696,16 @@ struct tcb_s
|
|||||||
FAR void *pthread_data[CONFIG_NPTHREAD_KEYS];
|
FAR void *pthread_data[CONFIG_NPTHREAD_KEYS];
|
||||||
#endif
|
#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 *****************************************************/
|
/* Library related fields *****************************************************/
|
||||||
|
|
||||||
int pterrno; /* Current per-thread errno */
|
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) || \
|
#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);
|
void sched_resume_scheduler(FAR struct tcb_s *tcb);
|
||||||
#else
|
#else
|
||||||
# define sched_resume_scheduler(tcb)
|
# 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);
|
void sched_suspend_scheduler(FAR struct tcb_s *tcb);
|
||||||
#else
|
#else
|
||||||
# define sched_suspend_scheduler(tcb)
|
# define sched_suspend_scheduler(tcb)
|
||||||
|
|||||||
@@ -700,6 +700,39 @@ config SCHED_IRQMONITOR
|
|||||||
counts will be available in the mounted procfs file systems at the
|
counts will be available in the mounted procfs file systems at the
|
||||||
top-level file, "irqs".
|
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
|
config SCHED_CPULOAD
|
||||||
bool "Enable CPU load monitoring"
|
bool "Enable CPU load monitoring"
|
||||||
default n
|
default n
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ endif
|
|||||||
endif
|
endif
|
||||||
else ifeq ($(CONFIG_SCHED_INSTRUMENTATION_CSECTION),y)
|
else ifeq ($(CONFIG_SCHED_INSTRUMENTATION_CSECTION),y)
|
||||||
CSRCS += irq_csection.c
|
CSRCS += irq_csection.c
|
||||||
|
else ifeq ($(CONFIG_SCHED_CRITMONITOR),y)
|
||||||
|
CSRCS += irq_csection.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_SCHED_IRQMONITOR),y)
|
ifeq ($(CONFIG_SCHED_IRQMONITOR),y)
|
||||||
|
|||||||
@@ -49,7 +49,8 @@
|
|||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "irq/irq.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
|
* Public Data
|
||||||
@@ -375,9 +376,12 @@ try_again:
|
|||||||
&g_cpu_irqlock);
|
&g_cpu_irqlock);
|
||||||
rtcb->irqcount = 1;
|
rtcb->irqcount = 1;
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
|
|
||||||
/* Note that we have entered the critical section */
|
/* 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);
|
sched_note_csection(rtcb, true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -388,7 +392,8 @@ try_again:
|
|||||||
|
|
||||||
return ret;
|
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 enter_critical_section(void)
|
||||||
{
|
{
|
||||||
irqstate_t ret;
|
irqstate_t ret;
|
||||||
@@ -408,7 +413,12 @@ irqstate_t enter_critical_section(void)
|
|||||||
|
|
||||||
/* Yes.. Note that we have entered the critical section */
|
/* 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);
|
sched_note_csection(rtcb, true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return interrupt status */
|
/* Return interrupt status */
|
||||||
@@ -507,9 +517,12 @@ void leave_critical_section(irqstate_t flags)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
|
|
||||||
/* No.. Note that we have left the critical section */
|
/* 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);
|
sched_note_csection(rtcb, false);
|
||||||
#endif
|
#endif
|
||||||
/* Decrement our count on the lock. If all CPUs have
|
/* 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);
|
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)
|
void leave_critical_section(irqstate_t flags)
|
||||||
{
|
{
|
||||||
/* Check if we were called from an interrupt handler and that the tasks
|
/* 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 */
|
/* 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);
|
sched_note_csection(rtcb, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the previous interrupt state. */
|
/* Restore the previous interrupt state. */
|
||||||
@@ -669,4 +690,5 @@ bool irq_cpu_locked(int cpu)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* CONFIG_SMP || CONFIG_SCHED_INSTRUMENTATION_CSECTION */
|
#endif /* CONFIG_SMP || CONFIG_SCHED_INSTRUMENTATION_CSECTION ||
|
||||||
|
* CONFIG_SCHED_CRITMONITOR */
|
||||||
|
|||||||
+12
-4
@@ -73,6 +73,8 @@ ifeq ($(CONFIG_SCHED_SPORADIC),y)
|
|||||||
CSRCS += sched_sporadic.c sched_suspendscheduler.c
|
CSRCS += sched_sporadic.c sched_suspendscheduler.c
|
||||||
else ifeq ($(CONFIG_SCHED_INSTRUMENTATION),y)
|
else ifeq ($(CONFIG_SCHED_INSTRUMENTATION),y)
|
||||||
CSRCS += sched_suspendscheduler.c
|
CSRCS += sched_suspendscheduler.c
|
||||||
|
else ifeq ($(CONFIG_SCHED_CRITMONITOR),y)
|
||||||
|
CSRCS += sched_suspendscheduler.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(CONFIG_RR_INTERVAL),0)
|
ifneq ($(CONFIG_RR_INTERVAL),0)
|
||||||
@@ -81,6 +83,8 @@ else ifeq ($(CONFIG_SCHED_SPORADIC),y)
|
|||||||
CSRCS += sched_resumescheduler.c
|
CSRCS += sched_resumescheduler.c
|
||||||
else ifeq ($(CONFIG_SCHED_INSTRUMENTATION),y)
|
else ifeq ($(CONFIG_SCHED_INSTRUMENTATION),y)
|
||||||
CSRCS += sched_resumescheduler.c
|
CSRCS += sched_resumescheduler.c
|
||||||
|
else ifeq ($(CONFIG_SCHED_CRITMONITOR),y)
|
||||||
|
CSRCS += sched_resumescheduler.c
|
||||||
else ifeq ($(CONFIG_SMP),y)
|
else ifeq ($(CONFIG_SMP),y)
|
||||||
CSRCS += sched_resumescheduler.c
|
CSRCS += sched_resumescheduler.c
|
||||||
endif
|
endif
|
||||||
@@ -101,10 +105,6 @@ else
|
|||||||
CSRCS += sched_processtimer.c
|
CSRCS += sched_processtimer.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_SCHED_INSTRUMENTATION_BUFFER),y)
|
|
||||||
CSRCS += sched_note.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_SMP),y)
|
ifeq ($(CONFIG_SMP),y)
|
||||||
CSRCS += sched_tasklistlock.c
|
CSRCS += sched_tasklistlock.c
|
||||||
ifeq ($(CONFIG_ARCH_GLOBAL_IRQDISABLE),y)
|
ifeq ($(CONFIG_ARCH_GLOBAL_IRQDISABLE),y)
|
||||||
@@ -114,6 +114,14 @@ CSRCS += sched_thistask.c
|
|||||||
endif
|
endif
|
||||||
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
|
# Include sched build support
|
||||||
|
|
||||||
DEPPATH += --dep-path sched
|
DEPPATH += --dep-path sched
|
||||||
|
|||||||
@@ -496,6 +496,15 @@ void sched_tasklist_unlock(irqstate_t lock);
|
|||||||
void weak_function sched_process_cpuload(void);
|
void weak_function sched_process_cpuload(void);
|
||||||
#endif
|
#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 */
|
/* TCB operations */
|
||||||
|
|
||||||
bool sched_verifytcb(FAR struct tcb_s *tcb);
|
bool sched_verifytcb(FAR struct tcb_s *tcb);
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -250,14 +250,20 @@ int sched_lock(void)
|
|||||||
(void)up_fetchsub16(&g_global_lockcount, 1);
|
(void)up_fetchsub16(&g_global_lockcount, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
|
#if defined(CONFIG_SCHED_INSTRUMENTATION_PREEMPTION) || \
|
||||||
|
defined(CONFIG_SCHED_CRITMONITOR)
|
||||||
/* Check if we just acquired the lock */
|
/* Check if we just acquired the lock */
|
||||||
|
|
||||||
if (rtcb->lockcount == 1)
|
if (rtcb->lockcount == 1)
|
||||||
{
|
{
|
||||||
/* Note that we have pre-emption locked */
|
/* 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);
|
sched_note_premption(rtcb, true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -299,14 +305,20 @@ int sched_lock(void)
|
|||||||
|
|
||||||
rtcb->lockcount++;
|
rtcb->lockcount++;
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
|
#if defined(CONFIG_SCHED_INSTRUMENTATION_PREEMPTION) || \
|
||||||
|
defined(CONFIG_SCHED_CRITMONITOR)
|
||||||
/* Check if we just acquired the lock */
|
/* Check if we just acquired the lock */
|
||||||
|
|
||||||
if (rtcb->lockcount == 1)
|
if (rtcb->lockcount == 1)
|
||||||
{
|
{
|
||||||
/* Note that we have pre-emption locked */
|
/* 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);
|
sched_note_premption(rtcb, true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/sched/sched_resumescheduler.c
|
* 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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -49,7 +49,8 @@
|
|||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
|
|
||||||
#if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC) || \
|
#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
|
* Public Functions
|
||||||
@@ -96,9 +97,12 @@ void sched_resume_scheduler(FAR struct tcb_s *tcb)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
/* Indicate the task has been resumed */
|
||||||
/* Inidicate the task has been resumed */
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_CRITMONITOR
|
||||||
|
sched_critmon_resume(tcb);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
sched_note_resume(tcb);
|
sched_note_resume(tcb);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -142,4 +146,5 @@ void sched_resume_scheduler(FAR struct tcb_s *tcb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_RR_INTERVAL > 0 || CONFIG_SCHED_SPORADIC || \
|
#endif /* CONFIG_RR_INTERVAL > 0 || CONFIG_SCHED_SPORADIC || \
|
||||||
* CONFIG_SCHED_INSTRUMENTATION || CONFIG_SMP */
|
* CONFIG_SCHED_INSTRUMENTATION || CONFIG_SCHED_CRITMONITOR ||
|
||||||
|
* CONFIG_SMP */
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/sched/sched_suspendscheduler.c
|
* 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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -50,7 +50,8 @@
|
|||||||
#include "clock/clock.h"
|
#include "clock/clock.h"
|
||||||
#include "sched/sched.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
|
* Public Functions
|
||||||
@@ -83,11 +84,15 @@ void sched_suspend_scheduler(FAR struct tcb_s *tcb)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
/* Indicate that the task has been suspended */
|
||||||
/* Inidicate the task has been suspended */
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_CRITMONITOR
|
||||||
|
sched_critmon_suspend(tcb);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
sched_note_suspend(tcb);
|
sched_note_suspend(tcb);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_SCHED_SPORADIC || CONFIG_SCHED_INSTRUMENTATION */
|
#endif /* CONFIG_SCHED_SPORADIC || CONFIG_SCHED_INSTRUMENTATION ||
|
||||||
|
* CONFIG_SCHED_CRITMONITOR */
|
||||||
|
|||||||
@@ -103,11 +103,15 @@ int sched_unlock(void)
|
|||||||
|
|
||||||
if (rtcb->lockcount <= 0)
|
if (rtcb->lockcount <= 0)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
|
|
||||||
/* Note that we no longer have pre-emption disabled. */
|
/* 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);
|
sched_note_premption(rtcb, false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set the lock count to zero */
|
/* Set the lock count to zero */
|
||||||
|
|
||||||
rtcb->lockcount = 0;
|
rtcb->lockcount = 0;
|
||||||
@@ -254,11 +258,15 @@ int sched_unlock(void)
|
|||||||
|
|
||||||
if (rtcb->lockcount <= 0)
|
if (rtcb->lockcount <= 0)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
|
|
||||||
/* Note that we no longer have pre-emption disabled. */
|
/* 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);
|
sched_note_premption(rtcb, false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set the lock count to zero */
|
/* Set the lock count to zero */
|
||||||
|
|
||||||
rtcb->lockcount = 0;
|
rtcb->lockcount = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user