diff --git a/TODO b/TODO
index c46328f076df3d5e6bdae78e9b0c5e167ad352b6..17f0905874a5cc8f5842672bcde21912def82a0d 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-NuttX TODO List (Last updated July 14, 2015)
+NuttX TODO List (Last updated July 25, 2015)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 This file summarizes known NuttX bugs, limitations, inconsistencies with
@@ -9,7 +9,7 @@ issues reated to each board port.
 
 nuttx/
 
- (11)  Task/Scheduler (sched/)
+ (12)  Task/Scheduler (sched/)
   (1)  Memory Management (mm/)
   (3)  Signals (sched/signal, arch/)
   (2)  pthreads (sched/pthread)
@@ -213,6 +213,22 @@ o Task/Scheduler (sched/)
   Status:      Open
   Priority:    Medium-ish
 
+  Title:       TICKLESS SCHEDULING INACCURACIES
+  Description: Interval timers are set up to determine timing for round-
+               robin and sporadic scheduling policies.  In the timer
+               interrupt mode, the budget remaining for the thread is
+               decremented on each timer interrupt and so is always
+               accurate to within one clock time.  So when the task
+               suspended, the remaining budget is accurate.
+
+               But in tickless mode, the budget is only updated on the
+               expiration of the timer.  So if the task is suspended by an
+               asynchronous event, the budget will fail to decrement and the
+               task will get a larger share of CPU that is deserves in those
+               cases.
+  Status:      Open
+  Priority:    Low.  I am not aware of any real world issues.
+
 o Memory Managment (mm/)
   ^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index 10821cb983bd22bee8c07bc75f82f6ec3ac410a4..74a44d3fe0171953bab58af30b27c009116f7c46 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -116,6 +116,12 @@
 #  undef HAVE_GROUP_MEMBERS
 #endif
 
+/* Sporadic scheduling */
+
+#ifndef CONFIG_SCHED_SPORADIC_MAXREPL
+#  define CONFIG_SCHED_SPORADIC_MAXREPL 3
+#endif
+
 /* Task Management Definitions **************************************************/
 /* Special task IDS.  Any negative PID is invalid. */
 
@@ -234,10 +240,49 @@ typedef CODE void (*atexitfunc_t)(void);
 typedef CODE void (*onexitfunc_t)(int exitcode, FAR void *arg);
 #endif
 
+/* struct sporadic_s *************************************************************/
+
+#ifdef CONFIG_SCHED_SPORADIC
+
+/* This structure represents oen replenishment interval.  This is what is
+ * received by each timeout handler.
+ */
+
+struct sporadic_s;
+struct replenishment_s
+{
+  FAR struct tcb_s *tcb;            /* The parent TCB structure                 */
+  struct wdog_s timer;              /* Timer dedicated to this interval         */
+  bool active;                      /* True: replenishment instance is busy     */
+};
+
+/* This structure is an allocated "plug-in" to the main TCB structure.  It is
+ * allocated when the sporadic scheduling policy is assigned to a thread.  Thus,
+ * in the context of numerous threads of varying policies, there the overhead
+ * from this significant allocation is only borne by the threads with the
+ * sporadic scheduling policy.
+ */
+
+struct sporadic_s
+{
+  uint8_t  hi_priority;             /* Sporadic high priority                   */
+  uint8_t  low_priority;            /* Sporadic low priority                    */
+  uint8_t  max_repl;                /* Maximum number of replenishments         */
+  uint8_t  nrepls;                  /* Number of active replenishments          */
+  uint32_t repl_period;             /* Sporadic replenishment period            */
+  uint32_t budget;                  /* Sporadic execution budget period         */
+  uint32_t pending;                 /* Unrealized, pending execution time       */
+
+  /* This is the list of replenishment intervals */
+
+  struct replenishment_s replenishments[CONFIG_SCHED_SPORADIC_MAXREPL];
+};
+
+#endif /* CONFIG_SCHED_SPORADIC */
+
 /* struct child_status_s *********************************************************/
-/* This structure is used to maintin information about child tasks.
- * pthreads work differently, they have join information.  This is
- * only for child tasks.
+/* This structure is used to maintain information about child tasks.  pthreads
+ * work differently, they have join information.  This is only for child tasks.
  */
 
 #ifdef CONFIG_SCHED_CHILD_STATUS
@@ -245,9 +290,9 @@ struct child_status_s
 {
   FAR struct child_status_s *flink;
 
-  uint8_t ch_flags;           /* Child status:  See CHILD_FLAG_* definitions */
-  pid_t   ch_pid;             /* Child task ID */
-  int     ch_status;          /* Child exit status */
+  uint8_t ch_flags;                 /* Child status:  See CHILD_FLAG_* defns     */
+  pid_t   ch_pid;                   /* Child task ID                             */
+  int     ch_status;                /* Child exit status                         */
 };
 #endif
 
@@ -478,20 +523,12 @@ struct tcb_s
   entry_t  entry;                        /* Entry Point into the thread         */
   uint8_t  sched_priority;               /* Current priority of the thread      */
 
-#if defined(CONFIG_PRIORITY_INHERITANCE) && CONFIG_PRIORITY_INHERITANCE > 0
+#ifdef CONFIG_PRIORITY_INHERITANCE
+#if CONFIG_SEM_NNESTPRIO > 0
   uint8_t  npend_reprio;                 /* Number of nested reprioritizations  */
   uint8_t  pend_reprios[CONFIG_SEM_NNESTPRIO];
 #endif
-#if defined(CONFIG_PRIORITY_INHERITANCE) || defined(CONFIG_SCHED_SPORADIC)
   uint8_t  base_priority;                /* "Normal" priority of the thread     */
-#endif
-#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         */
@@ -503,9 +540,7 @@ struct tcb_s
                                          /* interval remaining                  */
 #endif
 #ifdef CONFIG_SCHED_SPORADIC
-  uint32_t repl_period;                  /* Sporadic replenishment period       */
-  uint32_t budget;                       /* Sporadic execution budget           */
-  struct wdog_s low_dog;                 /* Times low-priority interval         */
+  FAR struct sporadic_s *sporadic;       /* Sporadic scheduling parameters      */
 #endif
 
   FAR struct wdog_s *waitdog;            /* All timed waits use this timer      */
diff --git a/sched/Kconfig b/sched/Kconfig
index a94f2fa307153a156f3907e4dba3b1cab1310237..6128057996c187bb656a9ca3926bdea4128ce38e 100644
--- a/sched/Kconfig
+++ b/sched/Kconfig
@@ -311,7 +311,17 @@ config SCHED_SPORADIC
 	bool "Support sporadic scheduling"
 	default n
 	---help---
