This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 4a34293263527b60a0ec112c6ad6bdfd5f7ff43a
Author: yushuailong <[email protected]>
AuthorDate: Mon Sep 7 21:13:10 2026 +0800

    sched: Centralize sporadic parameter validation
    
    Sporadic scheduling parameters are processed independently by 
sched_setparam(), sched_setscheduler(), and pthread_create(). The three paths 
currently validate different subsets of the parameters.
    
    In particular, pthread_create() does not validate sched_ss_max_repl and 
only requires the replenishment period to be greater than the budget, while the 
scheduler interfaces enforce the implementation's 50 percent duty-cycle limit.
    
    Add nxsched_validate_sporadic() to validate the common parameters and 
convert the replenishment period and budget to ticks. Use it from all paths 
that directly initialize or update sporadic scheduler state.
    
    Express the duty-cycle check using division to avoid overflow when doubling 
a clock_t value.
    
    Assisted-by: OpenAI Codex
    Signed-off-by: yushuailong <[email protected]>
---
 sched/pthread/pthread_create.c   | 43 +++++++++---------
 sched/sched/sched.h              |  3 ++
 sched/sched/sched_setparam.c     | 94 ++++++++++++----------------------------
 sched/sched/sched_setscheduler.c | 90 +++++++++++++-------------------------
 sched/sched/sched_sporadic.c     | 65 +++++++++++++++++++++++++++
 5 files changed, 145 insertions(+), 150 deletions(-)

diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c
index 19b43f85895..684495b101c 100644
--- a/sched/pthread/pthread_create.c
+++ b/sched/pthread/pthread_create.c
@@ -189,7 +189,6 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
   struct sched_param param;
   FAR struct tcb_s *parent;
   int policy;
-  int errcode;
   int ret;
 
   DEBUGASSERT(trampoline != NULL);
@@ -238,7 +237,6 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
   ret = addrenv_join(this_task(), ptcb);
   if (ret < 0)
     {
-      errcode = -ret;
       goto errout_with_tcb;
     }
 #endif
@@ -265,7 +263,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
 
   if (ret != OK)
     {
-      errcode = ENOMEM;
+      ret = -ENOMEM;
       goto errout_with_tcb;
     }
 
@@ -275,7 +273,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
   ret = up_addrenv_kstackalloc(ptcb);
   if (ret < 0)
     {
-      errcode = ENOMEM;
+      ret = -ENOMEM;
       goto errout_with_tcb;
     }
 #endif
@@ -294,7 +292,6 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
       ret = nxsched_get_param(0, &param);
       if (ret < 0)
         {
-          errcode = -ret;
           goto errout_with_tcb;
         }
 
@@ -303,7 +300,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
       policy = nxsched_get_scheduler(0);
       if (policy < 0)
         {
-          errcode = -policy;
+          ret = policy;
           goto errout_with_tcb;
         }
     }
@@ -331,24 +328,28 @@ int nx_pthread_create(pthread_trampoline_t trampoline, 
FAR pthread_t *thread,
       clock_t repl_ticks;
       clock_t budget_ticks;
 
-      /* Convert timespec values to system clock ticks */
+      /* Validate the priority before initializing sporadic state */
 
-      repl_ticks = clock_time2ticks(&param.sched_ss_repl_period);
-      budget_ticks = clock_time2ticks(&param.sched_ss_init_budget);
-
-      /* The replenishment period must be greater than or equal to the
-       * budget period.
-       */
-
-      if (repl_ticks < budget_ticks)
+      if (param.sched_priority < SCHED_PRIORITY_MIN ||
+          param.sched_priority > SCHED_PRIORITY_MAX)
         {
-          errcode = EINVAL;
-          goto errout_with_tcb;
+          ret = -EINVAL;
+        }
+      else
+        {
+          /* Validate the sporadic parameters */
+
+          ret = nxsched_validate_sporadic(&param, &repl_ticks,
+                                          &budget_ticks);
         }
 
       /* Initialize the sporadic policy */
 
-      ret = nxsched_initialize_sporadic(ptcb);
+      if (ret >= 0)
+        {
+          ret = nxsched_initialize_sporadic(ptcb);
+        }
+
       if (ret >= 0)
         {
           sporadic               = ptcb->sporadic;
@@ -371,7 +372,6 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
 
       if (ret < 0)
         {
-          errcode = -ret;
           goto errout_with_tcb;
         }
     }
@@ -383,7 +383,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
                                 entry);
   if (ret != OK)
     {
-      errcode = EBUSY;
+      ret = -EBUSY;
       goto errout_with_tcb;
     }
 
