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

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

commit 08f7152d9f13aafd7270b2462572c189ea669692
Author: zhangyuan21 <zhangyua...@xiaomi.com>
AuthorDate: Sun Nov 13 20:39:14 2022 +0800

    nuttx/sched: remove nxsched_remove_readytorun from up_block_task
    
    It takes about 10 cycles to obtain the task list according to the task
    status. In most cases, we know the task status, so we can directly
    add the task from the specified task list to reduce time consuming.
---
 Documentation/reference/os/arch.rst              |  26 ++---
 arch/arm/src/common/arm_blocktask.c              | 119 +++++++-------------
 arch/arm/src/common/arm_reprioritizertr.c        |   2 +-
 arch/arm64/src/common/arm64_blocktask.c          | 121 +++++++-------------
 arch/arm64/src/common/arm64_reprioritizertr.c    |   2 +-
 arch/avr/src/avr/up_blocktask.c                  | 115 +++++++------------
 arch/avr/src/avr/up_reprioritizertr.c            |   2 +-
 arch/avr/src/avr32/up_blocktask.c                | 135 ++++++++---------------
 arch/avr/src/avr32/up_reprioritizertr.c          |   2 +-
 arch/ceva/src/common/up_blocktask.c              | 117 +++++++-------------
 arch/hc/src/common/up_blocktask.c                | 127 ++++++++-------------
 arch/hc/src/common/up_reprioritizertr.c          |   2 +-
 arch/mips/src/mips32/mips_blocktask.c            | 121 +++++++-------------
 arch/mips/src/mips32/mips_reprioritizertr.c      |   2 +-
 arch/misoc/src/lm32/lm32_blocktask.c             | 121 +++++++-------------
 arch/misoc/src/lm32/lm32_reprioritizertr.c       |   2 +-
 arch/misoc/src/minerva/minerva_blocktask.c       | 121 +++++++-------------
 arch/misoc/src/minerva/minerva_reprioritizertr.c |   2 +-
 arch/or1k/src/common/up_blocktask.c              | 127 ++++++++-------------
 arch/or1k/src/common/up_reprioritizertr.c        |   2 +-
 arch/renesas/src/common/up_blocktask.c           | 129 ++++++++--------------
 arch/renesas/src/common/up_reprioritizertr.c     |   2 +-
 arch/risc-v/src/common/riscv_blocktask.c         | 121 +++++++-------------
 arch/risc-v/src/common/riscv_reprioritizertr.c   |   2 +-
 arch/sim/src/sim/up_blocktask.c                  | 109 ++++++------------
 arch/sim/src/sim/up_reprioritizertr.c            |   2 +-
 arch/sparc/src/sparc_v8/up_blocktask.c           | 123 +++++++--------------
 arch/sparc/src/sparc_v8/up_reprioritizertr.c     |   2 +-
 arch/x86/src/common/up_blocktask.c               | 129 ++++++++--------------
 arch/x86/src/common/up_reprioritizertr.c         |   2 +-
 arch/x86_64/src/common/up_blocktask.c            | 131 ++++++++--------------
 arch/x86_64/src/common/up_reprioritizertr.c      |   2 +-
 arch/xtensa/src/common/xtensa_blocktask.c        | 119 +++++++-------------
 arch/xtensa/src/common/xtensa_reprioritizertr.c  |   2 +-
 arch/z16/src/common/z16_blocktask.c              | 117 +++++++-------------
 arch/z16/src/common/z16_reprioritizertr.c        |   2 +-
 arch/z80/src/common/z80_blocktask.c              | 131 ++++++++--------------
 arch/z80/src/common/z80_reprioritizertr.c        |   2 +-
 include/nuttx/arch.h                             |  17 +--
 sched/mqueue/mq_rcvinternal.c                    |  19 +++-
 sched/mqueue/mq_sndinternal.c                    |  18 ++-
 sched/mqueue/msgrcv.c                            |  18 ++-
 sched/mqueue/msgsnd.c                            |  18 ++-
 sched/paging/pg_miss.c                           |  18 ++-
 sched/sched/sched.h                              |   2 +-
 sched/sched/sched_removereadytorun.c             |  17 ++-
 sched/sched/sched_setpriority.c                  |   2 +-
 sched/sched/sched_suspend.c                      |  23 +++-
 sched/semaphore/sem_wait.c                       |  18 ++-
 sched/signal/sig_suspend.c                       |  18 ++-
 sched/signal/sig_timedwait.c                     |  35 +++++-
 sched/task/task_exit.c                           |  11 +-
 52 files changed, 1017 insertions(+), 1612 deletions(-)

diff --git a/Documentation/reference/os/arch.rst 
b/Documentation/reference/os/arch.rst
index 12c9dbbb86..627f6a1af7 100644
--- a/Documentation/reference/os/arch.rst
+++ b/Documentation/reference/os/arch.rst
@@ -186,21 +186,17 @@ APIs Exported by Architecture-Specific Logic to NuttX
      which will be executed.
   :param rtcb: Refers to the running task which will be blocked.
 
-.. c:function:: void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state)
-
-  The currently executing task at the head of the
-  ready to run list must be stopped. Save its context and move it to
-  the inactive list specified by task_state. This function is called
-  only from the NuttX scheduling logic. Interrupts will always be
-  disabled when this function is called.
-
-  :param tcb: Refers to a task in the ready-to-run list (normally
-     the task at the head of the list). It must be stopped, its
-     context saved and moved into one of the waiting task lists. If
-     it was the task at the head of the ready-to-run list, then a
-     context switch to the new ready to run task must be performed.
-  :param task_state: Specifies which waiting task list should be
-     hold the blocked task TCB.
+.. c:function:: void up_block_task(FAR struct tcb_s *rtcb)
+
+  The currently executing task has already removed from ready-to-run list.
+  Save its context and switch to the next running task at the head of the
+  ready-to-run list.
+
+  This function is called only from the NuttX scheduling logic.
+  Interrupts will always be disabled when this function is called.
+
+  :param rtcb: Reference to the running task which is different to the
+     task (next running task) at the head of the list.
 
 .. c:function:: void up_release_pending(void)
 
diff --git a/arch/arm/src/common/arm_blocktask.c 
b/arch/arm/src/common/arm_blocktask.c
index dd8cb365a1..1db14cb6d8 100644
--- a/arch/arm/src/common/arm_blocktask.c
+++ b/arch/arm/src/common/arm_blocktask.c
@@ -44,108 +44,69 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (CURRENT_REGS)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the CURRENT_REGS into the OLD rtcb.
+       */
 
-      if (CURRENT_REGS)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the CURRENT_REGS into the OLD rtcb.
-           */
+      arm_savestate(rtcb->xcp.regs);
 
-          arm_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Then switch contexts.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
-
-          arm_restorestate(rtcb->xcp.regs);
-        }
+      arm_restorestate(rtcb->xcp.regs);
+    }
 
-      /* No, then we will need to perform the user context switch */
+  /* No, then we will need to perform the user context switch */
 
-      else
-        {
-          struct tcb_s *nexttcb = this_task();
+  else
+    {
+      struct tcb_s *nexttcb = this_task();
 
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(nexttcb);
+      nxsched_resume_scheduler(nexttcb);
 
-          /* Switch context to the context of the task at the head of the
-           * ready to run list.
-           */
+      /* Switch context to the context of the task at the head of the
+       * ready to run list.
+       */
 
-          arm_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
+      arm_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
 
-          /* arm_switchcontext forces a context switch to the task at the
-           * head of the ready-to-run list.  It does not 'return' in the
-           * normal sense.  When it does return, it is because the blocked
-           * task is again ready to run and has execution priority.
-           */
-        }
+      /* arm_switchcontext forces a context switch to the task at the
+       * head of the ready-to-run list.  It does not 'return' in the
+       * normal sense.  When it does return, it is because the blocked
+       * task is again ready to run and has execution priority.
+       */
     }
 }
diff --git a/arch/arm/src/common/arm_reprioritizertr.c 
b/arch/arm/src/common/arm_reprioritizertr.c
index d019d9dee7..6a44fb5147 100644
--- a/arch/arm/src/common/arm_reprioritizertr.c
+++ b/arch/arm/src/common/arm_reprioritizertr.c
@@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/arm64/src/common/arm64_blocktask.c 
b/arch/arm64/src/common/arm64_blocktask.c
index f8b79a77c2..85f9490760 100644
--- a/arch/arm64/src/common/arm64_blocktask.c
+++ b/arch/arm64/src/common/arm64_blocktask.c
@@ -44,110 +44,69 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb;
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  rtcb = this_task();
+  nxsched_suspend_scheduler(rtcb);
 
-  /* Verify that the context switch can be performed */
+  /* Are we in an interrupt handler? */
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
-
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
+  if (CURRENT_REGS)
     {
-      switch_needed |= nxsched_merge_pending();
-    }
+      /* Yes, then we have to do things differently.
+       * Just copy the CURRENT_REGS into the OLD rtcb.
+       */
 
-  /* Now, perform the context switch if one is needed */
+      arm64_savestate(rtcb->xcp.regs);
 