-		Build in additional logic to support sporadic scheduling (SCHED_SPORADIC).
+		Build in additional logic to support sporadic scheduling
+		(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 TASK_NAME_SIZE
 	int "Maximum task name size"
diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c
index df175c7982ffe282395a80a3d925001df5d3586b..b5df6364c70a714c94b83d6ecec8689657c8e5e9 100644
--- a/sched/pthread/pthread_create.c
+++ b/sched/pthread/pthread_create.c
@@ -228,7 +228,7 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
 {
   FAR struct pthread_tcb_s *ptcb;
   FAR struct join_s *pjoin;
-  int priority;
+  struct sched_param param;
   int policy;
   int errcode;
   pid_t pid;
@@ -298,18 +298,13 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
       goto errout_with_join;
     }
 
-  /* Should we use the priority and scheduler specified in the
-   * pthread attributes?  Or should we use the current thread's
-   * priority and scheduler?
+  /* Should we use the priority and scheduler specified in the pthread
+   * attributes?  Or should we use the current thread's priority and
+   * scheduler?
    */
 
   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.
        */
@@ -321,8 +316,6 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
           goto errout_with_join;
         }
 
-      priority = param.sched_priority;
-
       /* Get the scheduler policy for this thread */
 
       policy = sched_getscheduler(0);
@@ -331,71 +324,81 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
           errcode = get_errno();
           goto errout_with_join;
         }
+    }
+  else
+    {
+      /* Use the scheduler policy and policy the attributes */
 
-#ifdef CONFIG_SCHED_SPORADIC
-      /* Save the sporadic scheduling parameters */
-
-      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(&param.sched_ss_repl_period, &ticks);
-      ptcb->cmn.repl_period  = ticks;
+      policy                             = attr->policy;
+      param.sched_priority               = attr->priority;
 
-      (void)clock_time2ticks(&param.sched_ss_init_budget, &ticks);
-      ptcb->cmn.budget       = ticks;
+#ifdef CONFIG_SCHED_SPORADIC
+      param.sched_ss_low_priority        = attr->low_priority;
+      param.sched_ss_max_repl            = attr->max_repl;
+      param.sched_ss_repl_period.tv_sec  = attr->repl_period.tv_sec;
+      param.sched_ss_repl_period.tv_nsec = attr->repl_period.tv_nsec;
+      param.sched_ss_init_budget.tv_sec  = attr->budget.tv_sec;
+      param.sched_ss_init_budget.tv_nsec = attr->budget.tv_nsec;
 #endif
     }
-  else
+
+#ifdef CONFIG_SCHED_SPORADIC
+  if (policy == SCHED_SPORADIC)
     {
-      /* Use the priority and scheduler from the attributes */
+      FAR struct sporadic_s *sporadic;
+      int repl_ticks;
+      int budget_ticks;
 
-      priority = attr->priority;
-      policy   = attr->policy;
+      /* Convert timespec values to system clock ticks */
 
-#ifdef CONFIG_SCHED_SPORADIC
-      if (policy == SCHED_SPORADIC)
-        {
-          int repl_ticks;
-          int budget_ticks;
+      (void)clock_time2ticks(&param.sched_ss_repl_period, &repl_ticks);
+      (void)clock_time2ticks(&param.sched_ss_init_budget, &budget_ticks);
 
-          /* Convert timespec values to system clock ticks */
+      /* The replenishment period must be greater than or equal to the
+       * budget period.
+       */
 
-          (void)clock_time2ticks(&attr->repl_period, &repl_ticks);
-          (void)clock_time2ticks(&attr->budget, &budget_ticks);
+      if (repl_ticks < budget_ticks)
+        {
+          errcode = EINVAL;
+          goto errout_with_join;
+        }
 
-          /* The replenishment period must be greater than or equal to the
-           * budget period.
-           */
+      /* Initialize the sporadic policy */
 
-          if (repl_ticks < budget_ticks)
-            {
-              errcode = EINVAL;
-              goto errout_with_join;
-            }
+      ret = sched_sporadic_initialize(&ptcb->cmn);
+      if (ret >= 0)
+        {
+          sporadic               = ptcb->cmn.sporadic;
+          DEBUGASSERT(sporadic != NULL);
 
           /* Save the sporadic scheduling parameters */
 
-          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;
+          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 start the frist replenishment interval */
+          /* And start the first replenishment interval */
 
-          DEBUGVERIFY(sched_sporadic_start(&ptcb->cmn));
+          ret = sched_sporadic_start(&ptcb->cmn);
+        }
+
+      /* Handle any failures */
+
+      if (ret < 0)
+        {
+          errcode = -ret;
+          goto errout_with_join;
         }
-#endif
     }
+#endif
 
   /* Initialize the task control block */
 
-  ret = pthread_schedsetup(ptcb, priority, pthread_start, start_routine);
+  ret = pthread_schedsetup(ptcb, param.sched_priority, pthread_start,
+                           start_routine);
   if (ret != OK)
     {
       errcode = EBUSY;
diff --git a/sched/sched/sched.h b/sched/sched/sched.h
index ca83dcfe049a1b3ad356f26bf118032a5c10184a..95595b5bcb4b4f6753607bbb4ebe1c0c7c28fee7 100644
--- a/sched/sched/sched.h
+++ b/sched/sched/sched.h
@@ -246,9 +246,11 @@ uint32_t sched_roundrobin_process(FAR struct tcb_s *tcb, uint32_t ticks,
 #endif
 
 #ifdef CONFIG_SCHED_SPORADIC
-int sched_sporadic_start(FAR struct tcb_s *tcb);
-int sched_sporadic_stop(FAR struct tcb_s *tcb);
-int sched_sporadic_resume(FAR struct tcb_s *tcb);
+int  sched_sporadic_initialize(FAR struct tcb_s *tcb);
+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);
 uint32_t sched_sporadic_process(FAR struct tcb_s *tcb, uint32_t ticks,
                                 bool noswitches);
 void sched_sporadic_lowpriority(FAR struct tcb_s *tcb);
diff --git a/sched/sched/sched_getparam.c b/sched/sched/sched_getparam.c
index 82dc406eb2b628080018542d8a78bffe3ea5891f..b42c8316033e8a51988c013fd40b406ff3c22d5f 100644
--- a/sched/sched/sched_getparam.c
+++ b/sched/sched/sched_getparam.c
@@ -134,22 +134,35 @@ int sched_getparam (pid_t pid, FAR struct sched_param *param)
         }
       else
         {
+#ifdef CONFIG_SCHED_SPORADIC
+#endif
           /* Return the priority of the task */
 
           param->sched_priority = (int)tcb->sched_priority;
 
 #ifdef CONFIG_SCHED_SPORADIC
-          /* 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, &param->sched_ss_repl_period);
-          clock_ticks2time((int)tcb->budget, &param->sched_ss_init_budget);
+          if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
+            {
+              FAR struct sporadic_s *sporadic = tcb->sporadic;
+              DEBUGASSERT(sporadic != NULL);
+
+              /* Return parameters associated with SCHED_SPORADIC */
+
+              param->sched_ss_low_priority = (int)sporadic->low_priority;
+              param->sched_ss_max_repl     = (int)sporadic->max_repl;
+
+              clock_ticks2time((int)sporadic->repl_period, &param->sched_ss_repl_period);
+              clock_ticks2time((int)sporadic->budget, &param->sched_ss_init_budget);
+            }
+          else
+            {
+              param->sched_ss_low_priority        = 0;
+              param->sched_ss_max_repl            = 0;
+              param->sched_ss_repl_period.tv_sec  = 0;
+              param->sched_ss_repl_period.tv_nsec = 0;
+              param->sched_ss_init_budget.tv_sec  = 0;
+              param->sched_ss_init_budget.tv_nsec = 0;
+            }
 #endif
         }
 