@@ -392,7 +392,6 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
   ret = tls_init_info(ptcb);
   if (ret != OK)
     {
-      errcode = -ret;
       goto errout_with_tcb;
     }
 
@@ -465,5 +464,5 @@ errout_with_tcb:
   ptcb->group = NULL;
 
   nxsched_release_tcb(ptcb, TCB_FLAG_TTYPE_PTHREAD);
-  return errcode;
+  return -ret;
 }
diff --git a/sched/sched/sched.h b/sched/sched/sched.h
index f1a8776fcf1..212f379a71c 100644
--- a/sched/sched/sched.h
+++ b/sched/sched/sched.h
@@ -367,6 +367,9 @@ void nxsched_resume_roundrobin(FAR struct tcb_s *tcb);
 #endif
 
 #ifdef CONFIG_SCHED_SPORADIC
+int  nxsched_validate_sporadic(FAR const struct sched_param *param,
+                                FAR clock_t *repl_ticks,
+                                FAR clock_t *budget_ticks);
 int  nxsched_initialize_sporadic(FAR struct tcb_s *tcb);
 int  nxsched_start_sporadic(FAR struct tcb_s *tcb);
 int  nxsched_stop_sporadic(FAR struct tcb_s *tcb);
diff --git a/sched/sched/sched_setparam.c b/sched/sched/sched_setparam.c
index 61e8c7a1b04..d9f031712ca 100644
--- a/sched/sched/sched_setparam.c
+++ b/sched/sched/sched_setparam.c
@@ -35,7 +35,6 @@
 #include <nuttx/irq.h>
 #include <nuttx/arch.h>
 
-#include "clock/clock.h"
 #include "sched/sched.h"
 
 /****************************************************************************
@@ -47,6 +46,9 @@ static inline_function
 int set_sporadic_param(FAR const struct sched_param *param,
                        FAR struct tcb_s *tcb)
 {
+  FAR struct sporadic_s *sporadic;
+  clock_t repl_ticks;
+  clock_t budget_ticks;
   irqstate_t flags;
   int ret = OK;
 
@@ -54,83 +56,41 @@ int set_sporadic_param(FAR const struct sched_param *param,
 
   if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
     {
-      FAR struct sporadic_s *sporadic;
-      clock_t repl_ticks;
-      clock_t budget_ticks;
-
-      if (param->sched_ss_max_repl >= 1 &&
-          param->sched_ss_max_repl <= CONFIG_SCHED_SPORADIC_MAXREPL)
+      ret = nxsched_validate_sporadic(param, &repl_ticks, &budget_ticks);
+      if (ret < 0)
         {
-          /* Convert timespec values to system clock ticks */
-
-          repl_ticks = clock_time2ticks(&param->sched_ss_repl_period);
-          budget_ticks = clock_time2ticks(&param->sched_ss_init_budget);
-
-          /* Avoid zero/negative times */
-
-          if (repl_ticks < 1)
-            {
-              repl_ticks = 1;
-            }
-
-          if (budget_ticks < 1)
-            {
-              budget_ticks = 1;
-            }
+          return ret;
+        }
 
-          /* The replenishment period must be greater than or equal to the
-           * budget period.
-           */
+      /* Stop/reset current sporadic scheduling */
 
-#if 1
-          /* REVISIT: In the current implementation, the budget cannot exceed
-           * half the duty.
+      flags = enter_critical_section();
+      ret = nxsched_reset_sporadic(tcb);
+      if (ret >= 0)
+        {
+          /* Save the sporadic scheduling parameters and reset to the
+           * beginning to the replenishment interval.
            */
 
