Sporadic scheduler: Add instrumentation hooks to support GPIO outputs

This commit is contained in:
Gregory Nutt 2015-07-27 08:37:25 -06:00
parent 7c04ad8209
commit 484f148001
8 changed files with 92 additions and 18 deletions

@ -1 +1 @@
Subproject commit 88c720dd2b0641f4fc549d0dac5064bae8b35efe Subproject commit fa79d7e92b5317f239219e9714e0d22806550845

View File

@ -1972,6 +1972,29 @@ int up_getc(void);
void up_puts(FAR const char *str); void up_puts(FAR const char *str);
/********************************************************************************
* Name: arch_sporadic_*
*
* Description:
* Hooks that can be enabled to monitor the behavior of the sporadic
* scheduler. These are call outs from the OS and must be provided by
* architecture-specific logic.
*
* Input Parameters:
* tcb - The TCB of the thread to be restarted.
*
* Returned Value:
* None
*
********************************************************************************/
#ifdef CONFIG_SPORADIC_INSTRUMENTATION
void arch_sporadic_start(FAR struct tcb_s *tcb);
void arch_sporadic_lowpriority(FAR struct tcb_s *tcb);
void arch_sporadic_suspend(FAR struct tcb_s *tcb);
void arch_sporadic_resume(FAR struct tcb_s *tcb);
#endif
#undef EXTERN #undef EXTERN
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -796,7 +796,7 @@ void sched_resume_scheduler(FAR struct tcb_s *tcb);
* Name: sched_suspend_scheduler * Name: sched_suspend_scheduler
* *
* Description: * Description:
* Called by architecture specific implementations the start task execution. * Called by architecture specific implementations to resume task execution.
* This function performs scheduler operations for the thread that is about to * This function performs scheduler operations for the thread that is about to
* be suspended. * be suspended.
* *
@ -808,7 +808,8 @@ void sched_resume_scheduler(FAR struct tcb_s *tcb);
* *
********************************************************************************/ ********************************************************************************/
#if defined(CONFIG_SCHED_SPORADIC) && defined(CONFIG_SCHED_TICKLESS) #if defined(CONFIG_SCHED_SPORADIC) && (defined(CONFIG_SCHED_TICKLESS) || \
defined(CONFIG_SPORADIC_INSTRUMENTATION))
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)

View File

@ -314,15 +314,31 @@ config SCHED_SPORADIC
Build in additional logic to support sporadic scheduling Build in additional logic to support sporadic scheduling
(SCHED_SPORADIC). (SCHED_SPORADIC).
if SCHED_SPORADIC
config SCHED_SPORADIC_MAXREPL config SCHED_SPORADIC_MAXREPL
int "Maximum number of replenishments" int "Maximum number of replenishments"
default 3 default 3
range 1 255 range 1 255
depends on SCHED_SPORADIC
---help--- ---help---
Controls the size of allocated replenishment structures and, hence, Controls the size of allocated replenishment structures and, hence,
also limits the maximum number of replenishments. also limits the maximum number of replenishments.
config SPORADIC_INSTRUMENTATION
bool "Sporadic scheduler monitor hooks"
default n
---help---
Enables instrumentation in the sporadic scheduler to monitor
scheduler behavior. If enabled, then the board-specific logic must
provide the following functions:
void arch_sporadic_start(FAR struct tcb_s *tcb);
void arch_sporadic_lowpriority(FAR struct tcb_s *tcb);
void arch_sporadic_suspend(FAR struct tcb_s *tcb);
void arch_sporadic_resume(FAR struct tcb_s *tcb);
endif # SCHED_SPORADIC
config TASK_NAME_SIZE config TASK_NAME_SIZE
int "Maximum task name size" int "Maximum task name size"
default 31 default 31

View File

@ -60,21 +60,18 @@ endif
ifeq ($(CONFIG_SCHED_SPORADIC),y) ifeq ($(CONFIG_SCHED_SPORADIC),y)
CSRCS += sched_sporadic.c CSRCS += sched_sporadic.c
ifeq ($(CONFIG_SCHED_TICKLESS),y)
CSRCS += sched_suspendscheduler.c
else ifeq ($(CONFIG_SPORADIC_INSTRUMENTATION),y)
CSRCS += sched_suspendscheduler.c
endif
endif endif
ifneq ($(CONFIG_RR_INTERVAL),0) ifneq ($(CONFIG_RR_INTERVAL),0)
CSRCS += sched_resumescheduler.c CSRCS += sched_resumescheduler.c
else else ifeq ($(CONFIG_SCHED_SPORADIC),y)
ifeq ($(CONFIG_SCHED_SPORADIC),y)
CSRCS += sched_resumescheduler.c CSRCS += sched_resumescheduler.c
endif endif
endif
ifeq ($(CONFIG_SCHED_TICKLESS),y)
ifeq ($(CONFIG_SCHED_SPORADIC),y)
CSRCS += sched_suspendscheduler.c
endif
endif
ifeq ($(CONFIG_SCHED_CPULOAD),y) ifeq ($(CONFIG_SCHED_CPULOAD),y)
CSRCS += sched_cpuload.c CSRCS += sched_cpuload.c

View File

@ -251,7 +251,7 @@ int sched_sporadic_start(FAR struct tcb_s *tcb);
int sched_sporadic_stop(FAR struct tcb_s *tcb); int sched_sporadic_stop(FAR struct tcb_s *tcb);
int sched_sporadic_reset(FAR struct tcb_s *tcb); int sched_sporadic_reset(FAR struct tcb_s *tcb);
int sched_sporadic_resume(FAR struct tcb_s *tcb); int sched_sporadic_resume(FAR struct tcb_s *tcb);
#ifdef CONFIG_SCHED_TICKLESS #if defined(CONFIG_SCHED_TICKLESS) || defined(CONFIG_SPORADIC_INSTRUMENTATION)
int sched_sporadic_suspend(FAR struct tcb_s *tcb, int sched_sporadic_suspend(FAR struct tcb_s *tcb,
FAR const struct timespec *suspend_time); FAR const struct timespec *suspend_time);
#endif #endif