-  if (switch_needed)
-    {
-      /* Update scheduler parameters */
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-      nxsched_suspend_scheduler(rtcb);
+      rtcb = this_task();
 
-      /* Are we in an interrupt handler? */
+      /* Reset scheduler parameters */
 
-      if (CURRENT_REGS)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the CURRENT_REGS into the OLD rtcb.
-           */
+      nxsched_resume_scheduler(rtcb);
 
-          arm64_savestate(rtcb->xcp.regs);
+      /* Then switch contexts.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
-
-          rtcb = this_task();
-
-          /* Reset scheduler parameters */
-
-          nxsched_resume_scheduler(rtcb);
-
-          /* Then switch contexts.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
-
-          arm64_restorestate(rtcb->xcp.regs);
-        }
+      arm64_restorestate(rtcb->xcp.regs);
+    }
 
-      /* No, then we will need to perform the user context switch */
+  /* No, then we will need to perform the user context switch */
 
-      else
-        {
-          struct tcb_s *nexttcb = this_task();
+  else
+    {
+      struct tcb_s *nexttcb = this_task();
 
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(nexttcb);
+      nxsched_resume_scheduler(nexttcb);
 
-          /* Switch context to the context of the task at the head of the
-           * ready to run list.
-           */
+      /* Switch context to the context of the task at the head of the
+       * ready to run list.
+       */
 
-          arm64_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
+      arm64_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
 
-          /* arm_switchcontext forces a context switch to the task at the
-           * head of the ready-to-run list.  It does not 'return' in the
-           * normal sense.  When it does return, it is because the blocked
-           * task is again ready to run and has execution priority.
-           */
-        }
+      /* arm_switchcontext forces a context switch to the task at the
+       * head of the ready-to-run list.  It does not 'return' in the
+       * normal sense.  When it does return, it is because the blocked
+       * task is again ready to run and has execution priority.
+       */
     }
 }
diff --git a/arch/arm64/src/common/arm64_reprioritizertr.c 
b/arch/arm64/src/common/arm64_reprioritizertr.c
index 8cefcf86e5..437902b31d 100644
--- a/arch/arm64/src/common/arm64_reprioritizertr.c
+++ b/arch/arm64/src/common/arm64_reprioritizertr.c
@@ -85,7 +85,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/avr/src/avr/up_blocktask.c b/arch/avr/src/avr/up_blocktask.c
index 1be4c6751f..02d3a5b877 100644
--- a/arch/avr/src/avr/up_blocktask.c
+++ b/arch/avr/src/avr/up_blocktask.c
@@ -43,106 +43,67 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-         (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (g_current_regs)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the g_current_regs into the OLD rtcb.
+       */
 
-      if (g_current_regs)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the g_current_regs into the OLD rtcb.
-           */
+      up_savestate(rtcb->xcp.regs);
 
-          up_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts */
 
-          /* Then switch contexts */
-
-          up_restorestate(rtcb->xcp.regs);
-        }
+      up_restorestate(rtcb->xcp.regs);
+    }
 
-      /* No, then we will need to perform the user context switch */
+  /* No, then we will need to perform the user context switch */
 
-      else
-        {
-          struct tcb_s *nexttcb = this_task();
+  else
+    {
+      struct tcb_s *nexttcb = this_task();
 
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(nexttcb);
+      nxsched_resume_scheduler(nexttcb);
 
-          /* Switch context to the context of the task at the head of the
-           * ready to run list.
-           */
+      /* Switch context to the context of the task at the head of the
+       * ready to run list.
+       */
 
-          up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+      up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
 
-          /* up_switchcontext forces a context switch to the task at the
-           * head of the ready-to-run list.  It does not 'return' in the
-           * normal sense.  When it does return, it is because the blocked
-           * task is again ready to run and has execution priority.
-           */
-        }
+      /* up_switchcontext forces a context switch to the task at the
+       * head of the ready-to-run list.  It does not 'return' in the
+       * normal sense.  When it does return, it is because the blocked
+       * task is again ready to run and has execution priority.
+       */
     }
 }
diff --git a/arch/avr/src/avr/up_reprioritizertr.c 
b/arch/avr/src/avr/up_reprioritizertr.c
index 7bf1565e96..51c504afd6 100644
--- a/arch/avr/src/avr/up_reprioritizertr.c
+++ b/arch/avr/src/avr/up_reprioritizertr.c
@@ -86,7 +86,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/avr/src/avr32/up_blocktask.c 
b/arch/avr/src/avr32/up_blocktask.c
index f789aa022b..5da62c9562 100644
--- a/arch/avr/src/avr32/up_blocktask.c
+++ b/arch/avr/src/avr32/up_blocktask.c
@@ -44,120 +44,81 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-         (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (g_current_regs)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the g_current_regs into the OLD rtcb.
+       */
 
-      if (g_current_regs)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the g_current_regs into the OLD rtcb.
-           */
+      up_savestate(rtcb->xcp.regs);
 
-          up_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any new address environment needed by
+       * the new thread will be instantiated before the return from
+       * interrupt.
+       */
 
-          /* Then switch contexts.  Any new address environment needed by
-           * the new thread will be instantiated before the return from
-           * interrupt.
-           */
-
-          up_restorestate(rtcb->xcp.regs);
-        }
+      up_restorestate(rtcb->xcp.regs);
+    }
 
-      /* No, then we will need to perform the user context switch */
+  /* No, then we will need to perform the user context switch */
 
-      else
-        {
-          /* Get the context of the task at the head of the ready to
-           * run list.
-           */
+  else
+    {
+      /* Get the context of the task at the head of the ready to
+       * run list.
+       */
 
-          struct tcb_s *nexttcb = this_task();
+      struct tcb_s *nexttcb = this_task();
 
 #ifdef CONFIG_ARCH_ADDRENV
-          /* Make sure that the address environment for the previously
-           * running task is closed down gracefully (data caches dump,
-           * MMU flushed) and set up the address environment for the new
-           * thread at the head of the ready-to-run list.
-           */
+      /* Make sure that the address environment for the previously
+       * running task is closed down gracefully (data caches dump,
+       * MMU flushed) and set up the address environment for the new
+       * thread at the head of the ready-to-run list.
+       */
 
-          group_addrenv(nexttcb);
+      group_addrenv(nexttcb);
 #endif
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(nexttcb);
+      nxsched_resume_scheduler(nexttcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+      up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
 
-          /* up_switchcontext forces a context switch to the task at the
-           * head of the ready-to-run list.  It does not 'return' in the
-           * normal sense.  When it does return, it is because the blocked
-           * task is again ready to run and has execution priority.
-           */
-        }
+      /* up_switchcontext forces a context switch to the task at the
+       * head of the ready-to-run list.  It does not 'return' in the
+       * normal sense.  When it does return, it is because the blocked
+       * task is again ready to run and has execution priority.
+       */
     }
 }
diff --git a/arch/avr/src/avr32/up_reprioritizertr.c 
b/arch/avr/src/avr32/up_reprioritizertr.c
index ccc3bf431c..7a841387c0 100644
--- a/arch/avr/src/avr32/up_reprioritizertr.c
+++ b/arch/avr/src/avr32/up_reprioritizertr.c
@@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/ceva/src/common/up_blocktask.c 
b/arch/ceva/src/common/up_blocktask.c
index 9ceeb233ad..2fdcbdb70b 100644
--- a/arch/ceva/src/common/up_blocktask.c
+++ b/arch/ceva/src/common/up_blocktask.c
@@ -36,108 +36,67 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of
- *   the ready to run list must be stopped.  Save its context
- *   and move it to the inactive list specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Inputs:
- *   tcb: Refers to a task in the ready-to-run list (normally
- *     the task at the head of the list).  It most be
- *     stopped, its context saved and moved into one of the
- *     waiting task lists.  It it was the task at the head
- *     of the ready-to-run list, then a context to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should be
- *     hold the blocked task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  sched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-         (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we
-   * are blocking the task at the head of the task list (the
-   * most likely case), then a context switch to the next
-   * ready-to-run task is needed. In this case, it should
-   * also be true that rtcb == tcb.
-   */
-
-  switch_needed = sched_removereadytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  sched_addblocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= sched_mergepending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (CURRENT_REGS)
     {
-      /* Update scheduler parameters */
-
-      sched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the CURRENT_REGS into the OLD rtcb.
+       */
 
-      if (CURRENT_REGS)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the CURRENT_REGS into the OLD rtcb.
-           */
+      rtcb->xcp.regs = CURRENT_REGS;
 
-          rtcb->xcp.regs = CURRENT_REGS;
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      sched_resume_scheduler(rtcb);
 
-          sched_resume_scheduler(rtcb);
+      /* Then switch contexts */
 
-          /* Then switch contexts */
-
-          CURRENT_REGS = rtcb->xcp.regs;
-        }
+      CURRENT_REGS = rtcb->xcp.regs;
+    }
 
-      /* No, then we will need to perform the user context switch */
+  /* No, then we will need to perform the user context switch */
 
-      else
-        {
-          struct tcb_s *nexttcb = this_task();
+  else
+    {
+      struct tcb_s *nexttcb = this_task();
 
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          sched_resume_scheduler(nexttcb);
+      sched_resume_scheduler(nexttcb);
 
-          /* Switch context to the context of the task at the head of the
-           * ready to run list.
-           */
+      /* Switch context to the context of the task at the head of the
+       * ready to run list.
+       */
 
-          up_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
+      up_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
 
-          /* up_switchcontext forces a context switch to the task at the
-           * head of the ready-to-run list.  It does not 'return' in the
-           * normal sense.  When it does return, it is because the blocked
-           * task is again ready to run and has execution priority.
-           */
-        }
+      /* up_switchcontext forces a context switch to the task at the
+       * head of the ready-to-run list.  It does not 'return' in the
+       * normal sense.  When it does return, it is because the blocked
+       * task is again ready to run and has execution priority.
+       */
     }
 }