-          if (repl_ticks >= (2 * budget_ticks))
-#else
-          if (repl_ticks < budget_ticks)
-#endif
-            {
-              /* Stop/reset current sporadic scheduling */
-
-              flags = enter_critical_section();
-              ret = nxsched_reset_sporadic(tcb);
-              if (ret >= 0)
-                {
-                  /* Save the sporadic scheduling parameters and reset to the
-                   * beginning to the replenishment interval.
-                   */
+          tcb->timeslice         = budget_ticks;
 
-                  tcb->timeslice         = budget_ticks;
+          sporadic = tcb->sporadic;
+          DEBUGASSERT(sporadic != NULL);
 
-                  sporadic = tcb->sporadic;
-                  DEBUGASSERT(sporadic != NULL);
+          sporadic->hi_priority  = param->sched_priority;
+          sporadic->low_priority = param->sched_ss_low_priority;
+          sporadic->max_repl     = param->sched_ss_max_repl;
+          sporadic->repl_period  = repl_ticks;
+          sporadic->budget       = budget_ticks;
 
-                  sporadic->hi_priority  = param->sched_priority;
-                  sporadic->low_priority = param->sched_ss_low_priority;
-                  sporadic->max_repl     = param->sched_ss_max_repl;
-                  sporadic->repl_period  = repl_ticks;
-                  sporadic->budget       = budget_ticks;
+          /* And restart at the next replenishment interval */
 
-                  /* And restart at the next replenishment interval */
-
-                  ret = nxsched_start_sporadic(tcb);
-                }
+          ret = nxsched_start_sporadic(tcb);
+        }
 
-              /* Restore interrupts and handle any pending work */
+      /* Restore interrupts and handle any pending work */
 
-              leave_critical_section(flags);
-            }
-          else
-            {
-              ret = -EINVAL;
-            }
-        }
-      else
-        {
-          ret = -EINVAL;
-        }
+      leave_critical_section(flags);
     }
 
   return ret;
diff --git a/sched/sched/sched_setscheduler.c b/sched/sched/sched_setscheduler.c
index c5a7ec74be8..fd6f632657c 100644
--- a/sched/sched/sched_setscheduler.c
+++ b/sched/sched/sched_setscheduler.c
@@ -37,7 +37,6 @@
 #include <nuttx/arch.h>
 
 #include "sched/sched.h"
-#include "clock/clock.h"
 
 /****************************************************************************
  * Private Functions
@@ -51,76 +50,45 @@ int process_sporadic(FAR struct tcb_s *tcb,
   FAR struct sporadic_s *sporadic;
   clock_t repl_ticks;
   clock_t budget_ticks;
-  int ret = -EINVAL;
+  int ret;
 
-  if (param->sched_ss_max_repl >= 1 &&
-      param->sched_ss_max_repl <= CONFIG_SCHED_SPORADIC_MAXREPL)
+  ret = nxsched_validate_sporadic(param, &repl_ticks, &budget_ticks);
+  if (ret < 0)
     {
-      /* Convert timespec values to system clock ticks */
-
-      repl_ticks = clock_time2ticks(&param->sched_ss_repl_period);
-      budget_ticks = clock_time2ticks(&param->sched_ss_init_budget);
-
-      /* Avoid zero/negative times */
-
-      if (repl_ticks < 1)
-        {
-          repl_ticks = 1;
-        }
-
-      if (budget_ticks < 1)
-        {
-          budget_ticks = 1;
-        }
-
-      /* The replenishment period must be greater than or equal to the
-       * budget period.
-       */
-
-#if 1
-      /* REVISIT: In the current implementation, the budget cannot
-       * exceed half the duty.
-       */
+      return ret;
+    }
 