View File

@ -46,6 +46,7 @@
#include <errno.h> #include <errno.h>
#include <nuttx/sched.h> #include <nuttx/sched.h>
#include <nuttx/arch.h>
#include <nuttx/wdog.h> #include <nuttx/wdog.h>
#include <nuttx/clock.h> #include <nuttx/clock.h>
@ -110,6 +111,12 @@ static int sporadic_budget_start(FAR struct tcb_s *tcb,
DEBUGASSERT(tcb && tcb->sporadic); DEBUGASSERT(tcb && tcb->sporadic);
sporadic = tcb->sporadic; sporadic = tcb->sporadic;
#ifdef CONFIG_SPORADIC_INSTRUMENTATION
/* Inform the monitor of this event */
arch_sporadic_start(tcb);
#endif
/* Start the next replenishment interval */ /* Start the next replenishment interval */
tcb->timeslice = budget; tcb->timeslice = budget;
@ -260,6 +267,12 @@ static int sporadic_set_lowpriority(FAR struct tcb_s *tcb)
DEBUGASSERT(tcb != NULL && tcb->sporadic != NULL); DEBUGASSERT(tcb != NULL && tcb->sporadic != NULL);
sporadic = tcb->sporadic; sporadic = tcb->sporadic;
#ifdef CONFIG_SPORADIC_INSTRUMENTATION
/* Inform the monitor of this event */
arch_sporadic_lowpriority(tcb);
#endif
#ifdef CONFIG_PRIORITY_INHERITANCE #ifdef CONFIG_PRIORITY_INHERITANCE
/* If the priority was boosted above the higher priority, than just /* If the priority was boosted above the higher priority, than just
* reset the base priority. * reset the base priority.
@ -782,6 +795,12 @@ int sched_sporadic_resume(FAR struct tcb_s *tcb)
DEBUGASSERT(tcb && tcb->sporadic); DEBUGASSERT(tcb && tcb->sporadic);
sporadic = tcb->sporadic; sporadic = tcb->sporadic;
#ifdef CONFIG_SPORADIC_INSTRUMENTATION
/* Inform the monitor of this event */
arch_sporadic_resume(tcb);
#endif
/* Check if are in the budget portion of the replenishment interval. We /* Check if are in the budget portion of the replenishment interval. We
* know this is the case if the current timeslice is non-zero. * know this is the case if the current timeslice is non-zero.
* *
@ -849,17 +868,27 @@ int sched_sporadic_resume(FAR struct tcb_s *tcb)
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_SCHED_TICKLESS #if defined(CONFIG_SCHED_SPORADIC) && (defined(CONFIG_SCHED_TICKLESS) || \
defined(CONFIG_SPORADIC_INSTRUMENTATION))
int sched_sporadic_suspend(FAR struct tcb_s *tcb, int sched_sporadic_suspend(FAR struct tcb_s *tcb,
FAR const struct timespec *suspend_time) FAR const struct timespec *suspend_time)
{ {
#ifdef CONFIG_SCHED_TICKLESS
FAR struct sporadic_s *sporadic; FAR struct sporadic_s *sporadic;
struct timespec elapsed_time; struct timespec elapsed_time;
uint32_t elapsed_ticks; uint32_t elapsed_ticks;
DEBUGASSERT(tcb && tcb->sporadic); DEBUGASSERT(tcb && tcb->sporadic);
sporadic = tcb->sporadic; sporadic = tcb->sporadic;
#endif
#ifdef CONFIG_SPORADIC_INSTRUMENTATION
/* Inform the monitor of this event */
arch_sporadic_suspend(tcb);
#endif
#ifdef CONFIG_SCHED_TICKLESS
/* Check if are in the budget portion of the replenishment interval. We /* Check if are in the budget portion of the replenishment interval. We
* know this is the case if the current timeslice is non-zero. * know this is the case if the current timeslice is non-zero.
* *
@ -912,6 +941,7 @@ int sched_sporadic_suspend(FAR struct tcb_s *tcb,
tcb->timeslice -= (int32_t)elapsed_ticks; tcb->timeslice -= (int32_t)elapsed_ticks;
} }
} }
#endif
return OK; return OK;
} }

View File

@ -49,7 +49,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_TICKLESS) #if defined(CONFIG_SCHED_SPORADIC) && (defined(CONFIG_SCHED_TICKLESS) || \
defined(CONFIG_SPORADIC_INSTRUMENTATION))
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
@ -77,11 +78,17 @@ void sched_suspend_scheduler(FAR struct tcb_s *tcb)
if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC) if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
{ {
#ifdef CONFIG_SCHED_TICKLESS
/* Get the current time when the thread was suspended */ /* Get the current time when the thread was suspended */
(void)up_timer_gettime(&suspend_time); (void)up_timer_gettime(&suspend_time);
#else
suspend_time.tv_sec = 0;
suspend_time.tv_nsec = 0;
#endif
DEBUGVERIFY(sched_sporadic_suspend(tcb, &suspend_time)); DEBUGVERIFY(sched_sporadic_suspend(tcb, &suspend_time));
} }
} }
#endif /* CONFIG_SCHED_SPORADIC && CONFIG_SCHED_TICKLESS */ #endif /* CONFIG_SCHED_SPORADIC && (CONFIG_SCHED_TICKLESS || CONFIG_SPORADIC_INSTRUMENTATION) */