diff --git a/arch/hc/src/common/up_blocktask.c 
b/arch/hc/src/common/up_blocktask.c
index 768d5429fd..dfc9a86c14 100644
--- a/arch/hc/src/common/up_blocktask.c
+++ b/arch/hc/src/common/up_blocktask.c
@@ -44,116 +44,77 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-         (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (g_current_regs)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the g_current_regs into the OLD rtcb.
+       */
 
-      if (g_current_regs)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the g_current_regs into the OLD rtcb.
-           */
+      up_savestate(rtcb->xcp.regs);
 
-          up_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Then switch contexts.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
+      up_restorestate(rtcb->xcp.regs);
+    }
 
-          up_restorestate(rtcb->xcp.regs);
-        }
+  /* Copy the user C context into the TCB at the (old) head of the
+   * ready-to-run Task list. if up_saveusercontext returns a non-zero
+   * value, then this is really the previously running task restarting!
+   */
 
-      /* Copy the user C context into the TCB at the (old) head of the
-       * ready-to-run Task list. if up_saveusercontext returns a non-zero
-       * value, then this is really the previously running task restarting!
+  else if (!up_saveusercontext(rtcb->xcp.regs))
+    {
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
        */
 
-      else if (!up_saveusercontext(rtcb->xcp.regs))
-        {
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
-
-          rtcb = this_task();
+      rtcb = this_task();
 
 #ifdef CONFIG_ARCH_ADDRENV
-          /* Make sure that the address environment for the previously
-           * running task is closed down gracefully (data caches dump,
-           * MMU flushed) and set up the address environment for the new
-           * thread at the head of the ready-to-run list.
-           */
+      /* Make sure that the address environment for the previously
+       * running task is closed down gracefully (data caches dump,
+       * MMU flushed) and set up the address environment for the new
+       * thread at the head of the ready-to-run list.
+       */
 
-          group_addrenv(rtcb);
+      group_addrenv(rtcb);
 #endif
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(rtcb);
+      nxsched_resume_scheduler(rtcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          up_fullcontextrestore(rtcb->xcp.regs);
-        }
+      up_fullcontextrestore(rtcb->xcp.regs);
     }
 }
diff --git a/arch/hc/src/common/up_reprioritizertr.c 
b/arch/hc/src/common/up_reprioritizertr.c
index 04f074fa84..4d7c830998 100644
--- a/arch/hc/src/common/up_reprioritizertr.c
+++ b/arch/hc/src/common/up_reprioritizertr.c
@@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/mips/src/mips32/mips_blocktask.c 
b/arch/mips/src/mips32/mips_blocktask.c
index 5971f02137..35df105361 100644
--- a/arch/mips/src/mips32/mips_blocktask.c
+++ b/arch/mips/src/mips32/mips_blocktask.c
@@ -45,110 +45,71 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (CURRENT_REGS)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the g_current_regs into the OLD rtcb.
+       */
 
-      if (CURRENT_REGS)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the g_current_regs into the OLD rtcb.
-           */
+      up_savestate(rtcb->xcp.regs);
 
-          up_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Then switch contexts.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
-
-          up_restorestate(rtcb->xcp.regs);
-        }
+      up_restorestate(rtcb->xcp.regs);
+    }
 
-      /* No, then we will need to perform the user context switch */
+  /* No, then we will need to perform the user context switch */
 
-      else
-        {
-          /* Get the context of the task at the head of the ready to
-           * run list.
-           */
+  else
+    {
+      /* Get the context of the task at the head of the ready to
+       * run list.
+       */
 
-          struct tcb_s *nexttcb = this_task();
+      struct tcb_s *nexttcb = this_task();
 
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(nexttcb);
+      nxsched_resume_scheduler(nexttcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+      up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
 
-          /* up_switchcontext forces a context switch to the task at the
-           * head of the ready-to-run list.  It does not 'return' in the
-           * normal sense.  When it does return, it is because the blocked
-           * task is again ready to run and has execution priority.
-           */
-        }
+      /* up_switchcontext forces a context switch to the task at the
+       * head of the ready-to-run list.  It does not 'return' in the
+       * normal sense.  When it does return, it is because the blocked
+       * task is again ready to run and has execution priority.
+       */
     }
 }
diff --git a/arch/mips/src/mips32/mips_reprioritizertr.c 
b/arch/mips/src/mips32/mips_reprioritizertr.c
index 7a99968d9c..c424592e55 100644
--- a/arch/mips/src/mips32/mips_reprioritizertr.c
+++ b/arch/mips/src/mips32/mips_reprioritizertr.c
@@ -89,7 +89,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/misoc/src/lm32/lm32_blocktask.c 
b/arch/misoc/src/lm32/lm32_blocktask.c
index 9bed1c0201..78f915d556 100644
--- a/arch/misoc/src/lm32/lm32_blocktask.c
+++ b/arch/misoc/src/lm32/lm32_blocktask.c
@@ -45,110 +45,71 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (g_current_regs)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the g_current_regs into the OLD rtcb.
+       */
 
-      if (g_current_regs)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the g_current_regs into the OLD rtcb.
-           */
+      up_savestate(rtcb->xcp.regs);
 
-          up_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Then switch contexts.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
-
-          up_restorestate(rtcb->xcp.regs);
-        }
+      up_restorestate(rtcb->xcp.regs);
+    }
 
-      /* No, then we will need to perform the user context switch */
+  /* No, then we will need to perform the user context switch */
 
-      else
-        {
-          /* Get the context of the task at the head of the ready to
-           * run list.
-           */
+  else
+    {
+      /* Get the context of the task at the head of the ready to
+       * run list.
+       */
 
-          struct tcb_s *nexttcb = this_task();
+      struct tcb_s *nexttcb = this_task();
 
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(nexttcb);
+      nxsched_resume_scheduler(nexttcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+      up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
 
-          /* up_switchcontext forces a context switch to the task at the
-           * head of the ready-to-run list.  It does not 'return' in the
-           * normal sense.  When it does return, it is because the blocked
-           * task is again ready to run and has execution priority.
-           */
-        }
+      /* up_switchcontext forces a context switch to the task at the
+       * head of the ready-to-run list.  It does not 'return' in the
+       * normal sense.  When it does return, it is because the blocked
+       * task is again ready to run and has execution priority.
+       */
     }
 }
diff --git a/arch/misoc/src/lm32/lm32_reprioritizertr.c 
b/arch/misoc/src/lm32/lm32_reprioritizertr.c
index 97a2568b8a..dd4e766a98 100644
--- a/arch/misoc/src/lm32/lm32_reprioritizertr.c
+++ b/arch/misoc/src/lm32/lm32_reprioritizertr.c
@@ -89,7 +89,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/misoc/src/minerva/minerva_blocktask.c 
b/arch/misoc/src/minerva/minerva_blocktask.c
index 6c6349af40..07888c91ab 100644
--- a/arch/misoc/src/minerva/minerva_blocktask.c
+++ b/arch/misoc/src/minerva/minerva_blocktask.c
@@ -45,110 +45,71 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t) task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run task
-   * list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (g_current_regs)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently. Just copy the
+       * g_current_regs into the OLD rtcb.
+       */
 
-      if (g_current_regs)
-        {
-          /* Yes, then we have to do things differently. Just copy the
-           * g_current_regs into the OLD rtcb.
-           */
+      up_savestate(rtcb->xcp.regs);
 
-          up_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head of
+       * the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head of
-           * the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any necessary address environment changes
+       * will be made when the interrupt returns.
+       */
 
-          /* Then switch contexts.  Any necessary address environment changes
-           * will be made when the interrupt returns.
-           */
-
-          up_restorestate(rtcb->xcp.regs);
-        }
+      up_restorestate(rtcb->xcp.regs);
+    }
 
-      /* No, then we will need to perform the user context switch */
+  /* No, then we will need to perform the user context switch */
 
-      else
-        {
-          /* Get the context of the task at the head of the ready to run
-           * list.
-           */
+  else
+    {
+      /* Get the context of the task at the head of the ready to run
+       * list.
+       */
 
-          struct tcb_s *nexttcb = this_task();
+      struct tcb_s *nexttcb = this_task();
 
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(nexttcb);
+      nxsched_resume_scheduler(nexttcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+      up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
 
-          /* up_switchcontext forces a context switch to the task at the head
-           * of the ready-to-run list.  It does not 'return' in the normal
-           * sense.  When it does return, it is because the blocked task is
-           * again ready to run and has execution priority.
-           */
-        }
+      /* up_switchcontext forces a context switch to the task at the head
+       * of the ready-to-run list.  It does not 'return' in the normal
+       * sense.  When it does return, it is because the blocked task is
+       * again ready to run and has execution priority.
+       */
     }
 }
diff --git a/arch/misoc/src/minerva/minerva_reprioritizertr.c 
b/arch/misoc/src/minerva/minerva_reprioritizertr.c
index 00edf65419..387fd0c30e 100644
--- a/arch/misoc/src/minerva/minerva_reprioritizertr.c
+++ b/arch/misoc/src/minerva/minerva_reprioritizertr.c
@@ -89,7 +89,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/or1k/src/common/up_blocktask.c 
b/arch/or1k/src/common/up_blocktask.c
index e710fc9642..f3b513409a 100644
--- a/arch/or1k/src/common/up_blocktask.c
+++ b/arch/or1k/src/common/up_blocktask.c
@@ -44,116 +44,77 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (CURRENT_REGS)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the CURRENT_REGS into the OLD rtcb.
+       */
 