-      if (repl_ticks >= (2 * budget_ticks))
-#else
-      if (repl_ticks < budget_ticks)
-#endif
-        {
-          /* Initialize or reset current sporadic scheduling */
+  /* Initialize or reset current sporadic scheduling */
 
-          if ((tcb->flags & TCB_FLAG_POLICY_MASK) ==
-              TCB_FLAG_SCHED_SPORADIC)
-            {
-              ret = nxsched_reset_sporadic(tcb);
-            }
-          else
-            {
-              ret = nxsched_initialize_sporadic(tcb);
-            }
+  if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
+    {
+      ret = nxsched_reset_sporadic(tcb);
+    }
+  else
+    {
+      ret = nxsched_initialize_sporadic(tcb);
+    }
 
-          /* Save the sporadic scheduling parameters. */
+  /* Save the sporadic scheduling parameters. */
 
-          if (ret >= 0)
-            {
-              tcb->flags            &= ~TCB_FLAG_POLICY_MASK;
-              tcb->flags            |= TCB_FLAG_SCHED_SPORADIC;
-              tcb->timeslice         = budget_ticks;
+  if (ret >= 0)
+    {
+      tcb->flags            &= ~TCB_FLAG_POLICY_MASK;
+      tcb->flags            |= TCB_FLAG_SCHED_SPORADIC;
+      tcb->timeslice         = budget_ticks;
 
-              sporadic               = tcb->sporadic;
-              DEBUGASSERT(sporadic != NULL);
+      sporadic               = tcb->sporadic;
+      DEBUGASSERT(sporadic != NULL);
 
-              sporadic->hi_priority  = param->sched_priority;
-              sporadic->low_priority = param->sched_ss_low_priority;
-              sporadic->max_repl     = param->sched_ss_max_repl;
-              sporadic->repl_period  = repl_ticks;
-              sporadic->budget       = budget_ticks;
+      sporadic->hi_priority  = param->sched_priority;
+      sporadic->low_priority = param->sched_ss_low_priority;
+      sporadic->max_repl     = param->sched_ss_max_repl;
+      sporadic->repl_period  = repl_ticks;
+      sporadic->budget       = budget_ticks;
 
-              /* And restart at the next replenishment interval */
+      /* And restart at the next replenishment interval */
 
-              ret = nxsched_start_sporadic(tcb);
-            }
-        }
+      ret = nxsched_start_sporadic(tcb);
     }
 
   return ret;
diff --git a/sched/sched/sched_sporadic.c b/sched/sched/sched_sporadic.c
index 9991ae3d398..86b0b139574 100644
--- a/sched/sched/sched_sporadic.c
+++ b/sched/sched/sched_sporadic.c
@@ -755,6 +755,71 @@ FAR struct replenishment_s *
  * Public Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: nxsched_validate_sporadic
+ *
+ * Description:
+ *   Validate sporadic scheduling parameters and convert the replenishment
+ *   period and initial budget to system clock ticks.
+ *
+ * Input Parameters:
+ *   param        - Sporadic scheduling parameters to validate.
+ *   repl_ticks   - Location to return the replenishment period in ticks.
+ *   budget_ticks - Location to return the initial budget in ticks.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success.  A negated errno value is returned
+ *   on failure.
+ *
+ ****************************************************************************/
+
+int nxsched_validate_sporadic(FAR const struct sched_param *param,
+                              FAR clock_t *repl_ticks,
+                              FAR clock_t *budget_ticks)
+{
+  clock_t repl;
+  clock_t budget;
+
+  if (param->sched_ss_low_priority < SCHED_PRIORITY_MIN ||
+      param->sched_ss_low_priority > SCHED_PRIORITY_MAX ||
+      param->sched_ss_max_repl < 1 ||
+      param->sched_ss_max_repl > CONFIG_SCHED_SPORADIC_MAXREPL)
+    {
+      return -EINVAL;
+    }
+
+  /* Convert timespec values to system clock ticks */
+
+  repl = clock_time2ticks(&param->sched_ss_repl_period);
+  budget = clock_time2ticks(&param->sched_ss_init_budget);
+
+  /* Avoid zero/negative times */
+
+  if (repl < 1)
+    {
+      repl = 1;
+    }
+
+  if (budget < 1)
+    {
+      budget = 1;
+    }
+
+  /* REVISIT: In the current implementation, the budget cannot exceed
+   * half the replenishment period.  Use division instead of doubling the
+   * budget to avoid signed overflow.
+   */
+
+  if (budget > repl / 2)
+    {
+      return -EINVAL;
+    }
+
+  *repl_ticks = repl;
+  *budget_ticks = budget;
+  return OK;
+}
+
 /****************************************************************************
  * Name: nxsched_initialize_sporadic
  *

Reply via email to