diff --git a/sched/sched/sched_setparam.c b/sched/sched/sched_setparam.c
index e477f05cf8938736c88c8ed5b998329b9aa6320c..42bfe06303d550ce7e85ffc292889b4eda1e1f35 100644
--- a/sched/sched/sched_setparam.c
+++ b/sched/sched/sched_setparam.c
@@ -131,19 +131,35 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param)
 
   if ((rtcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
     {
+      FAR struct sporadic_s *sporadic;
       irqstate_t flags;
       int repl_ticks;
       int budget_ticks;
 
-#ifdef __REVISIT_REPLENISHMENTS
-      DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX);
-#endif
+      if (param->sched_ss_max_repl < 1 ||
+          param->sched_ss_max_repl > CONFIG_SCHED_SPORADIC_MAXREPL)
+        {
+          errcode = EINVAL;
+          goto errout_with_lock;
+        }
 
       /* Convert timespec values to system clock ticks */
 
       (void)clock_time2ticks(&param->sched_ss_repl_period, &repl_ticks);
       (void)clock_time2ticks(&param->sched_ss_init_budget, &budget_ticks);
 
+      /* 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.
        */
@@ -157,35 +173,37 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param)
       /* Stop/reset current sporadic scheduling */
 
       flags = irqsave();
-      DEBUGVERIFY(sched_sporadic_stop(tcb));
+      ret = sched_sporadic_reset(tcb);
+      if (ret >= 0)
+        {
+          /* Save the sporadic scheduling parameters and reset to the
+           * beginning to the replenishment interval.
+           */
 
-      /* Save the sporadic scheduling parameters and reset to the beginning
-       * to the replenishment interval.
-       */
+          tcb->timeslice         = budget_ticks;
 
-      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;
+          sporadic = rtcb->sporadic;
+          DEBUGASSERT(sporadic != NULL);
 
-      /* And restart at the next replenishment interval */
+          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 */
+
+          ret = sched_sporadic_start(tcb);
+        }
+
+      /* Restore interrupts and handler errors */
 
-      DEBUGVERIFY(sched_sporadic_start(tcb));
       irqrestore(flags);
-    }
-  else
-    {
-      tcb->hi_priority  = 0;
-      tcb->low_priority = 0;
-#ifdef __REVISIT_REPLENISHMENTS
-      tcb->max_repl     = 0;
-#endif
-      tcb->repl_period  = 0;
-      tcb->budget       = 0;
+      if (ret < 0)
+        {
+          errcode = -ret;
+          goto errout_with_lock;
+        }
     }
 #endif
 