-      if (CURRENT_REGS)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the CURRENT_REGS into the OLD rtcb.
-           */
+      up_savestate(rtcb->xcp.regs);
 
-          up_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Then switch contexts.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
+      up_restorestate(rtcb->xcp.regs);
+    }
 
-          up_restorestate(rtcb->xcp.regs);
-        }
+  /* Copy the user C context into the TCB at the (old) head of the
+   * ready-to-run Task list. if up_saveusercontext returns a non-zero
+   * value, then this is really the previously running task restarting!
+   */
 
-      /* Copy the user C context into the TCB at the (old) head of the
-       * ready-to-run Task list. if up_saveusercontext returns a non-zero
-       * value, then this is really the previously running task restarting!
+  else if (!up_saveusercontext(rtcb->xcp.regs))
+    {
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
        */
 
-      else if (!up_saveusercontext(rtcb->xcp.regs))
-        {
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
-
-          rtcb = this_task();
+      rtcb = this_task();
 
 #ifdef CONFIG_ARCH_ADDRENV
-          /* Make sure that the address environment for the previously
-           * running task is closed down gracefully (data caches dump,
-           * MMU flushed) and set up the address environment for the new
-           * thread at the head of the ready-to-run list.
-           */
+      /* Make sure that the address environment for the previously
+       * running task is closed down gracefully (data caches dump,
+       * MMU flushed) and set up the address environment for the new
+       * thread at the head of the ready-to-run list.
+       */
 
-          group_addrenv(rtcb);
+      group_addrenv(rtcb);
 #endif
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(rtcb);
+      nxsched_resume_scheduler(rtcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          up_fullcontextrestore(rtcb->xcp.regs);
-        }
+      up_fullcontextrestore(rtcb->xcp.regs);
     }
 }
diff --git a/arch/or1k/src/common/up_reprioritizertr.c 
b/arch/or1k/src/common/up_reprioritizertr.c
index 2a7c315b4a..363e11a900 100644
--- a/arch/or1k/src/common/up_reprioritizertr.c
+++ b/arch/or1k/src/common/up_reprioritizertr.c
@@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/renesas/src/common/up_blocktask.c 
b/arch/renesas/src/common/up_blocktask.c
index 7b8ac5276a..83221fcb88 100644
--- a/arch/renesas/src/common/up_blocktask.c
+++ b/arch/renesas/src/common/up_blocktask.c
@@ -43,117 +43,78 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (g_current_regs)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the g_current_regs into the OLD rtcb.
+       */
 
-      if (g_current_regs)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the g_current_regs into the OLD rtcb.
-           */
+      up_savestate(rtcb->xcp.regs);
 
-          up_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Then switch contexts.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
+      g_current_regs = rtcb->xcp.regs;
+    }
 
-          g_current_regs = rtcb->xcp.regs;
-        }
+  /* Copy the user C context into the TCB at the (old) head of the
+   * ready-to-run Task list. if up_saveusercontext returns a non-zero
+   * value, then this is really the previously running task
+   * restarting!
+   */
 
-      /* Copy the user C context into the TCB at the (old) head of the
-       * ready-to-run Task list. if up_saveusercontext returns a non-zero
-       * value, then this is really the previously running task
-       * restarting!
+  else if (!up_saveusercontext(rtcb->xcp.regs))
+    {
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
        */
 
-      else if (!up_saveusercontext(rtcb->xcp.regs))
-        {
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
-
-          rtcb = this_task();
+      rtcb = this_task();
 
 #ifdef CONFIG_ARCH_ADDRENV
-          /* Make sure that the address environment for the previously
-           * running task is closed down gracefully (data caches dump,
-           * MMU flushed) and set up the address environment for the new
-           * thread at the head of the ready-to-run list.
-           */
+      /* Make sure that the address environment for the previously
+       * running task is closed down gracefully (data caches dump,
+       * MMU flushed) and set up the address environment for the new
+       * thread at the head of the ready-to-run list.
+       */
 
-          group_addrenv(rtcb);
+      group_addrenv(rtcb);
 #endif
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(rtcb);
+      nxsched_resume_scheduler(rtcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          up_fullcontextrestore(rtcb->xcp.regs);
-        }
+      up_fullcontextrestore(rtcb->xcp.regs);
     }
 }
diff --git a/arch/renesas/src/common/up_reprioritizertr.c 
b/arch/renesas/src/common/up_reprioritizertr.c
index c0f03925fa..cc41f8ace6 100644
--- a/arch/renesas/src/common/up_reprioritizertr.c
+++ b/arch/renesas/src/common/up_reprioritizertr.c
@@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/risc-v/src/common/riscv_blocktask.c 
b/arch/risc-v/src/common/riscv_blocktask.c
index b3833c225a..94d3207a67 100644
--- a/arch/risc-v/src/common/riscv_blocktask.c
+++ b/arch/risc-v/src/common/riscv_blocktask.c
@@ -45,110 +45,71 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (CURRENT_REGS)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the CURRENT_REGS into the OLD rtcb.
+       */
 
-      if (CURRENT_REGS)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the CURRENT_REGS into the OLD rtcb.
-           */
+      riscv_savestate(rtcb->xcp.regs);
 
-          riscv_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Then switch contexts.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
-
-          riscv_restorestate(rtcb->xcp.regs);
-        }
+      riscv_restorestate(rtcb->xcp.regs);
+    }
 
-      /* No, then we will need to perform the user context switch */
+  /* No, then we will need to perform the user context switch */
 
-      else
-        {
-          /* Get the context of the task at the head of the ready to
-           * run list.
-           */
+  else
+    {
+      /* Get the context of the task at the head of the ready to
+       * run list.
+       */
 
-          struct tcb_s *nexttcb = this_task();
+      struct tcb_s *nexttcb = this_task();
 
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(nexttcb);
+      nxsched_resume_scheduler(nexttcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          riscv_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
+      riscv_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
 
-          /* riscv_switchcontext forces a context switch to the task at the
-           * head of the ready-to-run list.  It does not 'return' in the
-           * normal sense.  When it does return, it is because the blocked
-           * task is again ready to run and has execution priority.
-           */
-        }
+      /* riscv_switchcontext forces a context switch to the task at the
+       * head of the ready-to-run list.  It does not 'return' in the
+       * normal sense.  When it does return, it is because the blocked
+       * task is again ready to run and has execution priority.
+       */
     }
 }
diff --git a/arch/risc-v/src/common/riscv_reprioritizertr.c 
b/arch/risc-v/src/common/riscv_reprioritizertr.c
index 02c6e9f2e0..53fd2abb34 100644
--- a/arch/risc-v/src/common/riscv_reprioritizertr.c
+++ b/arch/risc-v/src/common/riscv_reprioritizertr.c
@@ -89,7 +89,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/sim/src/sim/up_blocktask.c b/arch/sim/src/sim/up_blocktask.c
index 779d283cce..acd1d87e64 100644
--- a/arch/sim/src/sim/up_blocktask.c
+++ b/arch/sim/src/sim/up_blocktask.c
@@ -43,103 +43,62 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* TODO */
 
-  /* sinfo("Blocking TCB=%p\n", tcb); */
-
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
+  if (CURRENT_REGS)
     {
-      switch_needed |= nxsched_merge_pending();
+      ASSERT(false);
     }
 
-  /* Now, perform the context switch if one is needed */
+  /* Copy the exception context into the TCB at the (old) head of the
+   * ready-to-run Task list. if setjmp returns a non-zero
+   * value, then this is really the previously running task restarting!
+   */
 
-  if (switch_needed)
+  else if (!setjmp(rtcb->xcp.regs))
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* TODO */
-
-      if (CURRENT_REGS)
-        {
-          ASSERT(false);
-        }
-
-      /* Copy the exception context into the TCB at the (old) head of the
-       * ready-to-run Task list. if setjmp returns a non-zero
-       * value, then this is really the previously running task restarting!
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
        */
 
-      else if (!setjmp(rtcb->xcp.regs))
-        {
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
+      sinfo("New Active Task TCB=%p\n", rtcb);
 
-          rtcb = this_task();
-          sinfo("New Active Task TCB=%p\n", rtcb);
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Restore the cpu lock */
 
-          /* Restore the cpu lock */
+      restore_critical_section();
 
-          restore_critical_section();
+      /* Then switch contexts */
 
-          /* Then switch contexts */
-
-          longjmp(rtcb->xcp.regs, 1);
-        }
-      else
-        {
-          /* The way that we handle signals in the simulation is kind of
-           * a kludge.  This would be unsafe in a truly multi-threaded,
-           * interrupt driven environment.
-           */
+      longjmp(rtcb->xcp.regs, 1);
+    }
+  else
+    {
+      /* The way that we handle signals in the simulation is kind of
+       * a kludge.  This would be unsafe in a truly multi-threaded,
+       * interrupt driven environment.
+       */
 
-          sim_sigdeliver();
-        }
+      sim_sigdeliver();
     }
 }
