diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index 86e3dd8d8d636a30ed762a59fdf3d0919f641164..9cea2af0e82488ecb93f17279d02b5e6b1c362ec 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -227,9 +227,6 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, { FAR struct pthread_tcb_s *ptcb; FAR struct join_s *pjoin; -#ifdef CONFIG_SCHED_SPORADIC - int ticks; -#endif int priority; int policy; int errcode; @@ -308,6 +305,9 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, if (attr->inheritsched == PTHREAD_INHERIT_SCHED) { struct sched_param param; +#ifdef CONFIG_SCHED_SPORADIC + int ticks; +#endif /* Get the priority (and any other scheduling parameters) for this * thread. @@ -352,16 +352,42 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, policy = attr->policy; #ifdef CONFIG_SCHED_SPORADIC - /* Save the sporadic scheduling parameters */ + if (policy == SCHED_SPORADIC) + { + int repl_ticks; + int budget_ticks; - ptcb->cmn.low_priority = attr->low_priority; - ptcb->cmn.max_repl = attr->max_repl; + /* Convert timespec values to system clock ticks */ - (void)clock_time2ticks(&attr->repl_period, &ticks); - ptcb->cmn.repl_period = ticks; + (void)clock_time2ticks(&attr->repl_period, &repl_ticks); + (void)clock_time2ticks(&attr->budget, &budget_ticks); - (void)clock_time2ticks(&attr->budget, &ticks); - ptcb->cmn.budget = ticks; + /* The replenishment period must be greater than or equal to the + * budget period. + */ + + if (repl_ticks < budget_ticks) + { + errcode = EINVAL; + goto errout_with_join; + } + + /* Save the sporadic scheduling parameters */ + + ptcb->cmn.low_priority = attr->low_priority; + ptcb->cmn.max_repl = attr->max_repl; + ptcb->cmn.repl_period = repl_ticks; + ptcb->cmn.budget = budget_ticks; + } + else + { + /* Ignore sporadic scheduling parameters */ + + ptcb->cmn.low_priority = 0; + ptcb->cmn.max_repl = 0; + ptcb->cmn.repl_period = 0; + ptcb->cmn.budget = 0; + } #endif } diff --git a/sched/sched/sched_setparam.c b/sched/sched/sched_setparam.c index e75980c3b59169a32f83639db3501cf7383208f1..f7f193cdcf9c76bd2fff4dff7718d28dbd16a179 100644 --- a/sched/sched/sched_setparam.c +++ b/sched/sched/sched_setparam.c @@ -86,14 +86,15 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param) { FAR struct tcb_s *rtcb; FAR struct tcb_s *tcb; + int errcode; int ret; /* Verify that the requested priority is in the valid range */ if (!param) { - set_errno(EINVAL); - return ERROR; + errcode = EINVAL; + goto errout_with_errcode; } /* Prohibit modifications to the head of the ready-to-run task @@ -110,18 +111,17 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param) tcb = rtcb; } - /* The pid is not the calling task, we will have to search for it */ + /* The PID is not the calling task, we will have to search for it */ else { tcb = sched_gettcb(pid); if (!tcb) { - /* No task with this pid was found */ + /* No task with this PID was found */ - set_errno(ESRCH); - sched_unlock(); - return ERROR; + errcode = ESRCH; + goto errout_with_lock; } } @@ -130,20 +130,34 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param) if ((rtcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC) { - int ticks; + int repl_ticks; + int budget_ticks; DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX); + /* Convert timespec values to system clock ticks */ + + (void)clock_time2ticks(¶m->sched_ss_repl_period, &repl_ticks); + (void)clock_time2ticks(¶m->sched_ss_init_budget, &budget_ticks); + + /* The replenishment period must be greater than or equal to the + * budget period. + */ + + if (repl_ticks < budget_ticks) + { + errcode = EINVAL; + goto errout_with_lock; + } + + /* Save the sporadic scheduling parameters */ + tcb->flags |= TCB_FLAG_SCHED_SPORADIC; tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); tcb->low_priority = param->sched_ss_low_priority; tcb->max_repl = param->sched_ss_max_repl; - - (void)clock_time2ticks(¶m->sched_ss_repl_period, &ticks); - tcb->repl_period = ticks; - - (void)clock_time2ticks(¶m->sched_ss_init_budget, &ticks); - tcb->budget = ticks; + tcb->repl_period = repl_ticks; + tcb->budget = budget_ticks; } else { @@ -154,9 +168,18 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param) } #endif - /* Then perform the reprioritization */ + /* Then perform the reprioritization */ + + ret = sched_reprioritize(tcb, param->sched_priority); + sched_unlock(); + return ret; + +errout_with_lock: + set_errno(errcode); + sched_unlock(); + return ERROR; - ret = sched_reprioritize(tcb, param->sched_priority); - sched_unlock(); - return ret; +errout_with_errcode: + set_errno(errcode); + return ERROR; } diff --git a/sched/sched/sched_setscheduler.c b/sched/sched/sched_setscheduler.c index f05fb39bc79d7df32b0c31c8ec9af9a6083c1946..0c3c6a6f947afe01c0c6b01f9da9e415b1e1c9df 100644 --- a/sched/sched/sched_setscheduler.c +++ b/sched/sched/sched_setscheduler.c @@ -166,20 +166,35 @@ int sched_setscheduler(pid_t pid, int policy, #ifdef CONFIG_SCHED_SPORADIC case SCHED_SPORADIC: { - int ticks; + int repl_ticks; + int budget_ticks; DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX); + /* Convert timespec values to system clock ticks */ + + (void)clock_time2ticks(¶m->sched_ss_repl_period, &repl_ticks); + (void)clock_time2ticks(¶m->sched_ss_init_budget, &budget_ticks); + + /* The replenishment period must be greater than or equal to the + * budget period. + */ + + if (repl_ticks < budget_ticks) + { + set_errno(EINVAL); + sched_unlock(); + return ERROR; + } + + /* Save the sporadic scheduling parameters */ + tcb->flags |= TCB_FLAG_SCHED_SPORADIC; tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); tcb->low_priority = param->sched_ss_low_priority; tcb->max_repl = param->sched_ss_max_repl; - - (void)clock_time2ticks(¶m->sched_ss_repl_period, &ticks); - tcb->repl_period = ticks; - - (void)clock_time2ticks(¶m->sched_ss_init_budget, &ticks); - tcb->budget = ticks; + tcb->repl_period = repl_ticks; + tcb->budget = budget_ticks; } break; #endif @@ -197,13 +212,5 @@ int sched_setscheduler(pid_t pid, int policy, ret = sched_reprioritize(tcb, param->sched_priority); sched_unlock(); - - if (ret != OK) - { - return ERROR; - } - else - { - return OK; - } + return (ret >= 0) ? OK : ERROR; }