diff --git a/sched/sched/sched_setscheduler.c b/sched/sched/sched_setscheduler.c
index 118f71f2017d909696d635eb66a34e10992dca90..34c5750939b4d873d43245bd971a9b6779e8d35d 100644
--- a/sched/sched/sched_setscheduler.c
+++ b/sched/sched/sched_setscheduler.c
@@ -87,6 +87,9 @@ int sched_setscheduler(pid_t pid, int policy,
 {
   FAR struct tcb_s *tcb;
   irqstate_t saved_state;
+#ifdef CONFIG_SCHED_SPORADIC
+  int errcode;
+#endif
   int ret;
 
   /* Check for supported scheduling policy */
@@ -175,49 +178,83 @@ int sched_setscheduler(pid_t pid, int policy,
 #ifdef CONFIG_SCHED_SPORADIC
       case SCHED_SPORADIC:
         {
+          FAR struct sporadic_s *sporadic;
           int repl_ticks;
           int budget_ticks;
 
-#ifdef __REVISIT_REPLENISHMENTS
-          DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX);
-#endif
+          if (param->sched_ss_max_repl < 1 ||
+              param->sched_ss_max_repl > CONFIG_SCHED_SPORADIC_MAXREPL)
+            {
+              errcode = EINVAL;
+              goto errout_with_irq;
+            }
 
           /* Convert timespec values to system clock ticks */
 
           (void)clock_time2ticks(&param->sched_ss_repl_period, &repl_ticks);
           (void)clock_time2ticks(&param->sched_ss_init_budget, &budget_ticks);
 
+          /* 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 (repl_ticks < budget_ticks)
             {
-              set_errno(EINVAL);
-              irqrestore(saved_state);
-              sched_unlock();
-              return ERROR;
+              errcode = EINVAL;
+              goto errout_with_irq;
             }
 
-          /* Stop/reset current sporadic scheduling */
+          /* Initialize/reset current sporadic scheduling */
 
-          DEBUGVERIFY(sched_sporadic_stop(tcb));
+          if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
+            {
+              ret = sched_sporadic_reset(tcb);
+            }
+          else
+            {
+              ret = sched_sporadic_initialize(tcb);
+            }
 
           /* Save the sporadic scheduling parameters. */
 
-          tcb->flags       |= TCB_FLAG_SCHED_SPORADIC;
-          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;
+          if (ret >= 0)
+            {
+              tcb->flags            |= TCB_FLAG_SCHED_SPORADIC;
+              tcb->timeslice         = budget_ticks;
+
+              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;
+
+              /* And restart at the next replenishment interval */
+
+              ret = sched_sporadic_start(tcb);
+            }
 
-          /* And restart at the next replenishment interval */
+          /* Handle errors */
 
-          DEBUGVERIFY(sched_sporadic_start(tcb));
+          if (ret < 0)
+            {
+              errcode = -ret;
+              goto errout_with_irq;
+            }
         }
         break;
 #endif
@@ -236,4 +273,12 @@ int sched_setscheduler(pid_t pid, int policy,
   ret = sched_reprioritize(tcb, param->sched_priority);
   sched_unlock();
   return (ret >= 0) ? OK : ERROR;
+
+#ifdef CONFIG_SCHED_SPORADIC
+errout_with_irq:
+  set_errno(errcode);
+  irqrestore(saved_state);
+  sched_unlock();
+  return ERROR;
+#endif
 }
diff --git a/sched/sched/sched_sporadic.c b/sched/sched/sched_sporadic.c
index 8982817e6f49ed2a3251a7e4093338b85142da31..c392fba4ef15d2f8dd2efec67e458f8f93fa0813 100644
--- a/sched/sched/sched_sporadic.c
+++ b/sched/sched/sched_sporadic.c
@@ -1,4 +1,4 @@
-/************************************************************************
+/****************************************************************************
  * sched/sched/sched_sporadic.c
  *
  *   Copyright (C) 2015 Gregory Nutt. All rights reserved.
@@ -31,11 +31,11 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- ************************************************************************/
+ ****************************************************************************/
 
-/************************************************************************
+/****************************************************************************
  * Included Files
- ************************************************************************/
+ ****************************************************************************/
 
 #include <nuttx/config.h>
 
@@ -55,45 +55,65 @@
 
 #ifdef CONFIG_SCHED_SPORADIC
 
-/************************************************************************
+/****************************************************************************
  * Pre-processor Definitions
- ************************************************************************/
+ ****************************************************************************/
 
 #ifndef MIN
 #  define MIN(a,b) (((a) < (b)) ? (a) : (b))
 #endif
 
-/************************************************************************
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int sporadic_budget_start(FAR struct tcb_s *tcb,
+  FAR struct replenishment_s *repl, uint32_t budget);
+static int sporadic_budget_next(FAR struct replenishment_s *repl);
+static int sporadic_interval_start(FAR struct replenishment_s *repl);
+static void sporadic_budget_expire(int argc, wdparm_t arg1, ...);
+static void sporadic_interval_expire(int argc, wdparm_t arg1, ...);
+FAR struct replenishment_s *
+  sporadic_alloc_repl(FAR struct sporadic_s *sporadic);
+
+/****************************************************************************
  * Private Functions
- ************************************************************************/
+ ****************************************************************************/
 
-/************************************************************************
- * Name: sched_sporadic_replenish_start
+/****************************************************************************
+ * Name: sporadic_budget_start
  *
  * Description:
- *   Start the next replenishment cycle, increasing the priority of the
- *   thread to the high priority.  This is normally a pretty trivial
- *   operation.  But we do have to take a few precautions is priority
- *   inheritance is enabled.
+ *   Start the next replenishment cycle by (1) increasing the priority of
+ *   the thread to the high priority and (2) setting up a timer for the
+ *   budgeted portion of the replenishment interval. We do have to take a
+ *   few precautions is priority inheritance is enabled.
  *
- * Parameters:
- *   tcb - TCB of the thread whose priority is being boosted.
+ * Input Parameters:
+ *   tcb    - TCB of the thread whose priority is being boosted.
+ *   repl   - The replenishment timer to use
+ *   budget - Budgeted execution time
  *
  * Returned Value:
  *   Returns zero (OK) on success or a negated errno value on failure.
  *
- ************************************************************************/
+ ****************************************************************************/
 
-static int sched_sporadic_replenish_start(FAR struct tcb_s *tcb)
+static int sporadic_budget_start(FAR struct tcb_s *tcb,
+                                 FAR struct replenishment_s *repl,
+                                 uint32_t budget)
 {
+  FAR struct sporadic_s *sporadic;
   int ret;
 
+  DEBUGASSERT(tcb && tcb->sporadic);
+  sporadic = tcb->sporadic;
+
   /* Start the next replenishment interval */
 
-  tcb->timeslice = tcb->budget;
-#ifdef __REVISIT_REPLENISHMENTS
-  tcb->nrepl = tcb->max_repl;
-#endif
+  tcb->timeslice = budget;
+  ret = wd_start(&repl->timer, sporadic->budget, sporadic_budget_expire,
+                 1, (wdentry_t)sporadic);
 
 #ifdef CONFIG_PRIORITY_INHERITANCE
   /* If the priority was boosted above the higher priority, than just
@@ -104,13 +124,13 @@ static int sched_sporadic_replenish_start(FAR struct tcb_s *tcb)
     {
       /* Boosted... Do we still need to reprioritize? */
 
-      if (tcb->hi_priority < tcb->base_priority)
+      if (sporadic->hi_priority < sporadic->base_priority)
         {
           /* No.. the current execution priority is lower than the
            * boosted priority.  Just reset the base priority.
            */
 
-          tcb->base_priority = tcb->hi_priority;
+          tcb->base_priority = sporadic->hi_priority;
           return OK;
         }
     }
@@ -124,7 +144,7 @@ static int sched_sporadic_replenish_start(FAR struct tcb_s *tcb)
 
   /* Then reprioritize to the higher priority */
 
-  ret = sched_reprioritize(tcb, tcb->hi_priority);
+  ret = sched_reprioritize(tcb, sporadic->hi_priority);
   if (ret < 0)
     {
       return -get_errno();
@@ -133,14 +153,266 @@ static int sched_sporadic_replenish_start(FAR struct tcb_s *tcb)
   return OK;
 }
 
-/************************************************************************
- * Name: sched_sporadic_expire
+/****************************************************************************
+ * Name: sporadic_budget_next
+ *
+ * Description:
+ *   Start the next replenishment.  This is called at the complete of each
+ *   replenishment interval.
+ *
+ * Input Parameters:
+ *   repl - Replenishment structure whose budget timer just expired.
+ *
+ * Returned Value:
+ *   Returns zero (OK) on success or a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int sporadic_budget_next(FAR struct replenishment_s *repl)
+{
+  FAR struct sporadic_s *sporadic;
+  FAR struct tcb_s *tcb;
+  uint32_t budget;
+
+  DEBUGASSERT(repl != NULL && repl->tcb != NULL);
+  tcb      = repl->tcb;
+  sporadic = tcb->sporadic;
+  DEBUGASSERT(sporadic != NULL);
+
+  /* The budgeted interval will be the pending budget */
+
+  budget = sporadic->pending;
+  if (budget > sporadic->budget)
+    {
+      /* Clip to the maximum */
+
+      budget = sporadic->budget;
+    }
+
+  sporadic->pending -= budget;
+
+  /* If the budget zero, then all of the pending budget has been utilized.
+   * There are now two possibilities:  (1) There are multiple, active
+   * replenishment threads so this one is no longer needed, or (2) there is
+   * only one and we need to restart the budget interval with the full
+   * budget.
+   */
+
+   if (budget == 0)
+     {
+       if (sporadic->nrepls > 1)
+         {
+           /* Release this replenishment timer.  Processing will continue
+            * to be driven by the remaining timers.
+            */
+
+           repl->active = false;
+           sporadic->nrepls--;
+           return OK;
+         }
+       else
+         {
+           /* No, we are the only replenishment timer.  Restart with the
+            * full budget.
+            */
+
+           budget = sporadic->budget;
+         }
+     }
+
+  /* Start the next replenishment interval */
+
+  return sporadic_budget_start(tcb, repl, budget);
+}
+
+/****************************************************************************
+ * Name: sporadic_set_lowpriority
+ *
+ * Description:
+ *   Force the thread to lower priority.
+ *
+ * Input Parameters:
+ *   repl - Replenishment timer to be used
+ *
+ * Returned Value:
+ *   Returns zero (OK) on success or a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int sporadic_set_lowpriority(FAR struct tcb_s *tcb)
+{
+  FAR struct sporadic_s *sporadic;
+  int ret;
+
+  DEBUGASSERT(tcb != NULL && tcb->sporadic != NULL);
+  sporadic = tcb->sporadic;
+
+#ifdef CONFIG_PRIORITY_INHERITANCE
+  /* If the priority was boosted above the higher priority, than just
+   * reset the base priority.
+   */
+
+  if (tcb->sched_priority > tcb->base_priority)
+    {
+      /* Thread priority was boosted while we were in the high priority
+       * state.
+       */
+
+      tcb->base_priority = sporadic->low_priority;
+    }
+#endif
+
+  /* Otherwise drop the priority of thread, possible causing a context
+   * switch.
+   */
+
+  ret = sched_reprioritize(tcb, sporadic->low_priority);
+  if (ret < 0)
+    {
+      return -get_errno();
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: sporadic_interval_start
+ *
+ * Description:
+ *   Start the next replenishment cycle, increasing the priority of the
+ *   thread to the high priority.  This is normally a pretty trivial
+ *   operation.  But we do have to take a few precautions is priority
+ *   inheritance is enabled.
+ *
+ * Input Parameters:
+ *   repl - Replenishment timer to be used
+ *
+ * Returned Value:
+ *   Returns zero (OK) on success or a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int sporadic_interval_start(FAR struct replenishment_s *repl)
+{
+  FAR struct sporadic_s *sporadic;
+  FAR struct tcb_s *tcb;
+  uint32_t remainder;
+
+  DEBUGASSERT(repl != NULL && repl->tcb != NULL);
+  tcb      = repl->tcb;
+  sporadic = tcb->sporadic;
+  DEBUGASSERT(sporadic != NULL);
+
+  /* Enter the low-priority phase of the replenishment cycle */
+
+  tcb->timeslice = 0;
+
+  /* Calculate the remainder of the replenishment interval.  This is
+   * permitted to be zero, in which case we just restart the budget
+   * interval without lowering the priority.
+   */
+
+  DEBUGASSERT(sporadic->repl_period >= sporadic->budget);
+  remainder = sporadic->repl_period - sporadic->budget;
+  if (remainder == 0)
+    {
+      return sporadic_budget_next(repl);
+    }
+
+  /* Start the timer that will terminate the low priority cycle.  This timer
+   * expiration is independent of what else may occur (except that it must
+   * be cancelled if the thread exits.
+   */
+
+  DEBUGVERIFY(wd_start(&repl->timer, remainder, sporadic_interval_expire,
+              1, (wdentry_t)repl));
+
+  /* Drop the priority of thread, possible causing a context switch. */
+
+  return sporadic_set_lowpriority(tcb);
+}
+
+/****************************************************************************
+ * Name: sporadic_budget_expire
+ *
+ * Description:
+ *   Handles the expiration of a budget interval.  It saves the budget
+ *   For the next interval, drops the priority of the thread, and restarts
+ *   the timer for the rest of the replenishment period.
+ *
+ * Input Parameters:
+ *   Standard watchdog parameters
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   The thread is still running and is still using the sporadic
+ *   scheduling policy.
+ *
+ ****************************************************************************/
+
+static void sporadic_budget_expire(int argc, wdparm_t arg1, ...)
+{
+  FAR struct replenishment_s *repl = (FAR struct replenishment_s *)arg1;
+  FAR struct sporadic_s *sporadic;
+  FAR struct tcb_s *tcb;
+  uint32_t pending;
+
+  DEBUGASSERT(argc == 1 && repl != NULL && repl->tcb != NULL);
+  tcb      = repl->tcb;
+
+  sporadic = tcb->sporadic;
+  DEBUGASSERT(sporadic != NULL);
+
+  /* As a special case, we can do nothing here if schedule has been locked.
+   * We cannot drop the priority because that might cause a context switch,
+   * violating the lock.
+   *
+   * What we do instead is just deallocate the timer.  When the lock is
+   * finally released, sched_sporadic_lowpriority() and that will restart
+   * the interval period. timeslice == -1 is the cue to sched_unlock() that
+   * this operation is needed.
+   */
+
+  if (tcb->lockcount > 0)
+    {
+      DEBUGASSERT(repl->active && sporadic->nrepls > 0);
+      tcb->timeslice = -1;
+      repl->active   = false;
+      sporadic->nrepls--;
+      return;
+    }
+
+  /* Calculate any part of the budget that was not utilized */
+
+  DEBUGASSERT(sporadic->budget >= tcb->timeslice);
+  pending = sporadic->pending + sporadic->budget - tcb->timeslice;
+  if (pending > sporadic->budget)
+    {
+      /* Limit to the full budget.  This can happen if we are falling
+       * behind and the thread is not getting enough CPU bandwidth to
+       * satisfy its budget.
+       */
+
+      pending = sporadic->budget;
+    }
+
+  sporadic->pending = pending;
+
+  /* Drop the priority of the thread and start the timer for the rest of the interval */
+
+  DEBUGVERIFY(sporadic_interval_start(repl));
+}
+
+/****************************************************************************
+ * Name: sporadic_interval_expire
  *
  * Description:
  *   Handles the expiration of a replenishment interval by starting the
  *   next replenishment interval.
  *
- * Parameters:
+ * Input Parameters:
  *   Standard watchdog parameters
  *
  * Returned Value:
@@ -150,24 +422,158 @@ static int sched_sporadic_replenish_start(FAR struct tcb_s *tcb)
  *   The thread is still running and is still using the sporadic
  *   scheduling policy.
  *
- ************************************************************************/
+ ****************************************************************************/
 
-static void sched_sporadic_expire(int argc, wdparm_t arg1, ...)
+static void sporadic_interval_expire(int argc, wdparm_t arg1, ...)
 {
-  FAR struct tcb_s *tcb = (FAR struct tcb_s *)arg1;
+  FAR struct replenishment_s *repl = (FAR struct replenishment_s *)arg1;
 
-  DEBUGASSERT(argc == 1 && tcb != NULL);
+  DEBUGASSERT(argc == 1 && repl != NULL);
 
   /* Start the next replenishment interval */
 
-  DEBUGVERIFY(sched_sporadic_replenish_start(tcb));
+  DEBUGVERIFY(sporadic_budget_next(repl));
 }
 
-/************************************************************************
+/****************************************************************************
+ * Name: sporadic_timer_cancel
+ *
+ * Description:
+ *   Cancel all timers. We do this if/when the budget time expires while the
+ *   scheduler is locked.  Basically we need to stop everything and restart
+ *   when the scheduler is unlocked.
+ *
+ * Input Parameters:
+ *   tcb - The TCB of the thread that has the scheduler locked
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void sporadic_timer_cancel(FAR struct tcb_s *tcb)
+{
+  FAR struct sporadic_s *sporadic;
+  FAR struct replenishment_s *repl;
+  int i;
+
+  DEBUGASSERT(tcb && tcb->sporadic);
+  sporadic = tcb->sporadic;
+
+  /* Cancel all timers. */
+
+  for (i = 0; i < CONFIG_SCHED_SPORADIC_MAXREPL; i++)
+    {
+      repl = &sporadic->replenishments[i];
+
+      /* Cancel any outstanding timer activity */
+
+      wd_cancel(&repl->timer);
+      repl->active = false;
+    }
+
+  sporadic->nrepls = 0;
+}
+
+/****************************************************************************
+ * Name: sporadic_alloc_repl
+ *
+ * Description:
+ *   Allocate a replenishment timer structure.
+ *
+ * Input Parameters:
+ *   sporadic - The task's sporadic scheduling state.
+ *
+ * Returned Value:
+ *   The allocated replenishment timer structure; NULL is returned on a failure
+ *
+ ****************************************************************************/
+
+FAR struct replenishment_s *
+  sporadic_alloc_repl(FAR struct sporadic_s *sporadic)
+{
+  FAR struct replenishment_s *repl = NULL;
+  int i;
+
+  if (sporadic->nrepls < sporadic->max_repl)
+    {
+      /* Allocate a new replenishment timer */
+
+      DEBUGASSERT(sporadic->max_repl <= CONFIG_SCHED_SPORADIC_MAXREPL);
+      for (i = 0; i < sporadic->max_repl; i++)
+        {
+          FAR struct replenishment_s *tmp = &sporadic->replenishments[i];
+          if (!tmp->active)
+            {
+              repl         = tmp;
+              repl->active = true;
+              sporadic->nrepls++;
+              break;
+            }
+        }
+
+      /* Since we no that we have not yet reached the max_repl number of
+       * timers, the above search should never fail.
+       */
+
+      DEBUGASSERT(repl != NULL);
+    }
+
+  return repl;
+}
+
+
+/****************************************************************************
  * Public Functions
- ************************************************************************/
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_sporadic_initialize
+ *
+ * Description:
+ *   Allocate resources needed by the sporadic scheduling policy.
+ *
+ * Input Parameters:
+ *   tcb - TCB of the thread whose priority is being boosted.
+ *
+ * Returned Value:
+ *   Returns zero (OK) on success or a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int sched_sporadic_initialize(FAR struct tcb_s *tcb)
+{
+  FAR struct sporadic_s *sporadic;
+  int i;
 
-/************************************************************************
+  DEBUGASSERT(tcb != NULL && tcb->sporadic == NULL);
+
+  /* Allocate the sporadic add-on data structure that will hold the
+   * sporadic scheduling parameters and state data.
+   */
+
+   sporadic = (FAR struct sporadic_s *)kmm_zalloc(sizeof(struct sporadic_s));
+   if (sporadic == NULL)
+     {
+       return -ENOMEM;
+     }
+
+   /* The initialize required is to set the back pointer to the TCB in
+    * each of the replenishment structures.
+    */
+
+  for (i = 0; i < CONFIG_SCHED_SPORADIC_MAXREPL; i++)
+    {
+      sporadic->replenishments[i].tcb = tcb;
+    }
+
+  /* Hook the sporadic add-on into the TCB */
+
+  tcb->sporadic = sporadic;
+  return OK;
+}
+
+/****************************************************************************
  * Name: sched_sporadic_start
  *
  * Description:
@@ -176,12 +582,12 @@ static void sched_sporadic_expire(int argc, wdparm_t arg1, ...)
  *
  *     - When starting a pthread with sporadic scheduling specified in
  *       the pthread attributes.
- *     - When establishing sporadic scheduling policy via 
+ *     - When establishing sporadic scheduling policy via
  *       sched_setscheduler()
  *     - When the sporadic scheduling parameters are changed via
  *       sched_setparam().
  *
- * Parameters:
+ * Input Parameters:
  *   tcb - The TCB of the thread that is beginning sporadic scheduling.
  *
  * Returned Value:
@@ -192,38 +598,44 @@ static void sched_sporadic_expire(int argc, wdparm_t arg1, ...)
  *   - All sporadic scheduling parameters in the TCB are valid
  *   - The thread is not currently using the sporadic scheduliing policy.
  *
- ************************************************************************/
+ ****************************************************************************/
 
 int sched_sporadic_start(FAR struct tcb_s *tcb)
 {
-  DEBUGASSERT(tcb);
+  FAR struct sporadic_s *sporadic;
+  FAR struct replenishment_s *repl;
 
-  /* Cancel and pending low-priority interval timing and re-initialize
-   * the watchdog timer.
-   */
+  DEBUGASSERT(tcb && tcb->sporadic);
+  sporadic = tcb->sporadic;
 
-  wd_cancel(&tcb->low_dog);
-  memset(&tcb->low_dog, 0, sizeof(struct wdog_s));
+  DEBUGASSERT(sporadic->low_priority <= sporadic->hi_priority);
+  DEBUGASSERT(sporadic->max_repl <= CONFIG_SCHED_SPORADIC_MAXREPL);
+  DEBUGASSERT(sporadic->budget > 0 && sporadic->budget <= sporadic->repl_period);
+  DEBUGASSERT(sporadic->nrepls == 0 && sporadic->pending == 0);
 
-  /* Then start the first replenishment interval */
+  /* Allocate the first replenishment timer (should never fail) */
 
-  return sched_sporadic_replenish_start(tcb);
+  repl = sporadic_alloc_repl(sporadic);
+  DEBUGASSERT(repl != NULL && sporadic->nrepls == 1);
+
+  /* Then start the first interval */
+
+  return sporadic_budget_start(tcb, repl, sporadic->budget);
 }
 
-/************************************************************************
+/****************************************************************************
  * Name: sched_sporadic_stop
  *
  * Description:
- *   Called to terminate sporadic scheduling on a given thread.  This
- *   function is called in the following circumstances:
+ *   Called to terminate sporadic scheduling on a given thread and to
+ *   free all resources associated with the policy.  This function is
+ *   called in the following circumstances:
  *
  *     - When any thread exits with sporadic scheduling active.
  *     - When any thread using sporadic scheduling is changed to use
  *       some other scheduling policy via sched_setscheduler()
- *     - When the sporadic scheduling parameters are changed via
- *       sched_setparam().
  *
- * Parameters:
+ * Input Parameters:
  *   tcb - The TCB of the thread that is beginning sporadic scheduling.
  *
  * Returned Value:
@@ -234,34 +646,84 @@ int sched_sporadic_start(FAR struct tcb_s *tcb)
  *   - All sporadic scheduling parameters in the TCB are valid
  *   - The thread is currently using the sporadic scheduling policy.
  *
- ************************************************************************/
+ ****************************************************************************/
 
 int sched_sporadic_stop(FAR struct tcb_s *tcb)
 {
-  DEBUGASSERT(tcb);
+  DEBUGASSERT(tcb && tcb->sporadic);
 
-  /* Cancel and pending low-priority interval timing and re-initialize
-   * the watchdog timer.
-   */
+  /* Stop all timers, reset scheduling */
 
-  wd_cancel(&tcb->low_dog);
-  memset(&tcb->low_dog, 0, sizeof(struct wdog_s));
+  (void)sched_sporadic_reset(tcb);
 
-  /* Reset sporadic scheduling parameters */
+  /* The free the container holder the sporadic scheduling parameters */
 
-  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;
+  kmm_free(tcb->sporadic);
+  tcb->sporadic = NULL;
+  return OK;
+}
+
+/****************************************************************************
+ * Name: sched_sporadic_reset
+ *
+ * Description:
+ *   Called to stop sporadic scheduling on a given thread.  This
+ *   function is called in the following circumstances:
+ *
+ *     - When the sporadic scheduling parameters are changed via
+ *       sched_setparam()
+ *     - From sched_sporadic_stop when under those conditions.
+ *
+ * Input Parameters:
+ *   tcb - The TCB of the thread that is beginning sporadic scheduling.
+ *
+ * Returned Value:
+ *   Returns zero (OK) on success or a negated errno value on failure.
+ *
+ * Assumptions:
+ *   - Interrupts are disabled
+ *   - All sporadic scheduling parameters in the TCB are valid
+ *   - The thread is currently using the sporadic scheduling policy.
+ *
+ ****************************************************************************/
+
+int sched_sporadic_reset(FAR struct tcb_s *tcb)
+{
+  FAR struct sporadic_s *sporadic;
+  FAR struct replenishment_s *repl;
+  int i;
+
+  DEBUGASSERT(tcb && tcb->sporadic);
+  sporadic = tcb->sporadic;
+
+  /* Cancel all timers. */
+
+  for (i = 0; i < CONFIG_SCHED_SPORADIC_MAXREPL; i++)
+    {
+      repl = (FAR struct replenishment_s *)&sporadic->replenishments[i];
+
+      /* Cancel any outstanding timer activity */
+
+      wd_cancel(&repl->timer);
+
+      /* Re-initialize replenishment data */
+
+      repl->tcb = tcb;
+    }
+
+  /* Reset sporadic scheduling parameters and state data */
+
+  sporadic->hi_priority  = 0;
+  sporadic->low_priority = 0;
+  sporadic->max_repl     = 0;
+  sporadic->nrepls       = 0;
+  sporadic->repl_period  = 0;
+  sporadic->budget       = 0;
+  sporadic->pending      = 0;
   return OK;
 }
 
-/************************************************************************
+/****************************************************************************
  * Name: sched_sporadic_resume
  *
  * Description:
@@ -274,7 +736,7 @@ int sched_sporadic_stop(FAR struct tcb_s *tcb)
  *   This function does nothing if the budget phase as already elapsed or
  *   the maximum numer of replenishments have already been performed.
  *
- * Parameters:
+ * Input Parameters:
  *   tcb - The TCB of the thread that is beginning sporadic scheduling.
  *
  * Returned Value:
@@ -285,37 +747,40 @@ int sched_sporadic_stop(FAR struct tcb_s *tcb)
  *  - All sporadic scheduling parameters in the TCB are valid
  *  - The low priority interval timer is not running
  *
- ************************************************************************/
+ ****************************************************************************/
 
 int sched_sporadic_resume(FAR struct tcb_s *tcb)
 {
-  DEBUGASSERT(tcb);
+  FAR struct sporadic_s *sporadic;
+  FAR struct replenishment_s *repl;
+  uint32_t budget;
 
-  /* 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.
-   */
+  DEBUGASSERT(tcb && tcb->sporadic);
+  sporadic = tcb->sporadic;
 
-#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.
+  /* Check if 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.
    */
 
-  if (tcb->timeslice > 0 && tcb->nrepl > 0)
+  if (tcb->timeslice > 0)
     {
-      tcb->timeslice = tcb->budget;
-      tcb->nrepl--;
+      /* Allocate a new replenishment timer */
+
+      repl = sporadic_alloc_repl(sporadic);
+      if (repl)
+        {
+          budget = tcb->timeslice;
+          return sporadic_budget_start(tcb, repl, budget);
+        }
+
+      return -ENOMEM;
     }
-#endif
 
   return OK;
 }
 
-/************************************************************************
+/****************************************************************************
  * Name: sched_sporadic_process
  *
  * Description:
@@ -324,26 +789,31 @@ int sched_sporadic_resume(FAR struct tcb_s *tcb)
  *   - From the timer interrupt handler while the thread with sporadic
  *     scheduling is running.
  *
- * Parameters:
- *   tcb - The TCB of the thread that is beginning sporadic scheduling.
- *   ticks - The number of elapsed ticks since the last time this
- *   function was called.
+ * Input Parameters:
+ *   tcb        - The TCB of the thread that is beginning sporadic
+                  scheduling.
+ *   ticks      - The number of elapsed ticks since the last time this
+ *                function was called.
+ *   noswitches - We are running in a context where context switching is
+ *                not permitted.
  *
  * Returned Value:
  *   The number if ticks remaining until the budget interval expires.
- *   Zero is returned if we are in the low-prioriy phase of the the
+ *   Zero is returned if we are in the low-priority phase of the the
  *   replenishment interval.
  *
  * Assumptions:
  *   - Interrupts are disabled
  *   - All sporadic scheduling parameters in the TCB are valid
  *
- ************************************************************************/
+ ****************************************************************************/
 
 uint32_t sched_sporadic_process(FAR struct tcb_s *tcb, uint32_t ticks,
                                 bool noswitches)
 {
-  DEBUGASSERT(tcb && ticks > 0);
+  FAR struct sporadic_s *sporadic;
+
+  DEBUGASSERT(tcb != NULL && tcb->sporadic != NULL && ticks > 0);
 
   /* If we are in the low-priority phase of the replenishment interval,
    * then just return zero.
@@ -366,7 +836,7 @@ uint32_t sched_sporadic_process(FAR struct tcb_s *tcb, uint32_t ticks,
    * if there ever were the case.
    *
    * Notice that in the case where were are stuck in the high priority
-   * phase with scheduler locke, timeslice will by -1 and any value of
+   * phase with scheduler locked, timeslice will by -1 and any value of
    * ticks will pass this test.
    */
 
@@ -384,10 +854,11 @@ uint32_t sched_sporadic_process(FAR struct tcb_s *tcb, uint32_t ticks,
            * case.
            */
 
+          sporadic_timer_cancel(tcb);
           tcb->timeslice = -1;
           return 0;
         }
-      
+
       /* We will also suppress context switches if we were called via one of
        * the unusual cases handled by sched_timer_reasses(). In that case,
        * we will return a value of one so that the timer will expire as soon
@@ -410,15 +881,16 @@ uint32_t sched_sporadic_process(FAR struct tcb_s *tcb, uint32_t ticks,
        * thing to do, but is certainly permitted.
        */
 
-      if (tcb->budget >= tcb->repl_period)
+      sporadic = tcb->sporadic;
+      if (sporadic->budget >= sporadic->repl_period)
         {
-          tcb->timeslice = tcb->budget;
-          return tcb->budget;
+          tcb->timeslice = sporadic->budget;
+          return sporadic->budget;
         }
 
       /* Otherwise enter the low-priority phase of the replenishment cycle */
 
-      sched_sporadic_lowpriority(tcb);
+      sporadic_set_lowpriority(tcb);
       return 0;
     }
 
@@ -433,7 +905,7 @@ uint32_t sched_sporadic_process(FAR struct tcb_s *tcb, uint32_t ticks,
     }
 }
 