diff --git a/arch/sim/src/sim/up_reprioritizertr.c 
b/arch/sim/src/sim/up_reprioritizertr.c
index db2f143688..2b5b0807b0 100644
--- a/arch/sim/src/sim/up_reprioritizertr.c
+++ b/arch/sim/src/sim/up_reprioritizertr.c
@@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/sparc/src/sparc_v8/up_blocktask.c 
b/arch/sparc/src/sparc_v8/up_blocktask.c
index a80b4f48bb..c932da5a84 100644
--- a/arch/sparc/src/sparc_v8/up_blocktask.c
+++ b/arch/sparc/src/sparc_v8/up_blocktask.c
@@ -45,112 +45,71 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of
- *   the ready to run list must be stopped.  Save its context
- *   and move it to the inactive list specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally
- *     the task at the head of the list).  It most be
- *     stopped, its context saved and moved into one of the
- *     waiting task lists.  It it was the task at the head
- *     of the ready-to-run list, then a context to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should be
- *     hold the blocked task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we
-   * are blocking the task at the head of the task list (the
-   * most likely case), then a context switch to the next
-   * ready-to-run task is needed. In this case, it should
-   * also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (CURRENT_REGS)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the CURRENT_REGS into the OLD rtcb.
+       */
 
-      if (CURRENT_REGS)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the CURRENT_REGS into the OLD rtcb.
-           */
+      up_savestate(rtcb->xcp.regs);
 
-          up_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Then switch contexts.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
-
-          up_restorestate(rtcb->xcp.regs);
-        }
+      up_restorestate(rtcb->xcp.regs);
+    }
 
-      /* No, then we will need to perform the user context switch */
+  /* No, then we will need to perform the user context switch */
 
-      else
-        {
-          /* Get the context of the task at the head of the ready to
-           * run list.
-           */
+  else
+    {
+      /* Get the context of the task at the head of the ready to
+       * run list.
+       */
 
-          struct tcb_s *nexttcb = this_task();
+      struct tcb_s *nexttcb = this_task();
 
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(nexttcb);
+      nxsched_resume_scheduler(nexttcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+      up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
 
-          /* up_switchcontext forces a context switch to the task at the
-           * head of the ready-to-run list.  It does not 'return' in the
-           * normal sense.  When it does return, it is because the blocked
-           * task is again ready to run and has execution priority.
-           */
-        }
+      /* up_switchcontext forces a context switch to the task at the
+       * head of the ready-to-run list.  It does not 'return' in the
+       * normal sense.  When it does return, it is because the blocked
+       * task is again ready to run and has execution priority.
+       */
     }
 }
diff --git a/arch/sparc/src/sparc_v8/up_reprioritizertr.c 
b/arch/sparc/src/sparc_v8/up_reprioritizertr.c
index 1a8c575328..cf5946fbae 100644
--- a/arch/sparc/src/sparc_v8/up_reprioritizertr.c
+++ b/arch/sparc/src/sparc_v8/up_reprioritizertr.c
@@ -88,7 +88,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/x86/src/common/up_blocktask.c 
b/arch/x86/src/common/up_blocktask.c
index e51dfae540..0bcaccc60c 100644
--- a/arch/x86/src/common/up_blocktask.c
+++ b/arch/x86/src/common/up_blocktask.c
@@ -44,117 +44,78 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (g_current_regs)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the g_current_regs into the OLD rtcb.
+       */
 
-      if (g_current_regs)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the g_current_regs into the OLD rtcb.
-           */
+      up_savestate(rtcb->xcp.regs);
 
-          up_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Then switch contexts.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
+      up_restorestate(rtcb->xcp.regs);
+    }
 
-          up_restorestate(rtcb->xcp.regs);
-        }
+  /* Copy the user C context into the TCB at the (old) head of the
+   * ready-to-run Task list. if up_saveusercontext returns a non-zero
+   * value, then this is really the previously running task
+   * restarting!
+   */
 
-      /* Copy the user C context into the TCB at the (old) head of the
-       * ready-to-run Task list. if up_saveusercontext returns a non-zero
-       * value, then this is really the previously running task
-       * restarting!
+  else if (!up_saveusercontext(rtcb->xcp.regs))
+    {
+      /* Restore the exception context of the rtcb at the (new)
+       * head of the ready-to-run task list.
        */
 
-      else if (!up_saveusercontext(rtcb->xcp.regs))
-        {
-          /* Restore the exception context of the rtcb at the (new)
-           * head of the ready-to-run task list.
-           */
-
-          rtcb = this_task();
+      rtcb = this_task();
 
 #ifdef CONFIG_ARCH_ADDRENV
-          /* Make sure that the address environment for the previously
-           * running task is closed down gracefully (data caches dump,
-           * MMU flushed) and set up the address environment for the new
-           * thread at the head of the ready-to-run list.
-           */
+      /* Make sure that the address environment for the previously
+       * running task is closed down gracefully (data caches dump,
+       * MMU flushed) and set up the address environment for the new
+       * thread at the head of the ready-to-run list.
+       */
 
-          group_addrenv(rtcb);
+      group_addrenv(rtcb);
 #endif
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(rtcb);
+      nxsched_resume_scheduler(rtcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          up_fullcontextrestore(rtcb->xcp.regs);
-        }
+      up_fullcontextrestore(rtcb->xcp.regs);
     }
 }
diff --git a/arch/x86/src/common/up_reprioritizertr.c 
b/arch/x86/src/common/up_reprioritizertr.c
index 7442508078..3489854c87 100644
--- a/arch/x86/src/common/up_reprioritizertr.c
+++ b/arch/x86/src/common/up_reprioritizertr.c
@@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/x86_64/src/common/up_blocktask.c 
b/arch/x86_64/src/common/up_blocktask.c
index f87c5e9a46..11d229fdbc 100644
--- a/arch/x86_64/src/common/up_blocktask.c
+++ b/arch/x86_64/src/common/up_blocktask.c
@@ -44,118 +44,79 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-         (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (g_current_regs)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the g_current_regs into the OLD rtcb.
+       */
 
-      if (g_current_regs)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the g_current_regs into the OLD rtcb.
-           */
+      up_savestate(rtcb->xcp.regs);
 
-          up_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
+      up_restore_auxstate(rtcb);
 
-          rtcb = this_task();
-          up_restore_auxstate(rtcb);
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Then switch contexts.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
+      up_restorestate(rtcb->xcp.regs);
+    }
 
-          up_restorestate(rtcb->xcp.regs);
-        }
+  /* Copy the user C context into the TCB at the (old) head of the
+   * ready-to-run Task list. if up_saveusercontext returns a non-zero
+   * value, then this is really the previously running task restarting!
+   */
 
-      /* Copy the user C context into the TCB at the (old) head of the
-       * ready-to-run Task list. if up_saveusercontext returns a non-zero
-       * value, then this is really the previously running task restarting!
+  else if (!up_saveusercontext(rtcb->xcp.regs))
+    {
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
        */
 
-      else if (!up_saveusercontext(rtcb->xcp.regs))
-        {
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
-
-          rtcb = this_task();
-          up_restore_auxstate(rtcb);
+      rtcb = this_task();
+      up_restore_auxstate(rtcb);
 
 #ifdef CONFIG_ARCH_ADDRENV
-          /* Make sure that the address environment for the previously
-           * running task is closed down gracefully (data caches dump,
-           * MMU flushed) and set up the address environment for the new
-           * thread at the head of the ready-to-run list.
-           */
+      /* Make sure that the address environment for the previously
+       * running task is closed down gracefully (data caches dump,
+       * MMU flushed) and set up the address environment for the new
+       * thread at the head of the ready-to-run list.
+       */
 
-          group_addrenv(rtcb);
+      group_addrenv(rtcb);
 #endif
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(rtcb);
+      nxsched_resume_scheduler(rtcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          up_fullcontextrestore(rtcb->xcp.regs);
-        }
+      up_fullcontextrestore(rtcb->xcp.regs);
     }
 }
diff --git a/arch/x86_64/src/common/up_reprioritizertr.c 
b/arch/x86_64/src/common/up_reprioritizertr.c
index 7b4f01da6a..15f4ae9c7c 100644
--- a/arch/x86_64/src/common/up_reprioritizertr.c
+++ b/arch/x86_64/src/common/up_reprioritizertr.c
@@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/xtensa/src/common/xtensa_blocktask.c 
b/arch/xtensa/src/common/xtensa_blocktask.c
index c62ad63064..4c75cf099d 100644
--- a/arch/xtensa/src/common/xtensa_blocktask.c
+++ b/arch/xtensa/src/common/xtensa_blocktask.c
@@ -45,108 +45,69 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(struct tcb_s *rtcb)
 {
-  struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (CURRENT_REGS)
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the CURRENT_REGS into the OLD rtcb.
+       */
 
-      if (CURRENT_REGS)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the CURRENT_REGS into the OLD rtcb.
-           */
+      xtensa_savestate(rtcb->xcp.regs);
 
-          xtensa_savestate(rtcb->xcp.regs);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then switch contexts.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Then switch contexts.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
-
-          xtensa_restorestate(rtcb->xcp.regs);
-        }
+      xtensa_restorestate(rtcb->xcp.regs);
+    }
 
-      /* No, then we will need to perform the user context switch */
+  /* No, then we will need to perform the user context switch */
 
