From 484f1480017b4a44bde7bf267f10b43e31b81d96 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 27 Jul 2015 08:37:25 -0600 Subject: [PATCH] Sporadic scheduler: Add instrumentation hooks to support GPIO outputs --- configs | 2 +- include/nuttx/arch.h | 23 ++++++++++++++++++++ include/nuttx/sched.h | 5 +++-- sched/Kconfig | 18 +++++++++++++++- sched/sched/Make.defs | 15 ++++++------- sched/sched/sched.h | 2 +- sched/sched/sched_sporadic.c | 32 +++++++++++++++++++++++++++- sched/sched/sched_suspendscheduler.c | 13 ++++++++--- 8 files changed, 92 insertions(+), 18 deletions(-) diff --git a/configs b/configs index 88c720dd2b..fa79d7e92b 160000 --- a/configs +++ b/configs @@ -1 +1 @@ -Subproject commit 88c720dd2b0641f4fc549d0dac5064bae8b35efe +Subproject commit fa79d7e92b5317f239219e9714e0d22806550845 diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index d27de8953f..5f615cd51e 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -1972,6 +1972,29 @@ int up_getc(void); 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 #ifdef __cplusplus } diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 8c4918b6a8..91ec0da0be 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -796,7 +796,7 @@ void sched_resume_scheduler(FAR struct tcb_s *tcb); * Name: sched_suspend_scheduler * * 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 * 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); #else # define sched_suspend_scheduler(tcb) diff --git a/sched/Kconfig b/sched/Kconfig index 6128057996..be15080ea4 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -314,15 +314,31 @@ config SCHED_SPORADIC Build in additional logic to support sporadic scheduling (SCHED_SPORADIC). +if SCHED_SPORADIC + config SCHED_SPORADIC_MAXREPL int "Maximum number of replenishments" default 3 range 1 255 - depends on SCHED_SPORADIC ---help--- Controls the size of allocated replenishment structures and, hence, 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 int "Maximum task name size" default 31 diff --git a/sched/sched/Make.defs b/sched/sched/Make.defs index 2439c8b8a9..c3e4742c92 100644 --- a/sched/sched/Make.defs +++ b/sched/sched/Make.defs @@ -60,21 +60,18 @@ endif ifeq ($(CONFIG_SCHED_SPORADIC),y) 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 ifneq ($(CONFIG_RR_INTERVAL),0) CSRCS += sched_resumescheduler.c -else -ifeq ($(CONFIG_SCHED_SPORADIC),y) +else ifeq ($(CONFIG_SCHED_SPORADIC),y) CSRCS += sched_resumescheduler.c endif -endif - -ifeq ($(CONFIG_SCHED_TICKLESS),y) -ifeq ($(CONFIG_SCHED_SPORADIC),y) -CSRCS += sched_suspendscheduler.c -endif -endif ifeq ($(CONFIG_SCHED_CPULOAD),y) CSRCS += sched_cpuload.c diff --git a/sched/sched/sched.h b/sched/sched/sched.h index 3df2808524..59e62716f8 100644 --- a/sched/sched/sched.h +++ b/sched/sched/sched.h @@ -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_reset(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, FAR const struct timespec *suspend_time); #endif diff --git a/sched/sched/sched_sporadic.c b/sched/sched/sched_sporadic.c index 31280521da..bbe61d0abb 100644 --- a/sched/sched/sched_sporadic.c +++ b/sched/sched/sched_sporadic.c @@ -46,6 +46,7 @@ #include #include +#include #include #include @@ -110,6 +111,12 @@ static int sporadic_budget_start(FAR struct tcb_s *tcb, DEBUGASSERT(tcb && 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 */ tcb->timeslice = budget; @@ -260,6 +267,12 @@ static int sporadic_set_lowpriority(FAR struct tcb_s *tcb) DEBUGASSERT(tcb != NULL && tcb->sporadic != NULL); sporadic = tcb->sporadic; +#ifdef CONFIG_SPORADIC_INSTRUMENTATION + /* Inform the monitor of this event */ + + arch_sporadic_lowpriority(tcb); +#endif + #ifdef CONFIG_PRIORITY_INHERITANCE /* If the priority was boosted above the higher priority, than just * reset the base priority. @@ -782,6 +795,12 @@ int sched_sporadic_resume(FAR struct tcb_s *tcb) DEBUGASSERT(tcb && 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 * 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, FAR const struct timespec *suspend_time) { +#ifdef CONFIG_SCHED_TICKLESS FAR struct sporadic_s *sporadic; struct timespec elapsed_time; uint32_t elapsed_ticks; DEBUGASSERT(tcb && 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 * 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; } } +#endif return OK; } diff --git a/sched/sched/sched_suspendscheduler.c b/sched/sched/sched_suspendscheduler.c index e811649deb..d4cf1803f5 100644 --- a/sched/sched/sched_suspendscheduler.c +++ b/sched/sched/sched_suspendscheduler.c @@ -49,7 +49,8 @@ #include "clock/clock.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 @@ -77,11 +78,17 @@ void sched_suspend_scheduler(FAR struct tcb_s *tcb) if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC) { - /* Get the current time when the thread was suspended */ +#ifdef CONFIG_SCHED_TICKLESS + /* Get the current time when the thread was suspended */ (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)); } } -#endif /* CONFIG_SCHED_SPORADIC && CONFIG_SCHED_TICKLESS */ +#endif /* CONFIG_SCHED_SPORADIC && (CONFIG_SCHED_TICKLESS || CONFIG_SPORADIC_INSTRUMENTATION) */