-/************************************************************************
+/****************************************************************************
  * Name: sched_sporadic_lowpriority
  *
  * Description:
@@ -444,8 +916,9 @@ uint32_t sched_sporadic_process(FAR struct tcb_s *tcb, uint32_t ticks,
  *   - sched_unlock().  When the budget expires while the thread had the
  *     scheduler locked.
  *
- * Parameters:
- *   tcb - The TCB of the thread that is entering the low priority phase. 
+ * Input Parameters:
+ *   tcb     - The TCB of the thread that is entering the low priority phase.
+ *   restart - Restart timers.
  *
  * Returned Value:
  *   None
@@ -454,44 +927,31 @@ uint32_t sched_sporadic_process(FAR struct tcb_s *tcb, uint32_t ticks,
  *   - Interrupts are disabled
  *   - All sporadic scheduling parameters in the TCB are valid
  *
- ************************************************************************/
+ ****************************************************************************/
 
 void sched_sporadic_lowpriority(FAR struct tcb_s *tcb)
 {
-  DEBUGASSERT(tcb);
-
-  /* Enter the low-priority phase of the replenishment cycle */
+  FAR struct sporadic_s *sporadic;
+  FAR struct replenishment_s *repl;
 
-  tcb->timeslice = 0;
+  DEBUGASSERT(tcb && tcb->sporadic);
+  sporadic = tcb->sporadic;
 
-  /* Start the timer that will terminate the low priority cycle.  This timer
-   * expiration is independent of what else may occur (except that it must
-   * be cancelled if the thread exits.
-   */
+  /* Enter the low-priority phase of the replenishment cycle. */
 
-  DEBUGVERIFY(wd_start(&tcb->low_dog, tcb->repl_period - tcb->budget,
-                       sched_sporadic_expire, 1, (wdentry_t)tcb));
+  tcb->timeslice = 0;
 
-#ifdef CONFIG_PRIORITY_INHERITANCE
-  /* If the priority was boosted above the higher priority, than just
-   * reset the base priority.
+  /* Allocate a new replenishment timer.  There should be no timers
+   * active at this phase since they were stopped in sched_sporadic_process().
    */
 
-  if (tcb->sched_priority > tcb->base_priority)
-    {
-      /* Thread priority was boosted while we were in the high priority
-       * state.
-       */
-
-      tcb->base_priority = tcb->low_priority;
-    }
-#endif
+  DEBUGASSERT(sporadic->nrepls < sporadic->max_repl);
+  repl = sporadic_alloc_repl(sporadic);
+  DEBUGASSERT(repl != NULL);
 
-  /* Otherwise drop the priority of thread, possible causing a context
-   * switch.
-   */
+  /* Drop the priority of thread, possible causing a context switch. */
 
-  DEBUGVERIFY(sched_reprioritize(tcb, tcb->low_priority));
+  DEBUGVERIFY(sporadic_interval_start(repl));
 }
 
 #endif /* CONFIG_SCHED_SPORADIC */
diff --git a/sched/sched/sched_timerexpiration.c b/sched/sched/sched_timerexpiration.c
index c078328d8cb5b675933036655c438856326525dd..be409c3492643cf2b23c4f95a1d1cbe90c61bfa5 100644
--- a/sched/sched/sched_timerexpiration.c
+++ b/sched/sched/sched_timerexpiration.c
@@ -76,7 +76,7 @@
 #if CONFIG_RR_INTERVAL > 0
 #  define KEEP_ALIVE_TICKS MSEC2TICK(CONFIG_RR_INTERVAL)
 #else
-#  define KEEP_ALIVE_TICKS MSEC2TICK(50)
+#  define KEEP_ALIVE_TICKS MSEC2TICK(80)
 #endif
 
 #ifndef MIN