-      else
-        {
-          struct tcb_s *nexttcb = this_task();
+  else
+    {
+      struct tcb_s *nexttcb = this_task();
 
-          /* Switch context to the context of the task at the head of the
-           * ready to run list.
-           */
+      /* Switch context to the context of the task at the head of the
+       * ready to run list.
+       */
 
-          nxsched_resume_scheduler(nexttcb);
+      nxsched_resume_scheduler(nexttcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          xtensa_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
+      xtensa_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
 
-          /* xtensa_switchcontext forces a context switch to the task at the
-           * head of the ready-to-run list.  It does not 'return' in the
-           * normal sense.  When it does return, it is because the blocked
-           * task is again ready to run and has execution priority.
-           */
-        }
+      /* xtensa_switchcontext forces a context switch to the task at the
+       * head of the ready-to-run list.  It does not 'return' in the
+       * normal sense.  When it does return, it is because the blocked
+       * task is again ready to run and has execution priority.
+       */
     }
 }
diff --git a/arch/xtensa/src/common/xtensa_reprioritizertr.c 
b/arch/xtensa/src/common/xtensa_reprioritizertr.c
index 5360f7fff4..55eec2dd82 100644
--- a/arch/xtensa/src/common/xtensa_reprioritizertr.c
+++ b/arch/xtensa/src/common/xtensa_reprioritizertr.c
@@ -89,7 +89,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/z16/src/common/z16_blocktask.c 
b/arch/z16/src/common/z16_blocktask.c
index 0428f7c187..b6d593b5ce 100644
--- a/arch/z16/src/common/z16_blocktask.c
+++ b/arch/z16/src/common/z16_blocktask.c
@@ -43,109 +43,68 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(FAR struct tcb_s *rtcb)
 {
-  FAR struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* sinfo("Blocking TCB=%p\n", tcb); */
-
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
+  if (IN_INTERRUPT)
     {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
-    {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the current registers into the OLD rtcb.
+       */
 
-      if (IN_INTERRUPT)
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the current registers into the OLD rtcb.
-           */
+      SAVE_IRQCONTEXT(rtcb);
 
-          SAVE_IRQCONTEXT(rtcb);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then setup so that the context will be performed on exit
+       * from the interrupt.
+       */
 
-          /* Then setup so that the context will be performed on exit
-           * from the interrupt.
-           */
+      SET_IRQCONTEXT(rtcb);
+    }
 
-          SET_IRQCONTEXT(rtcb);
-        }
+  /* Copy the user C context into the TCB at the (old) head of the
+   * ready-to-run Task list. if SAVE_USERCONTEXT returns a non-zero
+   * value, then this is really the previously running task restarting!
+   */
 
-      /* Copy the user C context into the TCB at the (old) head of the
-       * ready-to-run Task list. if SAVE_USERCONTEXT returns a non-zero
-       * value, then this is really the previously running task restarting!
+  else if (!SAVE_USERCONTEXT(rtcb))
+    {
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
        */
 
-      else if (!SAVE_USERCONTEXT(rtcb))
-        {
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
-
-          rtcb = this_task();
+      rtcb = this_task();
 
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(rtcb);
+      nxsched_resume_scheduler(rtcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          RESTORE_USERCONTEXT(rtcb);
-        }
+      RESTORE_USERCONTEXT(rtcb);
     }
 }
diff --git a/arch/z16/src/common/z16_reprioritizertr.c 
b/arch/z16/src/common/z16_reprioritizertr.c
index 15a9124b7a..8e57088d2a 100644
--- a/arch/z16/src/common/z16_reprioritizertr.c
+++ b/arch/z16/src/common/z16_reprioritizertr.c
@@ -88,7 +88,7 @@ void up_reprioritize_rtr(FAR struct tcb_s *tcb, uint8_t 
priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/arch/z80/src/common/z80_blocktask.c 
b/arch/z80/src/common/z80_blocktask.c
index ed40a56105..9cf83eb48c 100644
--- a/arch/z80/src/common/z80_blocktask.c
+++ b/arch/z80/src/common/z80_blocktask.c
@@ -45,119 +45,78 @@
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new
- *     ready to run task must be performed.
- *   task_state: Specifies which waiting task list should hold the blocked
- *     task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state)
+void up_block_task(FAR struct tcb_s *rtcb)
 {
-  FAR struct tcb_s *rtcb = this_task();
-  bool switch_needed;
+  /* Update scheduler parameters */
 
-  /* Verify that the context switch can be performed */
+  nxsched_suspend_scheduler(rtcb);
 
-  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
-              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+  /* Are we in an interrupt handler? */
 
-  /* _info("Blocking TCB=%p\n", tcb); */
-
-  /* Remove the tcb task from the ready-to-run list.  If we are blocking the
-   * task at the head of the task list (the most likely case), then a
-   * context switch to the next ready-to-run task is needed. In this case,
-   * it should also be true that rtcb == tcb.
-   */
-
-  switch_needed = nxsched_remove_readytorun(tcb);
-
-  /* Add the task to the specified blocked task list */
-
-  nxsched_add_blocked(tcb, (tstate_t)task_state);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head)
-    {
-      switch_needed |= nxsched_merge_pending();
-    }
-
-  /* Now, perform the context switch if one is needed */
-
-  if (switch_needed)
+  if (IN_INTERRUPT())
     {
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(rtcb);
-
-      /* Are we in an interrupt handler? */
+      /* Yes, then we have to do things differently.
+       * Just copy the current registers into the OLD rtcb.
+       */
 
-      if (IN_INTERRUPT())
-        {
-          /* Yes, then we have to do things differently.
-           * Just copy the current registers into the OLD rtcb.
-           */
+      SAVE_IRQCONTEXT(rtcb);
 
-          SAVE_IRQCONTEXT(rtcb);
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
+       */
 
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
+      rtcb = this_task();
 
-          rtcb = this_task();
+      /* Reset scheduler parameters */
 
-          /* Reset scheduler parameters */
+      nxsched_resume_scheduler(rtcb);
 
-          nxsched_resume_scheduler(rtcb);
+      /* Then setup so that the context will be performed on exit
+       * from the interrupt.  Any necessary address environment
+       * changes will be made when the interrupt returns.
+       */
 
-          /* Then setup so that the context will be performed on exit
-           * from the interrupt.  Any necessary address environment
-           * changes will be made when the interrupt returns.
-           */
+      SET_IRQCONTEXT(rtcb);
+    }
 
-          SET_IRQCONTEXT(rtcb);
-        }
+  /* Copy the user C context into the TCB at the (old) head of the
+   * ready-to-run Task list. if SAVE_USERCONTEXT returns a non-zero
+   * value, then this is really the previously running task restarting!
+   */
 
-      /* Copy the user C context into the TCB at the (old) head of the
-       * ready-to-run Task list. if SAVE_USERCONTEXT returns a non-zero
-       * value, then this is really the previously running task restarting!
+  else if (!SAVE_USERCONTEXT(rtcb))
+    {
+      /* Restore the exception context of the rtcb at the (new) head
+       * of the ready-to-run task list.
        */
 
-      else if (!SAVE_USERCONTEXT(rtcb))
-        {
-          /* Restore the exception context of the rtcb at the (new) head
-           * of the ready-to-run task list.
-           */
-
-          rtcb = this_task();
+      rtcb = this_task();
 
 #ifdef CONFIG_ARCH_ADDRENV
-          /* Make sure that the address environment for the previously
-           * running task is closed down gracefully (data caches dump,
-           * MMU flushed) and set up the address environment for the new
-           * thread at the head of the ready-to-run list.
-           */
+      /* Make sure that the address environment for the previously
+       * running task is closed down gracefully (data caches dump,
+       * MMU flushed) and set up the address environment for the new
+       * thread at the head of the ready-to-run list.
+       */
 
-          group_addrenv(rtcb);
+      group_addrenv(rtcb);
 #endif
-          /* Reset scheduler parameters */
+      /* Reset scheduler parameters */
 
-          nxsched_resume_scheduler(rtcb);
+      nxsched_resume_scheduler(rtcb);
 
-          /* Then switch contexts */
+      /* Then switch contexts */
 
-          RESTORE_USERCONTEXT(rtcb);
-        }
+      RESTORE_USERCONTEXT(rtcb);
     }
 }
diff --git a/arch/z80/src/common/z80_reprioritizertr.c 
b/arch/z80/src/common/z80_reprioritizertr.c
index 5ceb2ca57d..9d5f97bdca 100644
--- a/arch/z80/src/common/z80_reprioritizertr.c
+++ b/arch/z80/src/common/z80_reprioritizertr.c
@@ -90,7 +90,7 @@ void up_reprioritize_rtr(FAR struct tcb_s *tcb, uint8_t 
priority)
        * remove the head of the ready to run list.
        */
 
-      switch_needed = nxsched_remove_readytorun(tcb);
+      switch_needed = nxsched_remove_readytorun(tcb, false);
 
       /* Setup up the new task priority */
 
diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h
index 6eee128995..dd45c4de5d 100644
--- a/include/nuttx/arch.h
+++ b/include/nuttx/arch.h
@@ -407,25 +407,20 @@ void up_unblock_task(FAR struct tcb_s *tcb, FAR struct 
tcb_s *rtcb);
  * Name: up_block_task
  *
  * Description:
- *   The currently executing task at the head of the ready to run list must
- *   be stopped.  Save its context and move it to the inactive list
- *   specified by task_state.
+ *   The currently executing task has already removed from ready-to-run list.
+ *   Save its context and switch to the next running task at the head of the
+ *   ready-to-run list.
  *
  *   This function is called only from the NuttX scheduling logic.
  *   Interrupts will always be disabled when this function is called.
  *
  * Input Parameters:
- *   tcb: Refers to a task in the ready-to-run list (normally the task at
- *     the head of the list).  It must be stopped, its context saved and
- *     moved into one of the waiting task lists.  If it was the task at the
- *     head of the ready-to-run list, then a context switch to the new ready
- *     to run task must be performed.
- *   task_state: Specifies which waiting task list should be
- *     hold the blocked task TCB.
+ *   rtcb: Reference to the running task which is different to the
+ *     task (next running task) at the head of the list.
  *
  ****************************************************************************/
 
-void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state);
+void up_block_task(FAR struct tcb_s *rtcb);
 
 /****************************************************************************
  * Name: up_release_pending
diff --git a/sched/mqueue/mq_rcvinternal.c b/sched/mqueue/mq_rcvinternal.c
index c22604658f..ad1f74197f 100644
--- a/sched/mqueue/mq_rcvinternal.c
+++ b/sched/mqueue/mq_rcvinternal.c
@@ -24,6 +24,7 @@
 
 #include <nuttx/config.h>
 
+#include <stdbool.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include <string.h>
@@ -135,6 +136,7 @@ int nxmq_wait_receive(FAR struct mqueue_inode_s *msgq,
 {
   FAR struct mqueue_msg_s *newmsg;
   FAR struct tcb_s *rtcb;
+  bool switch_needed;
 
   DEBUGASSERT(rcvmsg != NULL);
 
@@ -181,7 +183,22 @@ int nxmq_wait_receive(FAR struct mqueue_inode_s *msgq,
            */
 
           DEBUGASSERT(!is_idle_task(rtcb));
-          up_block_task(rtcb, TSTATE_WAIT_MQNOTEMPTY);
+
+          /* Remove the tcb task from the ready-to-run list. */
+
+          switch_needed = nxsched_remove_readytorun(rtcb, true);
+
+          /* Add the task to the specified blocked task list */
+
+          rtcb->task_state = TSTATE_WAIT_MQNOTEMPTY;
+          nxsched_add_prioritized(rtcb, MQ_WNELIST(msgq->cmn));
+
+          /* Now, perform the context switch if one is needed */
+
+          if (switch_needed)
+            {
+              up_block_task(rtcb);
+            }
 
           /* When we resume at this point, either (1) the message queue
            * is no longer empty, or (2) the wait has been interrupted by
diff --git a/sched/mqueue/mq_sndinternal.c b/sched/mqueue/mq_sndinternal.c
index d74f9301c3..0df671bde9 100644
--- a/sched/mqueue/mq_sndinternal.c
+++ b/sched/mqueue/mq_sndinternal.c
@@ -213,6 +213,7 @@ FAR struct mqueue_msg_s *nxmq_alloc_msg(void)
 int nxmq_wait_send(FAR struct mqueue_inode_s *msgq, int oflags)
 {
   FAR struct tcb_s *rtcb;
+  bool switch_needed;
 
 #ifdef CONFIG_CANCELLATION_POINTS
   /* nxmq_wait_send() is not a cancellation point, but may be called via
@@ -267,7 +268,22 @@ int nxmq_wait_send(FAR struct mqueue_inode_s *msgq, int 
oflags)
        */
 
       DEBUGASSERT(!is_idle_task(rtcb));
-      up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL);
+
+      /* Remove the tcb task from the ready-to-run list. */
+
+      switch_needed = nxsched_remove_readytorun(rtcb, true);
+
+      /* Add the task to the specified blocked task list */
+
+      rtcb->task_state = TSTATE_WAIT_MQNOTFULL;
+      nxsched_add_prioritized(rtcb, MQ_WNFLIST(msgq->cmn));
+
+      /* Now, perform the context switch if one is needed */
+
+      if (switch_needed)
+        {
+          up_block_task(rtcb);
+        }
 
       /* When we resume at this point, either (1) the message queue
        * is no longer empty, or (2) the wait has been interrupted by
diff --git a/sched/mqueue/msgrcv.c b/sched/mqueue/msgrcv.c
index 23a33a6abf..d4def19463 100644
--- a/sched/mqueue/msgrcv.c
+++ b/sched/mqueue/msgrcv.c
@@ -43,6 +43,7 @@ static int msgrcv_wait(FAR struct msgq_s *msgq, FAR struct 
msgbuf_s **rcvmsg,
   FAR struct msgbuf_s *newmsg = NULL;
   FAR struct msgbuf_s *tmp;
   FAR struct tcb_s *rtcb;
+  bool switch_needed;
 
 #ifdef CONFIG_CANCELLATION_POINTS
   /* msgrcv_wait() is not a cancellation point, but it may be called
@@ -125,7 +126,22 @@ static int msgrcv_wait(FAR struct msgq_s *msgq, FAR struct 
msgbuf_s **rcvmsg,
        */
 
       DEBUGASSERT(NULL != rtcb->flink);
-      up_block_task(rtcb, TSTATE_WAIT_MQNOTEMPTY);
+
+      /* Remove the tcb task from the ready-to-run list. */
+
+      switch_needed = nxsched_remove_readytorun(rtcb, true);
+
+      /* Add the task to the specified blocked task list */
+
+      rtcb->task_state = TSTATE_WAIT_MQNOTEMPTY;
+      nxsched_add_prioritized(rtcb, MQ_WNELIST(msgq->cmn));
+
+      /* Now, perform the context switch if one is needed */
+
+      if (switch_needed)
+        {
+          up_block_task(rtcb);
+        }
 
       /* When we resume at this point, either (1) the message queue
        * is no longer empty, or (2) the wait has been interrupted by
diff --git a/sched/mqueue/msgsnd.c b/sched/mqueue/msgsnd.c
index f10407b132..343137e9cd 100644
--- a/sched/mqueue/msgsnd.c
+++ b/sched/mqueue/msgsnd.c
@@ -40,6 +40,7 @@
 static int msgsnd_wait(FAR struct msgq_s *msgq, int msgflg)
 {
   FAR struct tcb_s *rtcb;
+  bool switch_needed;
 
 #ifdef CONFIG_CANCELLATION_POINTS
   /* msgsnd_wait() is not a cancellation point, but may be called via
@@ -91,7 +92,22 @@ static int msgsnd_wait(FAR struct msgq_s *msgq, int msgflg)
        */
 
       DEBUGASSERT(NULL != rtcb->flink);
-      up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL);
+
+      /* Remove the tcb task from the ready-to-run list. */
+
+      switch_needed = nxsched_remove_readytorun(rtcb, true);
+
+      /* Add the task to the specified blocked task list */
+
+      rtcb->task_state = TSTATE_WAIT_MQNOTFULL;
+      nxsched_add_prioritized(rtcb, MQ_WNFLIST(msgq->cmn));
+
+      /* Now, perform the context switch if one is needed */
+
+      if (switch_needed)
+        {
+          up_block_task(rtcb);
+        }
 
       /* When we resume at this point, either (1) the message queue
        * is no longer empty, or (2) the wait has been interrupted by
diff --git a/sched/paging/pg_miss.c b/sched/paging/pg_miss.c
index 05ed83606e..6584323083 100644
--- a/sched/paging/pg_miss.c
+++ b/sched/paging/pg_miss.c
@@ -110,6 +110,7 @@ void pg_miss(void)
 {
   FAR struct tcb_s *ftcb = this_task();
   FAR struct tcb_s *wtcb;
+  bool switch_needed;
 
   /* Sanity checking
    *
@@ -134,7 +135,22 @@ void pg_miss(void)
    */
 
   DEBUGASSERT(!is_idle_task(ftcb));
-  up_block_task(ftcb, TSTATE_WAIT_PAGEFILL);
+
+  /* Remove the tcb task from the ready-to-run list. */
+
+  switch_needed = nxsched_remove_readytorun(ftcb, true);
+
+  /* Add the task to the specified blocked task list */
+
+  ftcb->task_state = TSTATE_WAIT_PAGEFILL;
+  nxsched_add_prioritized(ftcb, &g_waitingforfill);
+
+  /* Now, perform the context switch if one is needed */
+
+  if (switch_needed)
+    {
+      up_block_task(ftcb);
+    }
 
   /* Boost the page fill worker thread priority.
    * - Check the priority of the task at the head of the g_waitingforfill
diff --git a/sched/sched/sched.h b/sched/sched/sched.h
index b32a0ddda4..1a43f47dd4 100644
--- a/sched/sched/sched.h
+++ b/sched/sched/sched.h
@@ -314,7 +314,7 @@ int nxthread_create(FAR const char *name, uint8_t ttype, 
int priority,
 /* Task list manipulation functions */
 
 bool nxsched_add_readytorun(FAR struct tcb_s *rtrtcb);
-bool nxsched_remove_readytorun(FAR struct tcb_s *rtrtcb);
+bool nxsched_remove_readytorun(FAR struct tcb_s *rtrtcb, bool merge);
 bool nxsched_add_prioritized(FAR struct tcb_s *tcb, DSEG dq_queue_t *list);
 void nxsched_merge_prioritized(FAR dq_queue_t *list1, FAR dq_queue_t *list2,
                                uint8_t task_state);
diff --git a/sched/sched/sched_removereadytorun.c 
b/sched/sched/sched_removereadytorun.c
index 0b168a15fb..bd3c26ebd4 100644
--- a/sched/sched/sched_removereadytorun.c
+++ b/sched/sched/sched_removereadytorun.c
@@ -45,6 +45,7 @@
  *
  * Input Parameters:
  *   rtcb - Points to the TCB that is ready-to-run
+ *   merge - Merge pending list or not
  *
  * Returned Value:
  *   true if the currently active task (the head of the ready-to-run list)
@@ -60,7 +61,7 @@
  ****************************************************************************/
 
 #ifndef CONFIG_SMP
-bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb)
+bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb, bool merge)
 {
   bool doswitch = false;
 
@@ -92,6 +93,12 @@ bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb)
   /* Since the TCB is not in any list, it is now invalid */
 
   rtcb->task_state = TSTATE_TASK_INVALID;
+
+  if (g_pendingtasks.head && merge)
+    {
+      doswitch |= nxsched_merge_pending();
+    }
+
   return doswitch;
 }
 #endif /* !CONFIG_SMP */
@@ -104,6 +111,7 @@ bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb)
  *
  * Input Parameters:
  *   rtcb - Points to the TCB that is ready-to-run
+ *   merge - Merge pending list or not
  *
  * Returned Value:
  *   true if the currently active task (the head of the ready-to-run list)
@@ -119,7 +127,7 @@ bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb)
  ****************************************************************************/
 
 #ifdef CONFIG_SMP
-bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb)
+bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb, bool merge)
 {
   FAR dq_queue_t *tasklist;
   bool doswitch = false;
@@ -276,6 +284,11 @@ bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb)
 
   rtcb->task_state = TSTATE_TASK_INVALID;
 
+  if (g_pendingtasks.head && merge)
+    {
+      doswitch |= nxsched_merge_pending();
+    }
+
   return doswitch;
 }
 #endif /* CONFIG_SMP */
diff --git a/sched/sched/sched_setpriority.c b/sched/sched/sched_setpriority.c
index 2ae5bc11e7..292efca14c 100644
--- a/sched/sched/sched_setpriority.c
+++ b/sched/sched/sched_setpriority.c
@@ -236,7 +236,7 @@ static void nxsched_readytorun_setpriority(FAR struct tcb_s 
*tcb,
        * It should not be at the head of the list.
        */
 
-      bool check = nxsched_remove_readytorun(tcb);
+      bool check = nxsched_remove_readytorun(tcb, false);
       DEBUGASSERT(check == false);
       UNUSED(check);
 
diff --git a/sched/sched/sched_suspend.c b/sched/sched/sched_suspend.c
index 7936b7c7d4..c8725f261e 100644
--- a/sched/sched/sched_suspend.c
+++ b/sched/sched/sched_suspend.c
@@ -50,6 +50,7 @@
 void nxsched_suspend(FAR struct tcb_s *tcb)
 {
   irqstate_t flags;
+  bool switch_needed;
 
   DEBUGASSERT(tcb != NULL);
 
@@ -73,10 +74,13 @@ void nxsched_suspend(FAR struct tcb_s *tcb)
 
       /* Move the TCB to the g_stoppedtasks list. */
 
-      nxsched_add_blocked(tcb, TSTATE_TASK_STOPPED);
+      tcb->task_state = TSTATE_TASK_STOPPED;
+      dq_addlast((FAR dq_entry_t *)tcb, &g_stoppedtasks);
     }
   else
     {
+      FAR struct tcb_s *rtcb = this_task();
+
       /* The task was running or runnable before being stopped.  Simply
        * block it in the stopped state.  If tcb refers to this task, then
        * this action will block this task.
@@ -85,7 +89,22 @@ void nxsched_suspend(FAR struct tcb_s *tcb)
        */
 
       DEBUGASSERT(!is_idle_task(tcb));
-      up_block_task(tcb, TSTATE_TASK_STOPPED);
+
+      /* Remove the tcb task from the ready-to-run list. */
+
+      switch_needed = nxsched_remove_readytorun(tcb, true);
+
+      /* Add the task to the specified blocked task list */
+
+      tcb->task_state = TSTATE_TASK_STOPPED;
+      dq_addlast((FAR dq_entry_t *)tcb, &g_stoppedtasks);
+
+      /* Now, perform the context switch if one is needed */
+
+      if (switch_needed)
+        {
+          up_block_task(rtcb);
+        }
     }
 
   leave_critical_section(flags);
diff --git a/sched/semaphore/sem_wait.c b/sched/semaphore/sem_wait.c
index 67e1722469..421f37d92a 100644
--- a/sched/semaphore/sem_wait.c
+++ b/sched/semaphore/sem_wait.c
@@ -72,6 +72,7 @@ int nxsem_wait(FAR sem_t *sem)
 {
   FAR struct tcb_s *rtcb = this_task();
   irqstate_t flags;
+  bool switch_needed;
   int ret;
 
   /* This API should not be called from interrupt handlers & idleloop */
@@ -150,7 +151,22 @@ int nxsem_wait(FAR sem_t *sem)
        */
 
       DEBUGASSERT(!is_idle_task(rtcb));
-      up_block_task(rtcb, TSTATE_WAIT_SEM);
+
+      /* Remove the tcb task from the ready-to-run list. */
+
+      switch_needed = nxsched_remove_readytorun(rtcb, true);
+
+      /* Add the task to the specified blocked task list */
+
+      rtcb->task_state = TSTATE_WAIT_SEM;
+      nxsched_add_prioritized(rtcb, SEM_WAITLIST(sem));
+
+      /* Now, perform the context switch if one is needed */
+
+      if (switch_needed)
+        {
+          up_block_task(rtcb);
+        }
 
       /* When we resume at this point, either (1) the semaphore has been
        * assigned to this thread of execution, or (2) the semaphore wait
diff --git a/sched/signal/sig_suspend.c b/sched/signal/sig_suspend.c
index 0937095595..bb45c49b7a 100644
--- a/sched/signal/sig_suspend.c
+++ b/sched/signal/sig_suspend.c
@@ -80,6 +80,7 @@ int sigsuspend(FAR const sigset_t *set)
   FAR struct tcb_s *rtcb = this_task();
   sigset_t saved_sigprocmask;
   irqstate_t flags;
+  bool switch_needed;
 
   /* sigsuspend() is a cancellation point */
 
@@ -123,7 +124,22 @@ int sigsuspend(FAR const sigset_t *set)
        */
 
       DEBUGASSERT(!is_idle_task(rtcb));
-      up_block_task(rtcb, TSTATE_WAIT_SIG);
+
+      /* Remove the tcb task from the ready-to-run list. */
+
+      switch_needed = nxsched_remove_readytorun(rtcb, true);
+
+      /* Add the task to the specified blocked task list */
+
+      rtcb->task_state = TSTATE_WAIT_SIG;
+      dq_addlast((FAR dq_entry_t *)rtcb, &g_waitingforsignal);
+
+      /* Now, perform the context switch if one is needed */
+
+      if (switch_needed)
+        {
+          up_block_task(rtcb);
+        }
 
       /* We are running again, restore the original sigprocmask */
 
diff --git a/sched/signal/sig_timedwait.c b/sched/signal/sig_timedwait.c
index b0a877c228..151842c29a 100644
--- a/sched/signal/sig_timedwait.c
+++ b/sched/signal/sig_timedwait.c
@@ -243,6 +243,7 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct 
siginfo *info,
   FAR sigpendq_t *sigpend;
   irqstate_t flags;
   int32_t waitticks;
+  bool switch_needed;
   int ret;
 
   DEBUGASSERT(set != NULL);
@@ -351,7 +352,22 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct 
siginfo *info,
                */
 
               DEBUGASSERT(!is_idle_task(rtcb));
-              up_block_task(rtcb, TSTATE_WAIT_SIG);
+
+              /* Remove the tcb task from the ready-to-run list. */
+
+              switch_needed = nxsched_remove_readytorun(rtcb, true);
+
+              /* Add the task to the specified blocked task list */
+
+              rtcb->task_state = TSTATE_WAIT_SIG;
+              dq_addlast((FAR dq_entry_t *)rtcb, &g_waitingforsignal);
+
+              /* Now, perform the context switch if one is needed */
+
+              if (switch_needed)
+                {
+                  up_block_task(rtcb);
+                }
 
               /* We no longer need the watchdog */
 
@@ -378,7 +394,22 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct 
siginfo *info,
            */
 
           DEBUGASSERT(!is_idle_task(rtcb));
-          up_block_task(rtcb, TSTATE_WAIT_SIG);
+
+          /* Remove the tcb task from the ready-to-run list. */
+
+          switch_needed = nxsched_remove_readytorun(rtcb, true);
+
+          /* Add the task to the specified blocked task list */
+
+          rtcb->task_state = TSTATE_WAIT_SIG;
+          dq_addlast((FAR dq_entry_t *)rtcb, &g_waitingforsignal);
+
+          /* Now, perform the context switch if one is needed */
+
+          if (switch_needed)
+            {
+              up_block_task(rtcb);
+            }
         }
 
       /* We are running again, clear the sigwaitmask */
diff --git a/sched/task/task_exit.c b/sched/task/task_exit.c
index a66d01de3b..72ced42e9b 100644
--- a/sched/task/task_exit.c
+++ b/sched/task/task_exit.c
@@ -100,16 +100,7 @@ int nxtask_exit(void)
    * ready-to-run with state == TSTATE_TASK_RUNNING
    */
 
-  nxsched_remove_readytorun(dtcb);
-
-  /* If there are any pending tasks, then add them to the ready-to-run
-   * task list now
-   */
-
-  if (g_pendingtasks.head != NULL)
-    {
-      nxsched_merge_pending();
-    }
+  nxsched_remove_readytorun(dtcb, true);
 
   /* Get the new task at the head of the ready to run list */
 

Reply via email to