diff --git a/Documentation b/Documentation index 5a5b086ac14..74323b92f29 160000 --- a/Documentation +++ b/Documentation @@ -1 +1 @@ -Subproject commit 5a5b086ac14ebab6619e53e15b8e4801142dec58 +Subproject commit 74323b92f293c18183e61c005a32e48925d73dc3 diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index d838f626820..10821cb983b 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -488,8 +488,10 @@ struct tcb_s #ifdef CONFIG_SCHED_SPORADIC uint8_t hi_priority; /* Sporadic high priority */ uint8_t low_priority; /* Sporadic low priority */ +#ifdef __REVISIT_REPLENISHMENTS uint8_t max_repl; /* Max. replenishments */ uint8_t nrepl; /* Number replenishments remaining */ +#endif #endif uint8_t task_state; /* Current state of the thread */ @@ -506,7 +508,7 @@ struct tcb_s struct wdog_s low_dog; /* Times low-priority interval */ #endif - FAR struct wdog_s *waitdog; /* All timed waits use this wdog */ + FAR struct wdog_s *waitdog; /* All timed waits use this timer */ /* Stack-Related Fields *******************************************************/ diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index 10e284bf38f..df175c7982f 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -337,7 +337,9 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, ptcb->cmn.hi_priority = priority; ptcb->cmn.low_priority = param.sched_ss_low_priority; +#ifdef __REVISIT_REPLENISHMENTS ptcb->cmn.max_repl = param.sched_ss_max_repl; +#endif (void)clock_time2ticks(¶m.sched_ss_repl_period, &ticks); ptcb->cmn.repl_period = ticks; @@ -378,7 +380,9 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, ptcb->cmn.hi_priority = priority; ptcb->cmn.low_priority = attr->low_priority; +#ifdef __REVISIT_REPLENISHMENTS ptcb->cmn.max_repl = attr->max_repl; +#endif ptcb->cmn.repl_period = repl_ticks; ptcb->cmn.budget = budget_ticks; diff --git a/sched/sched/sched_getparam.c b/sched/sched/sched_getparam.c index a715fb74431..82dc406eb2b 100644 --- a/sched/sched/sched_getparam.c +++ b/sched/sched/sched_getparam.c @@ -142,7 +142,11 @@ int sched_getparam (pid_t pid, FAR struct sched_param *param) /* Return parameters associated with SCHED_SPORADIC */ param->sched_ss_low_priority = (int)tcb->low_priority; +#ifdef __REVISIT_REPLENISHMENTS param->sched_ss_max_repl = (int)tcb->max_repl; +#else + param->sched_ss_max_repl = 1; +#endif clock_ticks2time((int)tcb->repl_period, ¶m->sched_ss_repl_period); clock_ticks2time((int)tcb->budget, ¶m->sched_ss_init_budget); diff --git a/sched/sched/sched_setparam.c b/sched/sched/sched_setparam.c index a5a9a88fd2a..e477f05cf89 100644 --- a/sched/sched/sched_setparam.c +++ b/sched/sched/sched_setparam.c @@ -135,7 +135,9 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param) int repl_ticks; int budget_ticks; +#ifdef __REVISIT_REPLENISHMENTS DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX); +#endif /* Convert timespec values to system clock ticks */ @@ -164,7 +166,9 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param) tcb->timeslice = budget_ticks; tcb->hi_priority = param->sched_priority; tcb->low_priority = param->sched_ss_low_priority; +#ifdef __REVISIT_REPLENISHMENTS tcb->max_repl = param->sched_ss_max_repl; +#endif tcb->repl_period = repl_ticks; tcb->budget = budget_ticks; @@ -177,7 +181,9 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param) { tcb->hi_priority = 0; tcb->low_priority = 0; +#ifdef __REVISIT_REPLENISHMENTS tcb->max_repl = 0; +#endif tcb->repl_period = 0; tcb->budget = 0; } diff --git a/sched/sched/sched_setscheduler.c b/sched/sched/sched_setscheduler.c index ed1090bec4f..118f71f2017 100644 --- a/sched/sched/sched_setscheduler.c +++ b/sched/sched/sched_setscheduler.c @@ -178,7 +178,9 @@ int sched_setscheduler(pid_t pid, int policy, int repl_ticks; int budget_ticks; +#ifdef __REVISIT_REPLENISHMENTS DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX); +#endif /* Convert timespec values to system clock ticks */ @@ -207,7 +209,9 @@ int sched_setscheduler(pid_t pid, int policy, tcb->timeslice = budget_ticks; tcb->hi_priority = param->sched_priority; tcb->low_priority = param->sched_ss_low_priority; +#ifdef __REVISIT_REPLENISHMENTS tcb->max_repl = param->sched_ss_max_repl; +#endif tcb->repl_period = repl_ticks; tcb->budget = budget_ticks; diff --git a/sched/sched/sched_sporadic.c b/sched/sched/sched_sporadic.c index 02f30a7aade..8982817e6f4 100644 --- a/sched/sched/sched_sporadic.c +++ b/sched/sched/sched_sporadic.c @@ -91,7 +91,9 @@ static int sched_sporadic_replenish_start(FAR struct tcb_s *tcb) /* Start the next replenishment interval */ tcb->timeslice = tcb->budget; +#ifdef __REVISIT_REPLENISHMENTS tcb->nrepl = tcb->max_repl; +#endif #ifdef CONFIG_PRIORITY_INHERITANCE /* If the priority was boosted above the higher priority, than just @@ -249,8 +251,10 @@ int sched_sporadic_stop(FAR struct tcb_s *tcb) tcb->hi_priority = 0; tcb->low_priority = 0; +#ifdef __REVISIT_REPLENISHMENTS tcb->max_repl = 0; tcb->nrepl = 0; +#endif tcb->timeslice = 0; tcb->repl_period = 0; tcb->budget = 0; @@ -287,6 +291,15 @@ int sched_sporadic_resume(FAR struct tcb_s *tcb) { DEBUGASSERT(tcb); + /* REVISIT: This logic is wrong. In order to correctly implement + * replenishments, we would need to add: (1) logic to keep more + * accurate accounting of the expended budget execution time, and (2) + * multiple timers to handle the nested replenishment intervals. + * + * The logic here works as is but effective max_repl == 1. + */ + +#ifdef __REVISIT_REPLENISHMENTS /* Make sure that we are in the budget portion of the replenishment * interval. We know this is the case if the current timeslice is * non-zero. Do not exceed the maximum number of replenishments. @@ -297,6 +310,7 @@ int sched_sporadic_resume(FAR struct tcb_s *tcb) tcb->timeslice = tcb->budget; tcb->nrepl--; } +#endif return OK; } diff --git a/sched/sched/sched_timerexpiration.c b/sched/sched/sched_timerexpiration.c index 8393be3e83e..c078328d8cb 100644 --- a/sched/sched/sched_timerexpiration.c +++ b/sched/sched/sched_timerexpiration.c @@ -284,6 +284,8 @@ static inline uint32_t sched_process_scheduler(uint32_t ticks, bool noswitches) if (rtcb != ntcb) { + /* Recurse just to get the correct return value */ + return sched_process_scheduler(0, true); } @@ -657,7 +659,7 @@ void sched_timer_resume(void) * * The kludge/work-around is simple to keep the timer running all of the * time with an interval of no more than the timeslice interval. If we - * this, then there is really no need to do anything when on context + * do this, then there is really no need to do anything on context * switches. * * Input Parameters: