[PATCH] score: Simplify _Thread_Change_priority()

Joel Sherrill joel.sherrill at OARcorp.com
Wed May 14 15:40:19 UTC 2014



On 5/14/2014 10:32 AM, Sebastian Huber wrote:
> The function to change a thread priority was too complex.  Simplify it
> with a new scheduler operation.  This increases the average case
> performance due to the simplified logic.  The interrupt disabled
> critical section is a bit prolonged since now the extract, update and
> enqueue steps are executed atomically.  This should however not impact
> the worst-case interrupt latency since at least for the Deterministic
> Priority Scheduler this sequence can be carried out with a wee bit of
> instructions and no loops.
I tend to agree with your analysis on performance. It won't have much impact
on the Simple since the insert still dominates. We added an extract. Big 
deal.
> Add _Scheduler_Change_priority() to replace
>    - _Thread_Set_transient(),
>    - _Scheduler_Extract(),
>    - _Scheduler_Enqueue(), and
>    - _Scheduler_Enqueue_first().
Do you remain "replace the sequence"?
> Delete STATES_TRANSIENT, _States_Is_transient() and
> _Thread_Set_transient() since this state is now superfluous.
I am using essentially the same sequence to change affinity.
Set STATES_TRANSIENT, set the new affinity, remove STATES_TRANSIENT.

Are you proposing that I change to using another scheduler operation
to do that?
> With this change it is possible to get rid of the
> SCHEDULER_SMP_NODE_IN_THE_AIR state.  This considerably simplifies the
> implementation of the new SMP locking protocols.
Agreed. I am concerned about locking while changing affinity. Is the
scheduler sufficiently locked that I can scan the executing list?

> ---
>   cpukit/libmisc/capture/capture.c                   |    3 +-
>   cpukit/libmisc/monitor/mon-prmisc.c                |    1 -
>   cpukit/posix/src/pthreadexit.c                     |    5 +-
>   cpukit/posix/src/pthreadjoin.c                     |    8 +-
>   cpukit/score/Makefile.am                           |   16 +--
>   cpukit/score/include/rtems/score/scheduler.h       |   17 +-
>   cpukit/score/include/rtems/score/schedulercbs.h    |    4 +-
>   cpukit/score/include/rtems/score/scheduleredf.h    |   50 +-----
>   .../score/include/rtems/score/scheduleredfimpl.h   |   25 +++
>   cpukit/score/include/rtems/score/schedulerimpl.h   |   70 +++-----
>   .../score/include/rtems/score/schedulerpriority.h  |   54 +-----
>   .../rtems/score/schedulerpriorityaffinitysmp.h     |    6 +-
>   .../include/rtems/score/schedulerpriorityimpl.h    |   13 +-
>   .../include/rtems/score/schedulerprioritysmp.h     |   23 +--
>   cpukit/score/include/rtems/score/schedulersimple.h |   71 +-------
>   .../include/rtems/score/schedulersimpleimpl.h      |   28 +--
>   .../score/include/rtems/score/schedulersimplesmp.h |   19 +--
>   cpukit/score/include/rtems/score/schedulersmp.h    |   17 +--
>   .../score/include/rtems/score/schedulersmpimpl.h   |  184 ++++++++------------
>   cpukit/score/include/rtems/score/statesimpl.h      |   17 --
>   cpukit/score/src/schedulercbsunblock.c             |    1 +
>   cpukit/score/src/scheduleredfchangepriority.c      |   36 ++++
>   cpukit/score/src/scheduleredfenqueue.c             |   34 ----
>   cpukit/score/src/scheduleredfenqueuefirst.c        |   32 ----
>   cpukit/score/src/scheduleredfextract.c             |   34 ----
>   cpukit/score/src/scheduleredfunblock.c             |    2 +-
>   cpukit/score/src/schedulerprioritychangepriority.c |   61 +++++++
>   cpukit/score/src/schedulerpriorityenqueue.c        |   37 ----
>   cpukit/score/src/schedulerpriorityenqueuefirst.c   |   38 ----
>   cpukit/score/src/schedulerpriorityextract.c        |   30 ----
>   cpukit/score/src/schedulerprioritysmp.c            |  133 ++++++++-------
>   cpukit/score/src/schedulerpriorityupdate.c         |    2 +-
>   cpukit/score/src/schedulersimplechangepriority.c   |   41 +++++
>   cpukit/score/src/schedulersimpleenqueue.c          |   30 ----
>   cpukit/score/src/schedulersimpleenqueuefirst.c     |   29 ---
>   cpukit/score/src/schedulersimpleextract.c          |   32 ----
>   .../score/src/schedulersimplereadyqueueenqueue.c   |   32 ----
>   .../src/schedulersimplereadyqueueenqueuefirst.c    |   32 ----
>   cpukit/score/src/schedulersimplesmp.c              |  105 ++++++-----
>   cpukit/score/src/schedulersimpleunblock.c          |    5 +-
>   cpukit/score/src/schedulersimpleyield.c            |    5 +-
>   cpukit/score/src/schedulersmpvalidstatechanges.c   |   11 +-
>   cpukit/score/src/threadchangepriority.c            |   89 +++-------
>   cpukit/score/src/threadsettransient.c              |   44 -----
>   testsuites/sptests/Makefile.am                     |    1 -
>   testsuites/sptests/configure.ac                    |    1 -
>   testsuites/sptests/spintrcritical19/Makefile.am    |   20 --
>   testsuites/sptests/spintrcritical19/init.c         |  136 ---------------
>   .../sptests/spintrcritical19/spintrcritical19.doc  |   13 --
>   .../sptests/spintrcritical19/spintrcritical19.scn  |    4 -
>   50 files changed, 511 insertions(+), 1190 deletions(-)
>   create mode 100644 cpukit/score/src/scheduleredfchangepriority.c
>   delete mode 100644 cpukit/score/src/scheduleredfenqueue.c
>   delete mode 100644 cpukit/score/src/scheduleredfenqueuefirst.c
>   delete mode 100644 cpukit/score/src/scheduleredfextract.c
>   create mode 100644 cpukit/score/src/schedulerprioritychangepriority.c
>   delete mode 100644 cpukit/score/src/schedulerpriorityenqueue.c
>   delete mode 100644 cpukit/score/src/schedulerpriorityenqueuefirst.c
>   delete mode 100644 cpukit/score/src/schedulerpriorityextract.c
>   create mode 100644 cpukit/score/src/schedulersimplechangepriority.c
>   delete mode 100644 cpukit/score/src/schedulersimpleenqueue.c
>   delete mode 100644 cpukit/score/src/schedulersimpleenqueuefirst.c
>   delete mode 100644 cpukit/score/src/schedulersimpleextract.c
>   delete mode 100644 cpukit/score/src/schedulersimplereadyqueueenqueue.c
>   delete mode 100644 cpukit/score/src/schedulersimplereadyqueueenqueuefirst.c
>   delete mode 100644 cpukit/score/src/threadsettransient.c
>   delete mode 100644 testsuites/sptests/spintrcritical19/Makefile.am
>   delete mode 100644 testsuites/sptests/spintrcritical19/init.c
>   delete mode 100644 testsuites/sptests/spintrcritical19/spintrcritical19.doc
>   delete mode 100644 testsuites/sptests/spintrcritical19/spintrcritical19.scn
>
> diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
> index da9d785..118e4ff 100644
> --- a/cpukit/libmisc/capture/capture.c
> +++ b/cpukit/libmisc/capture/capture.c
> @@ -913,8 +913,7 @@ rtems_capture_switch_task (rtems_tcb* current_task,
>       rtems_capture_task_t* ht;
>
>
> -    if (_States_Is_transient (current_task->current_state)
> -     || _States_Is_dormant (current_task->current_state))
> +    if (_States_Is_dormant (current_task->current_state))
>       {
>         rtems_id ct_id = current_task->Object.id;
>
> diff --git a/cpukit/libmisc/monitor/mon-prmisc.c b/cpukit/libmisc/monitor/mon-prmisc.c
> index 9126767..b22ae55 100644
> --- a/cpukit/libmisc/monitor/mon-prmisc.c
> +++ b/cpukit/libmisc/monitor/mon-prmisc.c
> @@ -116,7 +116,6 @@ rtems_monitor_dump_priority(rtems_task_priority priority)
>   static const rtems_assoc_t rtems_monitor_state_assoc[] = {
>       { "DORM",   STATES_DORMANT, 0 },
>       { "SUSP",   STATES_SUSPENDED, 0 },
> -    { "TRANS",  STATES_TRANSIENT, 0 },
>       { "DELAY",  STATES_DELAYING, 0 },
>       { "Wtime",  STATES_WAITING_FOR_TIME, 0 },
>       { "Wbuf",   STATES_WAITING_FOR_BUFFER, 0 },
> diff --git a/cpukit/posix/src/pthreadexit.c b/cpukit/posix/src/pthreadexit.c
> index 40cd160..6b3a09a 100644
> --- a/cpukit/posix/src/pthreadexit.c
> +++ b/cpukit/posix/src/pthreadexit.c
> @@ -54,10 +54,7 @@ void _POSIX_Thread_Exit(
>           *(void **)unblocked->Wait.return_argument = value_ptr;
>         } while ( (unblocked = _Thread_queue_Dequeue( &api->Join_List )) );
>       } else {
> -      _Thread_Set_state(
> -        the_thread,
> -        STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_TRANSIENT
> -      );
> +      _Thread_Set_state( the_thread, STATES_WAITING_FOR_JOIN_AT_EXIT );
>         _Thread_Enable_dispatch();
>         /* now waiting for thread to arrive */
>         _Thread_Disable_dispatch();
> diff --git a/cpukit/posix/src/pthreadjoin.c b/cpukit/posix/src/pthreadjoin.c
> index 5033c37..136eea6 100644
> --- a/cpukit/posix/src/pthreadjoin.c
> +++ b/cpukit/posix/src/pthreadjoin.c
> @@ -61,13 +61,9 @@ on_EINTR:
>          *  Put ourself on the threads join list
>          */
>
> -      if ( the_thread->current_state ==
> -             (STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_TRANSIENT) ) {
> +      if ( the_thread->current_state == STATES_WAITING_FOR_JOIN_AT_EXIT ) {
>            return_pointer = the_thread->Wait.return_argument;
> -         _Thread_Clear_state(
> -           the_thread,
> -           (STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_TRANSIENT)
> -         );
> +         _Thread_Clear_state( the_thread, STATES_WAITING_FOR_JOIN_AT_EXIT );
>         } else {
>           executing->Wait.return_argument = &return_pointer;
>           _Thread_queue_Enter_critical_section( &api->Join_List );
> diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
> index 8fb11d7..ed68ee0 100644
> --- a/cpukit/score/Makefile.am
> +++ b/cpukit/score/Makefile.am
> @@ -208,9 +208,7 @@ libscore_a_SOURCES += src/schedulerdefaultupdate.c
>   ## SCHEDULERPRIORITY_C_FILES
>   libscore_a_SOURCES += src/schedulerpriority.c \
>       src/schedulerpriorityblock.c \
> -    src/schedulerpriorityenqueue.c \
> -    src/schedulerpriorityenqueuefirst.c \
> -    src/schedulerpriorityextract.c \
> +    src/schedulerprioritychangepriority.c \
>       src/schedulerpriorityprioritycompare.c \
>       src/schedulerpriorityschedule.c \
>       src/schedulerpriorityunblock.c \
> @@ -220,11 +218,7 @@ libscore_a_SOURCES += src/schedulerpriority.c \
>   ## SCHEDULERSIMPLE_C_FILES
>   libscore_a_SOURCES += src/schedulersimple.c \
>       src/schedulersimpleblock.c \
> -    src/schedulersimpleenqueue.c \
> -    src/schedulersimpleenqueuefirst.c \
> -    src/schedulersimpleextract.c \
> -    src/schedulersimplereadyqueueenqueue.c \
> -    src/schedulersimplereadyqueueenqueuefirst.c \
> +    src/schedulersimplechangepriority.c \
>       src/schedulersimpleschedule.c \
>       src/schedulersimpleunblock.c \
>       src/schedulersimpleyield.c
> @@ -233,9 +227,7 @@ libscore_a_SOURCES += src/schedulersimple.c \
>   libscore_a_SOURCES += src/scheduleredf.c \
>       src/scheduleredfallocate.c \
>       src/scheduleredfblock.c \
> -    src/scheduleredfenqueue.c \
> -    src/scheduleredfenqueuefirst.c \
> -    src/scheduleredfextract.c \
> +    src/scheduleredfchangepriority.c \
>       src/scheduleredfprioritycompare.c \
>       src/scheduleredfreleasejob.c \
>       src/scheduleredfschedule.c \
> @@ -282,7 +274,7 @@ libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \
>       src/threadget.c src/threadhandler.c src/threadinitialize.c \
>       src/threadloadenv.c src/threadready.c \
>       src/threadrestart.c src/threadsetpriority.c \
> -    src/threadsetstate.c src/threadsettransient.c \
> +    src/threadsetstate.c \
>       src/threadstackallocate.c src/threadstackfree.c src/threadstart.c \
>       src/threadstartmultitasking.c src/iterateoverthreads.c \
>       src/threadblockingoperationcancel.c
> diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
> index 7f0b43a..b1e8f8a 100644
> --- a/cpukit/score/include/rtems/score/scheduler.h
> +++ b/cpukit/score/include/rtems/score/scheduler.h
> @@ -63,6 +63,14 @@ typedef struct {
>     /** @see _Scheduler_Unblock() */
>     void ( *unblock )( const Scheduler_Control *, Thread_Control * );
>
> +  /** @see _Scheduler_Change_priority() */
> +  void ( *change_priority )(
> +    const Scheduler_Control *,
> +    Thread_Control *,
> +    Priority_Control,
> +    bool
> +  );
> +
>     /** @see _Scheduler_Allocate() */
>     bool ( *allocate )( const Scheduler_Control *, Thread_Control * );
>
> @@ -72,15 +80,6 @@ typedef struct {
>     /** @see _Scheduler_Update() */
>     void ( *update )( const Scheduler_Control *, Thread_Control * );
>
> -  /** @see _Scheduler_Enqueue() */
> -  void ( *enqueue )( const Scheduler_Control *, Thread_Control * );
> -
> -  /** @see _Scheduler_Enqueue_first() */
> -  void ( *enqueue_first )( const Scheduler_Control *, Thread_Control * );
> -
> -  /** @see _Scheduler_Extract() */
> -  void ( *extract )( const Scheduler_Control *, Thread_Control * );
> -
>     /** @see _Scheduler_Priority_compare() */
>     int ( *priority_compare )(
>       Priority_Control,
> diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h
> index 6cfdfbe..46db8e5 100644
> --- a/cpukit/score/include/rtems/score/schedulercbs.h
> +++ b/cpukit/score/include/rtems/score/schedulercbs.h
> @@ -52,12 +52,10 @@ extern "C" {
>       _Scheduler_EDF_Yield,            /* yield entry point */ \
>       _Scheduler_EDF_Block,            /* block entry point */ \
>       _Scheduler_CBS_Unblock,          /* unblock entry point */ \
> +    _Scheduler_EDF_Change_priority,  /* change priority entry point */ \
>       _Scheduler_CBS_Allocate,         /* allocate entry point */ \
>       _Scheduler_default_Free,         /* free entry point */ \
>       _Scheduler_EDF_Update,           /* update entry point */ \
> -    _Scheduler_EDF_Enqueue,          /* enqueue entry point */ \
> -    _Scheduler_EDF_Enqueue_first,    /* enqueue_first entry point */ \
> -    _Scheduler_EDF_Extract,          /* extract entry point */ \
>       _Scheduler_EDF_Priority_compare, /* compares two priorities */ \
>       _Scheduler_CBS_Release_job,      /* new period of task */ \
>       _Scheduler_default_Tick,         /* tick entry point */ \
> diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h
> index 95be94c..301940c 100644
> --- a/cpukit/score/include/rtems/score/scheduleredf.h
> +++ b/cpukit/score/include/rtems/score/scheduleredf.h
> @@ -45,12 +45,10 @@ extern "C" {
>       _Scheduler_EDF_Yield,            /* yield entry point */ \
>       _Scheduler_EDF_Block,            /* block entry point */ \
>       _Scheduler_EDF_Unblock,          /* unblock entry point */ \
> +    _Scheduler_EDF_Change_priority,  /* change priority entry point */ \
>       _Scheduler_EDF_Allocate,         /* allocate entry point */ \
>       _Scheduler_default_Free,         /* free entry point */ \
>       _Scheduler_EDF_Update,           /* update entry point */ \
> -    _Scheduler_EDF_Enqueue,          /* enqueue entry point */ \
> -    _Scheduler_EDF_Enqueue_first,    /* enqueue_first entry point */ \
> -    _Scheduler_EDF_Extract,          /* extract entry point */ \
>       _Scheduler_EDF_Priority_compare, /* compares two priorities */ \
>       _Scheduler_EDF_Release_job,      /* new period of task */ \
>       _Scheduler_default_Tick,         /* tick entry point */ \
> @@ -187,6 +185,13 @@ void _Scheduler_EDF_Unblock(
>     Thread_Control          *the_thread
>   );
>
> +void _Scheduler_EDF_Change_priority(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Priority_Control         new_priority,
> +  bool                     prepend_it
> +);
> +
>   /**
>    *  @brief invoked when a thread wishes to voluntarily
>    *  transfer control of the processor to another thread
> @@ -208,45 +213,6 @@ void _Scheduler_EDF_Yield(
>   );
>
>   /**
> - *  @brief Put @a the_thread to the rbtree ready queue.
> - *
> - *  This routine puts @a the_thread to the rbtree ready queue.
> - *
> - *  @param[in] the_thread will be enqueued to the ready queue.
> - */
> -void _Scheduler_EDF_Enqueue(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -);
> -
> -/**
> - *  @brief Enqueue a thread to the ready queue.
> - *
> - *  This routine puts @a the_thread to the rbtree ready queue.
> - *  For the EDF scheduler this is the same as @a _Scheduler_EDF_Enqueue.
> - *
> - *  @param[in] the_thread will be enqueued to the ready queue.
> - */
> -void _Scheduler_EDF_Enqueue_first(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -);
> -
> -/**
> - *  @brief Remove a specific thread from the scheduler's set
> - *  of ready threads.
> - *
> - *  This routine removes a specific thread from the scheduler's set
> - *  of ready threads.
> - *
> - *  @param[in] the_thread will be extracted from the ready set.
> - */
> -void _Scheduler_EDF_Extract(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -);
> -
> -/**
>    *  @brief Explicitly compare absolute dedlines (priorities) of threads.
>    *
>    * This routine explicitly compares absolute dedlines (priorities) of threads.
> diff --git a/cpukit/score/include/rtems/score/scheduleredfimpl.h b/cpukit/score/include/rtems/score/scheduleredfimpl.h
> index 8c4cd2c..d424370 100644
> --- a/cpukit/score/include/rtems/score/scheduleredfimpl.h
> +++ b/cpukit/score/include/rtems/score/scheduleredfimpl.h
> @@ -44,6 +44,31 @@ RTEMS_INLINE_ROUTINE Scheduler_EDF_Node *_Scheduler_EDF_Node_get(
>     return (Scheduler_EDF_Node *) _Scheduler_Node_get( the_thread );
>   }
>
> +RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Enqueue(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread
> +)
> +{
> +  Scheduler_EDF_Context *context =
> +    _Scheduler_EDF_Get_context( scheduler );
> +  Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
> +
> +  _RBTree_Insert( &context->Ready, &node->Node );
> +  node->queue_state = SCHEDULER_EDF_QUEUE_STATE_YES;
> +}
> +
> +RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Extract(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread
> +)
> +{
> +  Scheduler_EDF_Context *context =
> +    _Scheduler_EDF_Get_context( scheduler );
> +  Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
> +
> +  _RBTree_Extract( &context->Ready, &node->Node );
> +}
> +
>   RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Schedule_body(
>     const Scheduler_Control *scheduler,
>     Thread_Control          *the_thread,
> diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
> index 2129493..f37a355 100644
> --- a/cpukit/score/include/rtems/score/schedulerimpl.h
> +++ b/cpukit/score/include/rtems/score/schedulerimpl.h
> @@ -144,6 +144,35 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Unblock(
>   }
>
>   /**
> + * @brief Propagates a priority change of a thread to the scheduler.
> + *
> + * The caller must ensure that the thread is in the ready state.  The caller
> + * must ensure that the priority value actually changed and is not equal to the
> + * current priority value.
> + *
> + * @param[in] scheduler The scheduler instance.
> + * @param[in] the_thread The thread changing its priority.
> + * @param[in] new_priority The new thread priority.
> + * @param[in] prepend_it In case this is true, then enqueue the thread as the
> + * first of its priority group, otherwise enqueue the thread as the last of its
> + * priority group.
> + */
> +RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Priority_Control         new_priority,
> +  bool                     prepend_it
> +)
> +{
> +  ( *scheduler->Operations.change_priority )(
> +    scheduler,
> +    the_thread,
> +    new_priority,
> +    prepend_it
> +  );
> +}
> +
> +/**
>    * @brief Scheduler allocate.
>    *
>    * This routine allocates @a the_thread->scheduler
> @@ -183,47 +212,6 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Update(
>   }
>
>   /**
> - * @brief Enqueues a thread as the last of its priority group.
> - *
> - * @param[in] scheduler The scheduler instance.
> - * @param[in] the_thread The thread to enqueue.
> - */
> -RTEMS_INLINE_ROUTINE void _Scheduler_Enqueue(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  ( *scheduler->Operations.enqueue )( scheduler, the_thread );
> -}
> -
> -/**
> - * @brief Enqueues a thread as the first of its priority group.
> - *
> - * @param[in] scheduler The scheduler instance.
> - * @param[in] the_thread The thread to enqueue.
> - */
> -RTEMS_INLINE_ROUTINE void _Scheduler_Enqueue_first(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  ( *scheduler->Operations.enqueue_first )( scheduler, the_thread );
> -}
> -
> -/**
> - * @brief Scheduler extract.
> - *
> - * This routine extract @a the_thread->scheduler
> - */
> -RTEMS_INLINE_ROUTINE void _Scheduler_Extract(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  ( *scheduler->Operations.extract )( scheduler, the_thread );
> -}
> -
> -/**
>    * @brief Compares two priority values.
>    *
>    * @param[in] scheduler The scheduler instance.
> diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
> index 134dcd7..b3c1466 100644
> --- a/cpukit/score/include/rtems/score/schedulerpriority.h
> +++ b/cpukit/score/include/rtems/score/schedulerpriority.h
> @@ -52,12 +52,10 @@ extern "C" {
>       _Scheduler_priority_Yield,            /* yield entry point */ \
>       _Scheduler_priority_Block,            /* block entry point */ \
>       _Scheduler_priority_Unblock,          /* unblock entry point */ \
> -    _Scheduler_default_Allocate,         /* allocate entry point */ \
> -    _Scheduler_default_Free,             /* free entry point */ \
> +    _Scheduler_priority_Change_priority,  /* change priority entry point */ \
> +    _Scheduler_default_Allocate,          /* allocate entry point */ \
> +    _Scheduler_default_Free,              /* free entry point */ \
>       _Scheduler_priority_Update,           /* update entry point */ \
> -    _Scheduler_priority_Enqueue,          /* enqueue entry point */ \
> -    _Scheduler_priority_Enqueue_first,    /* enqueue_first entry point */ \
> -    _Scheduler_priority_Extract,          /* extract entry point */ \
>       _Scheduler_priority_Priority_compare, /* compares two priorities */ \
>       _Scheduler_default_Release_job,       /* new period of task */ \
>       _Scheduler_default_Tick,              /* tick entry point */ \
> @@ -167,6 +165,13 @@ void _Scheduler_priority_Unblock(
>     Thread_Control          *the_thread
>   );
>
> +void _Scheduler_priority_Change_priority(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Priority_Control         new_priority,
> +  bool                     prepend_it
> +);
> +
>   /**
>    *  @brief The specified THREAD yields.
>    *
> @@ -192,45 +197,6 @@ void _Scheduler_priority_Yield(
>   );
>
>   /**
> - *  @brief Puts @a the_thread on to the priority-based ready queue.
> - *
> - *  This routine puts @a the_thread on to the priority-based ready queue.
> - *
> - *  @param[in] the_thread will be enqueued at the TAIL of its priority.
> - */
> -void _Scheduler_priority_Enqueue(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -);
> -
> -/**
> - *  @brief Puts @a the_thread to the head of the ready queue.
> - *
> - *  This routine puts @a the_thread to the head of the ready queue.
> - *  For priority-based ready queues, the thread will be the first thread
> - *  at its priority level.
> - *
> - *  @param[in] the_thread will be enqueued at the HEAD of its priority.
> - */
> -void _Scheduler_priority_Enqueue_first(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -);
> -
> -/**
> - *  @brief Remove a specific thread from scheduler.
> - *
> - *  This routine removes a specific thread from the scheduler's set
> - *  of ready threads.
> - *
> - *  @param[in] the_thread will be extracted from the ready set.
> - */
> -void _Scheduler_priority_Extract(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -);
> -
> -/**
>    *  @brief Compare two priorities.
>    *
>    *  This routine compares two priorities.
> diff --git a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
> index e86fd35..c21d066 100644
> --- a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
> +++ b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
> @@ -53,13 +53,11 @@ extern "C" {
>       _Scheduler_priority_SMP_Schedule, \
>       _Scheduler_priority_SMP_Yield, \
>       _Scheduler_priority_SMP_Block, \
> -    _Scheduler_priority_SMP_Enqueue_fifo, \
> +    _Scheduler_priority_SMP_Unblock, \
> +    _Scheduler_priority_SMP_Change_priority, \
>       _Scheduler_priority_affinity_SMP_Allocate, \
>       _Scheduler_default_Free, \
>       _Scheduler_priority_SMP_Update, \
> -    _Scheduler_priority_SMP_Enqueue_fifo, \
> -    _Scheduler_priority_SMP_Enqueue_lifo, \
> -    _Scheduler_priority_SMP_Extract, \
>       _Scheduler_priority_Priority_compare, \
>       _Scheduler_default_Release_job, \
>       _Scheduler_default_Tick, \
> diff --git a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
> index ae0cd1a..95d8e6a 100644
> --- a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
> +++ b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
> @@ -196,28 +196,27 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(
>   }
>
>   /**
> - * @brief Updates the specified ready queue data according to the current
> - * priority of the thread.
> + * @brief Updates the specified ready queue data according to the new priority
> + * value.
>    *
> - * @param[in] the_thread The thread.
>    * @param[in] ready_queue The ready queue.
> + * @param[in] new_priority The new priority.
>    * @param[in] bit_map The priority bit map of the scheduler instance.
>    * @param[in] ready_queues The ready queues of the scheduler instance.
>    */
>   RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_update(
> -  Thread_Control                 *the_thread,
>     Scheduler_priority_Ready_queue *ready_queue,
> +  Priority_Control                new_priority,
>     Priority_bit_map_Control       *bit_map,
>     Chain_Control                  *ready_queues
>   )
>   {
> -  Priority_Control priority = the_thread->current_priority;
> -  ready_queue->ready_chain = &ready_queues[ priority ];
> +  ready_queue->ready_chain = &ready_queues[ new_priority ];
>
>     _Priority_bit_map_Initialize_information(
>       bit_map,
>       &ready_queue->Priority_map,
> -    priority
> +    new_priority
>     );
>   }
>
> diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
> index 3e7d22f..a22b323 100644
> --- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h
> +++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
> @@ -7,7 +7,7 @@
>    */
>
>   /*
> - * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
> + * Copyright (c) 2013-2014 embedded brains GmbH.  All rights reserved.
>    *
>    *  embedded brains GmbH
>    *  Dornierstr. 4
> @@ -82,13 +82,11 @@ typedef struct {
>       _Scheduler_priority_SMP_Schedule, \
>       _Scheduler_priority_SMP_Yield, \
>       _Scheduler_priority_SMP_Block, \
> -    _Scheduler_priority_SMP_Enqueue_fifo, \
> +    _Scheduler_priority_SMP_Unblock, \
> +    _Scheduler_priority_SMP_Change_priority, \
>       _Scheduler_priority_SMP_Allocate, \
>       _Scheduler_default_Free, \
>       _Scheduler_priority_SMP_Update, \
> -    _Scheduler_priority_SMP_Enqueue_fifo, \
> -    _Scheduler_priority_SMP_Enqueue_lifo, \
> -    _Scheduler_priority_SMP_Extract, \
>       _Scheduler_priority_Priority_compare, \
>       _Scheduler_default_Release_job, \
>       _Scheduler_default_Tick, \
> @@ -114,22 +112,19 @@ void _Scheduler_priority_SMP_Block(
>     Thread_Control *thread
>   );
>
> -void _Scheduler_priority_SMP_Update(
> +void _Scheduler_priority_SMP_Unblock(
>     const Scheduler_Control *scheduler,
>     Thread_Control *thread
>   );
>
> -void _Scheduler_priority_SMP_Enqueue_fifo(
> +void _Scheduler_priority_SMP_Change_priority(
>     const Scheduler_Control *scheduler,
> -  Thread_Control *thread
> +  Thread_Control          *the_thread,
> +  Priority_Control         new_priority,
> +  bool                     prepend_it
>   );
>
> -void _Scheduler_priority_SMP_Enqueue_lifo(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control *thread
> -);
> -
> -void _Scheduler_priority_SMP_Extract(
> +void _Scheduler_priority_SMP_Update(
>     const Scheduler_Control *scheduler,
>     Thread_Control *thread
>   );
> diff --git a/cpukit/score/include/rtems/score/schedulersimple.h b/cpukit/score/include/rtems/score/schedulersimple.h
> index 213bbb2..6b59a0a 100644
> --- a/cpukit/score/include/rtems/score/schedulersimple.h
> +++ b/cpukit/score/include/rtems/score/schedulersimple.h
> @@ -42,12 +42,10 @@ extern "C" {
>       _Scheduler_simple_Yield,              /* yield entry point */ \
>       _Scheduler_simple_Block,              /* block entry point */ \
>       _Scheduler_simple_Unblock,            /* unblock entry point */ \
> +    _Scheduler_simple_Change_priority,    /* change priority entry point */ \
>       _Scheduler_default_Allocate,          /* allocate entry point */ \
>       _Scheduler_default_Free,              /* free entry point */ \
>       _Scheduler_default_Update,            /* update entry point */ \
> -    _Scheduler_simple_Enqueue,            /* enqueue entry point */ \
> -    _Scheduler_simple_Enqueue_first,      /* enqueue_first entry point */ \
> -    _Scheduler_simple_Extract,            /* extract entry point */ \
>       _Scheduler_priority_Priority_compare, /* compares two priorities */ \
>       _Scheduler_default_Release_job,       /* new period of task */ \
>       _Scheduler_default_Tick,              /* tick entry point */ \
> @@ -136,70 +134,11 @@ void _Scheduler_simple_Unblock(
>     Thread_Control          *the_thread
>   );
>
> -/**
> - *  @brief Removes a simple-priority-based thread from a simple queue.
> - *
> - *  This routine removes a specific thread from the specified
> - *  simple-based ready queue.
> - *
> - *  @param[in] the_thread is the thread to be blocked
> - */
> -void _Scheduler_simple_Extract(
> +void _Scheduler_simple_Change_priority(
>     const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -);
> -
> -/**
> - *  @brief Puts simple-priority-based thread onto the ready queue.
> - *
> - *  This routine puts @a the_thread on to the ready queue.
> - *
> - *  @param[in] the_thread is the thread to be enqueued
> - */
> -void _Scheduler_simple_Enqueue(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -);
> -
> -/**
> - *  @brief Put simple-priority-based @a the_thread to
> - *  the head of the ready queue.
> - *
> - *  This routine puts @a the_thread to the head of the ready queue.
> - *  The thread will be the first thread at its priority level.
> - *
> - *  @param[in] the_thread is the thread to be blocked
> - */
> -void _Scheduler_simple_Enqueue_first(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -);
> -
> -/**
> - *  _Scheduler_simple_Ready_queue_enqueue
> - *
> - *  This routine puts @a the_thread on the ready queue
> - *  at the end of its priority group.
> - *
> - *  @param[in] the_thread - pointer to a thread control block
> - */
> -void _Scheduler_simple_Ready_queue_enqueue(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -);
> -
> -/**
> - *  @brief Puts simple-priority-based @a the_thread on to the ready queue
> - *  at the beginning of its priority group.
> - *
> - *  This routine puts @a the_thread on to the ready queue
> - *  at the beginning of its priority group.
> - *
> - *  @param[in] the_thread - pointer to a thread control block
> - */
> -void _Scheduler_simple_Ready_queue_enqueue_first(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> +  Thread_Control          *the_thread,
> +  Priority_Control         new_priority,
> +  bool                     prepend_it
>   );
>
>   /**@}*/
> diff --git a/cpukit/score/include/rtems/score/schedulersimpleimpl.h b/cpukit/score/include/rtems/score/schedulersimpleimpl.h
> index c256071..b73a1b2 100644
> --- a/cpukit/score/include/rtems/score/schedulersimpleimpl.h
> +++ b/cpukit/score/include/rtems/score/schedulersimpleimpl.h
> @@ -38,24 +38,6 @@ RTEMS_INLINE_ROUTINE Scheduler_simple_Context *
>     return (Scheduler_simple_Context *) _Scheduler_Get_context( scheduler );
>   }
>
> -/**
> - * This routine puts @a the_thread on to the ready queue.
> - *
> - * @param[in] the_ready_queue is a pointer to the ready queue head
> - * @param[in] the_thread is the thread to be blocked
> - */
> -RTEMS_INLINE_ROUTINE void _Scheduler_simple_Ready_queue_requeue(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  /* extract */
> -  _Chain_Extract_unprotected( &the_thread->Object.Node );
> -
> -  /* enqueue */
> -  _Scheduler_simple_Ready_queue_enqueue( scheduler, the_thread );
> -}
> -
>   RTEMS_INLINE_ROUTINE bool _Scheduler_simple_Insert_priority_lifo_order(
>     const Chain_Node *to_insert,
>     const Chain_Node *next
> @@ -102,6 +84,16 @@ RTEMS_INLINE_ROUTINE void _Scheduler_simple_Insert_priority_fifo(
>     );
>   }
>
> +RTEMS_INLINE_ROUTINE void _Scheduler_simple_Extract(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread
> +)
> +{
> +  (void) scheduler;
> +
> +  _Chain_Extract_unprotected( &the_thread->Object.Node );
> +}
> +
>   RTEMS_INLINE_ROUTINE void _Scheduler_simple_Schedule_body(
>     const Scheduler_Control *scheduler,
>     Thread_Control          *the_thread,
> diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h
> index 1e71225..9da65ce 100644
> --- a/cpukit/score/include/rtems/score/schedulersimplesmp.h
> +++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h
> @@ -63,13 +63,11 @@ typedef struct {
>       _Scheduler_simple_SMP_Schedule, \
>       _Scheduler_simple_SMP_Yield, \
>       _Scheduler_simple_SMP_Block, \
> -    _Scheduler_simple_SMP_Enqueue_priority_fifo, \
> +    _Scheduler_simple_SMP_Unblock, \
>       _Scheduler_simple_SMP_Allocate, \
> +    _Scheduler_simple_SMP_Change_priority, \
>       _Scheduler_default_Free, \
>       _Scheduler_default_Update, \
> -    _Scheduler_simple_SMP_Enqueue_priority_fifo, \
> -    _Scheduler_simple_SMP_Enqueue_priority_lifo, \
> -    _Scheduler_simple_SMP_Extract, \
>       _Scheduler_priority_Priority_compare, \
>       _Scheduler_default_Release_job, \
>       _Scheduler_default_Tick, \
> @@ -90,19 +88,16 @@ void _Scheduler_simple_SMP_Block(
>     Thread_Control *thread
>   );
>
> -void _Scheduler_simple_SMP_Enqueue_priority_fifo(
> +void _Scheduler_simple_SMP_Unblock(
>     const Scheduler_Control *scheduler,
>     Thread_Control *thread
>   );
>
> -void _Scheduler_simple_SMP_Enqueue_priority_lifo(
> +void _Scheduler_simple_SMP_Change_priority(
>     const Scheduler_Control *scheduler,
> -  Thread_Control *thread
> -);
> -
> -void _Scheduler_simple_SMP_Extract(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control *thread
> +  Thread_Control          *the_thread,
> +  Priority_Control         new_priority,
> +  bool                     prepend_it
>   );
>
>   void _Scheduler_simple_SMP_Yield(
> diff --git a/cpukit/score/include/rtems/score/schedulersmp.h b/cpukit/score/include/rtems/score/schedulersmp.h
> index ee1b087..1a7aa55 100644
> --- a/cpukit/score/include/rtems/score/schedulersmp.h
> +++ b/cpukit/score/include/rtems/score/schedulersmp.h
> @@ -80,22 +80,7 @@ typedef enum {
>      * A scheduler node is ready if the corresponding thread is ready and the
>      * scheduler did not allocate a processor for it.
>      */
> -  SCHEDULER_SMP_NODE_READY,
> -
> -  /**
> -   * @brief This scheduler node is in the air.
> -   *
> -   * A scheduled node is in the air if it has an allocated processor and the
> -   * corresponding thread is in a transient state.  Such a node is not an
> -   * element of the set of scheduled nodes.  The extract operation on a
> -   * scheduled node will produce a scheduler node in the air (see also
> -   * _Thread_Set_transient()).  The next enqueue or schedule operation will
> -   * decide what to do based on this state indication.  It can either place the
> -   * scheduler node back on the set of scheduled nodes and the thread can keep
> -   * its allocated processor, or it can take the processor away from the thread
> -   * and give the processor to another thread of higher priority.
> -   */
> -  SCHEDULER_SMP_NODE_IN_THE_AIR
> +  SCHEDULER_SMP_NODE_READY
>   } Scheduler_SMP_Node_state;
>
>   /**
> diff --git a/cpukit/score/include/rtems/score/schedulersmpimpl.h b/cpukit/score/include/rtems/score/schedulersmpimpl.h
> index 161f742..9e931c4 100644
> --- a/cpukit/score/include/rtems/score/schedulersmpimpl.h
> +++ b/cpukit/score/include/rtems/score/schedulersmpimpl.h
> @@ -37,14 +37,12 @@ extern "C" {
>    *
>    * The scheduler nodes can be in four states
>    * - @ref SCHEDULER_SMP_NODE_BLOCKED,
> - * - @ref SCHEDULER_SMP_NODE_SCHEDULED,
> - * - @ref SCHEDULER_SMP_NODE_READY, and
> - * - @ref SCHEDULER_SMP_NODE_IN_THE_AIR.
> + * - @ref SCHEDULER_SMP_NODE_SCHEDULED, and
> + * - @ref SCHEDULER_SMP_NODE_READY.
>    *
> - * State transitions are triggered via basic three operations
> - * - _Scheduler_SMP_Enqueue_ordered(),
> - * - _Scheduler_SMP_Extract(), and
> - * - _Scheduler_SMP_Schedule().
> + * State transitions are triggered via basic operations
> + * - _Scheduler_SMP_Enqueue_ordered(), and
> + * - _Scheduler_SMP_Block().
>    *
>    * @dot
>    * digraph {
> @@ -53,39 +51,26 @@ extern "C" {
>    *   bs [label="BLOCKED"];
>    *   ss [label="SCHEDULED", fillcolor="green"];
>    *   rs [label="READY", fillcolor="red"];
> - *   as [label="IN THE AIR", fillcolor="orange"];
>    *
>    *   edge [label="enqueue"];
>    *   edge [fontcolor="darkgreen", color="darkgreen"];
>    *
>    *   bs -> ss;
> - *   as -> ss;
>    *
> - *   edge [label="enqueue"];
>    *   edge [fontcolor="red", color="red"];
>    *
>    *   bs -> rs;
> - *   as -> rs;
>    *
>    *   edge [label="enqueue other"];
>    *
>    *   ss -> rs;
>    *
> - *   edge [label="schedule"];
> - *   edge [fontcolor="black", color="black"];
> - *
> - *   as -> bs;
> - *
> - *   edge [label="extract"];
> - *   edge [fontcolor="brown", color="brown"];
> - *
> - *   ss -> as;
> - *
> + *   edge [label="block"];
>    *   edge [fontcolor="black", color="black"];
>    *
>    *   rs -> bs;
>    *
> - *   edge [label="enqueue other\nschedule other"];
> + *   edge [label="block other"];
>    *   edge [fontcolor="darkgreen", color="darkgreen"];
>    *
>    *   rs -> ss;
> @@ -216,38 +201,7 @@ extern "C" {
>    * }
>    * @enddot
>    *
> - * Lets do something with A.  This can be a blocking operation or a priority
> - * change.  For this an extract operation is performed first.
> - *
> - * @dot
> - * digraph {
> - *   node [style="filled"];
> - *   edge [dir="none"];
> - *
> - *   subgraph {
> - *     rank = same;
> - *
> - *     b [label="B (2)", fillcolor="green"];
> - *     a [label="A (1)", fillcolor="orange"];
> - *     c [label="C (3)", fillcolor="red"];
> - *     i [label="I (5)", fillcolor="red"];
> - *     j [label="J (5)", fillcolor="red"];
> - *     c -> i -> j;
> - *   }
> - *
> - *   subgraph {
> - *     rank = same;
> - *
> - *     p0 [label="PROCESSOR 0", shape="box"];
> - *     p1 [label="PROCESSOR 1", shape="box"];
> - *   }
> - *
> - *   b -> p0;
> - *   a -> p1;
> - * }
> - * @enddot
> - *
> - * Lets change the priority of thread A to 4 and enqueue it.
> + * Lets change the priority of thread A to 4.
>    *
>    * @dot
>    * digraph {
> @@ -278,8 +232,9 @@ extern "C" {
>    * }
>    * @enddot
>    *
> - * Alternatively we can also do a blocking operation with thread A.  In this
> - * case schedule will be called.
> + * Now perform a blocking operation with thread B.  Please note that thread A
> + * migrated now from processor 0 to processor 1 and thread C still executes on
> + * processor 1.
>    *
>    * @dot
>    * digraph {
> @@ -289,12 +244,12 @@ extern "C" {
>    *   subgraph {
>    *     rank = same;
>    *
> - *     b [label="B (2)", fillcolor="green"];
>    *     c [label="C (3)", fillcolor="green"];
> + *     a [label="A (4)", fillcolor="green"];
>    *     i [label="I (5)", fillcolor="red"];
>    *     j [label="J (5)", fillcolor="red"];
> - *     a [label="A (1)"];
> - *     b -> c;
> + *     b [label="B (2)"];
> + *     c -> a;
>    *     i -> j;
>    *   }
>    *
> @@ -305,7 +260,7 @@ extern "C" {
>    *     p1 [label="PROCESSOR 1", shape="box"];
>    *   }
>    *
> - *   b -> p0;
> + *   a -> p0;
>    *   c -> p1;
>    * }
>    * @enddot
> @@ -332,6 +287,18 @@ typedef void ( *Scheduler_SMP_Move )(
>     Thread_Control *thread_to_move
>   );
>
> +typedef void ( *Scheduler_SMP_Update )(
> +  Scheduler_Context *context,
> +  Thread_Control *thread,
> +  Priority_Control new_priority
> +);
> +
> +typedef void ( *Scheduler_SMP_Enqueue )(
> +  Scheduler_Context *context,
> +  Thread_Control *thread_to_enqueue,
> +  bool has_processor_allocated
> +);
> +
>   static inline Scheduler_SMP_Context *_Scheduler_SMP_Get_self(
>     Scheduler_Context *context
>   )
> @@ -360,7 +327,7 @@ static inline void _Scheduler_SMP_Node_initialize(
>     node->state = SCHEDULER_SMP_NODE_BLOCKED;
>   }
>
> -extern const bool _Scheduler_SMP_Node_valid_state_changes[ 4 ][ 4 ];
> +extern const bool _Scheduler_SMP_Node_valid_state_changes[ 3 ][ 3 ];
>
>   static inline void _Scheduler_SMP_Node_change_state(
>     Scheduler_SMP_Node *node,
> @@ -467,6 +434,7 @@ static inline Thread_Control *_Scheduler_SMP_Get_lowest_scheduled(
>    *
>    * @param[in] context The scheduler instance context.
>    * @param[in] thread The thread to enqueue.
> + * @param[in] has_processor_allocated The thread has a processor allocated.
>    * @param[in] order The order function.
>    * @param[in] get_highest_ready Function to get the highest ready node.
>    * @param[in] insert_ready Function to insert a node into the set of ready
> @@ -481,6 +449,7 @@ static inline Thread_Control *_Scheduler_SMP_Get_lowest_scheduled(
>   static inline void _Scheduler_SMP_Enqueue_ordered(
>     Scheduler_Context *context,
>     Thread_Control *thread,
> +  bool has_processor_allocated,
>     Chain_Node_order order,
>     Scheduler_SMP_Get_highest_ready get_highest_ready,
>     Scheduler_SMP_Insert insert_ready,
> @@ -492,7 +461,7 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
>     Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context );
>     Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
>
> -  if ( node->state == SCHEDULER_SMP_NODE_IN_THE_AIR ) {
> +  if ( has_processor_allocated) {
>       Thread_Control *highest_ready = ( *get_highest_ready )( &self->Base );
>
>       /*
> @@ -501,10 +470,7 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
>        *
>        * NOTE: Do not exchange parameters to do the negation of the order check.
>        */
> -    if (
> -      highest_ready != NULL
> -        && !( *order )( &thread->Object.Node, &highest_ready->Object.Node )
> -    ) {
> +    if ( !( *order )( &thread->Object.Node, &highest_ready->Object.Node ) ) {
>         _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
>         _Scheduler_SMP_Allocate_processor( self, highest_ready, thread );
>         ( *insert_ready )( &self->Base, thread );
> @@ -516,18 +482,10 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
>     } else {
>       Thread_Control *lowest_scheduled =
>         _Scheduler_SMP_Get_lowest_scheduled( self );
> +    Scheduler_SMP_Node *lowest_scheduled_node =
> +      _Scheduler_SMP_Node_get( lowest_scheduled );
>
> -    /*
> -     * The scheduled chain is empty if nested interrupts change the priority of
> -     * all scheduled threads.  These threads are in the air.
> -     */
> -    if (
> -      lowest_scheduled != NULL
> -        && ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node )
> -    ) {
> -      Scheduler_SMP_Node *lowest_scheduled_node =
> -        _Scheduler_SMP_Node_get( lowest_scheduled );
> -
> +    if ( ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) ) {
>         _Scheduler_SMP_Node_change_state(
>           lowest_scheduled_node,
>           SCHEDULER_SMP_NODE_READY
> @@ -535,13 +493,15 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
>         _Scheduler_SMP_Allocate_processor( self, thread, lowest_scheduled );
>         ( *insert_scheduled )( &self->Base, thread );
>         ( *move_from_scheduled_to_ready )( &self->Base, lowest_scheduled );
> -    } else {
> -      _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
> -      ( *insert_ready )( &self->Base, thread );
>       }
>     }
>   }
>
> +static inline void _Scheduler_SMP_Extract_from_scheduled( Thread_Control *thread )
> +{
> +  _Chain_Extract_unprotected( &thread->Object.Node );
> +}
> +
>   static inline void _Scheduler_SMP_Schedule_highest_ready(
>     Scheduler_Context *context,
>     Thread_Control *victim,
> @@ -558,25 +518,31 @@ static inline void _Scheduler_SMP_Schedule_highest_ready(
>   }
>
>   /**
> - * @brief Finalize a scheduling operation.
> + * @brief Blocks a thread.
>    *
>    * @param[in] context The scheduler instance context.
>    * @param[in] thread The thread of the scheduling operation.
> + * @param[in] extract_from_ready Function to extract a node from the set of
> + * ready nodes.
>    * @param[in] get_highest_ready Function to get the highest ready node.
>    * @param[in] move_from_ready_to_scheduled Function to move a node from the set
>    * of ready nodes to the set of scheduled nodes.
>    */
> -static inline void _Scheduler_SMP_Schedule(
> +static inline void _Scheduler_SMP_Block(
>     Scheduler_Context *context,
>     Thread_Control *thread,
> +  Scheduler_SMP_Extract extract_from_ready,
>     Scheduler_SMP_Get_highest_ready get_highest_ready,
>     Scheduler_SMP_Move move_from_ready_to_scheduled
>   )
>   {
>     Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
> +  bool is_scheduled = node->state == SCHEDULER_SMP_NODE_SCHEDULED;
> +
> +  _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
>
> -  if ( node->state == SCHEDULER_SMP_NODE_IN_THE_AIR ) {
> -    _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
> +  if ( is_scheduled ) {
> +    _Scheduler_SMP_Extract_from_scheduled( thread );
>
>       _Scheduler_SMP_Schedule_highest_ready(
>         context,
> @@ -584,42 +550,38 @@ static inline void _Scheduler_SMP_Schedule(
>         get_highest_ready,
>         move_from_ready_to_scheduled
>       );
> +  } else {
> +    ( *extract_from_ready )( context, thread );
>     }
>   }
>
> -static inline void _Scheduler_SMP_Block(
> +static inline void _Scheduler_SMP_Change_priority(
>     Scheduler_Context *context,
>     Thread_Control *thread,
> -  Scheduler_SMP_Extract extract,
> -  Scheduler_SMP_Get_highest_ready get_highest_ready,
> -  Scheduler_SMP_Move move_from_ready_to_scheduled
> +  Priority_Control new_priority,
> +  bool prepend_it,
> +  Scheduler_SMP_Extract extract_from_ready,
> +  Scheduler_SMP_Update update,
> +  Scheduler_SMP_Enqueue enqueue_fifo,
> +  Scheduler_SMP_Enqueue enqueue_lifo
>   )
>   {
> -  ( *extract )( context, thread );
> +  Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
> +  bool has_processor_allocated = node->state == SCHEDULER_SMP_NODE_SCHEDULED;
>
> -  _Scheduler_SMP_Schedule(
> -    context,
> -    thread,
> -    get_highest_ready,
> -    move_from_ready_to_scheduled
> -  );
> -}
> +  if ( has_processor_allocated ) {
> +    _Scheduler_SMP_Extract_from_scheduled( thread );
> +  } else {
> +    ( *extract_from_ready )( context, thread );
> +  }
>
> -/**
> - * @brief Extracts a thread from the set of scheduled or ready nodes.
> - *
> - * @param[in] context The scheduler instance context.
> - * @param[in] thread The thread to extract.
> - * @param[in] extract Function to extract a node from the set of scheduled or
> - * ready nodes.
> - */
> -static inline void _Scheduler_SMP_Extract(
> -  Scheduler_Context *context,
> -  Thread_Control *thread,
> -  Scheduler_SMP_Extract extract
> -)
> -{
> -  ( *extract )( context, thread );
> +  ( *update )( context, thread, new_priority );
> +
> +  if ( prepend_it ) {
> +    ( *enqueue_lifo )( context, thread, has_processor_allocated );
> +  } else {
> +    ( *enqueue_fifo )( context, thread, has_processor_allocated );
> +  }
>   }
>
>   static inline void _Scheduler_SMP_Insert_scheduled_lifo(
> diff --git a/cpukit/score/include/rtems/score/statesimpl.h b/cpukit/score/include/rtems/score/statesimpl.h
> index 00d1092..4251b3c 100644
> --- a/cpukit/score/include/rtems/score/statesimpl.h
> +++ b/cpukit/score/include/rtems/score/statesimpl.h
> @@ -42,8 +42,6 @@ extern "C" {
>   #define STATES_DORMANT                         0x00001
>   /** This macro corresponds to a task being suspended. */
>   #define STATES_SUSPENDED                       0x00002
> -/** This macro corresponds to a task being in an internal state transition. */
> -#define STATES_TRANSIENT                       0x00004
>   /** This macro corresponds to a task which is waiting for a timeout. */
>   #define STATES_DELAYING                        0x00008
>   /** This macro corresponds to a task waiting until a specific TOD. */
> @@ -215,21 +213,6 @@ RTEMS_INLINE_ROUTINE bool _States_Is_suspended (
>   }
>
>   /**
> - * This function returns true if the TRANSIENT state is set in
> - * the_states, and false otherwise.
> - *
> - * @param[in] the_states is the task state set to test
> - *
> - * @return This method returns true if the desired state condition is set.
> - */
> -RTEMS_INLINE_ROUTINE bool _States_Is_transient (
> -  States_Control the_states
> -)
> -{
> -   return (the_states & STATES_TRANSIENT);
> -}
> -
> -/**
>    * This function returns true if the DELAYING state is set in
>    * the_states, and false otherwise.
>    *
> diff --git a/cpukit/score/src/schedulercbsunblock.c b/cpukit/score/src/schedulercbsunblock.c
> index 411e6ce..1a374f6 100644
> --- a/cpukit/score/src/schedulercbsunblock.c
> +++ b/cpukit/score/src/schedulercbsunblock.c
> @@ -20,6 +20,7 @@
>   #endif
>
>   #include <rtems/score/schedulercbsimpl.h>
> +#include <rtems/score/scheduleredfimpl.h>
>   #include <rtems/score/schedulerimpl.h>
>   #include <rtems/score/threadimpl.h>
>   #include <rtems/score/watchdogimpl.h>
> diff --git a/cpukit/score/src/scheduleredfchangepriority.c b/cpukit/score/src/scheduleredfchangepriority.c
> new file mode 100644
> index 0000000..dfcfef5
> --- /dev/null
> +++ b/cpukit/score/src/scheduleredfchangepriority.c
> @@ -0,0 +1,36 @@
> +/**
> + *  @file
> + *
> + *  @brief Scheduler EDF Extract
> + *  @ingroup ScoreScheduler
> + */
> +
> +/*
> + *  Copyright (C) 2011 Petr Benes.
> + *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
> + *
> + *  The license and distribution terms for this file may be
> + *  found in the file LICENSE in this distribution or at
> + *  http://www.rtems.org/license/LICENSE.
> + */
> +
> +#if HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <rtems/score/scheduleredfimpl.h>
> +
> +void _Scheduler_EDF_Change_priority(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Priority_Control         new_priority,
> +  bool                     prepend_it
> +)
> +{
> +  Scheduler_EDF_Context *context =
> +    _Scheduler_EDF_Get_context( scheduler );
> +  Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
> +
> +  _RBTree_Extract( &context->Ready, &node->Node );
> +  _RBTree_Insert( &context->Ready, &node->Node );
> +}
> diff --git a/cpukit/score/src/scheduleredfenqueue.c b/cpukit/score/src/scheduleredfenqueue.c
> deleted file mode 100644
> index 8973d8b..0000000
> --- a/cpukit/score/src/scheduleredfenqueue.c
> +++ /dev/null
> @@ -1,34 +0,0 @@
> -/**
> - * @file
> - *
> - * @brief Scheduler EDF Enqueue
> - * @ingroup ScoreScheduler
> - */
> -
> -/*
> - *  Copyright (C) 2011 Petr Benes.
> - *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/score/scheduleredfimpl.h>
> -
> -void _Scheduler_EDF_Enqueue(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  Scheduler_EDF_Context *context =
> -    _Scheduler_EDF_Get_context( scheduler );
> -  Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
> -
> -  _RBTree_Insert( &context->Ready, &node->Node );
> -  node->queue_state = SCHEDULER_EDF_QUEUE_STATE_YES;
> -}
> diff --git a/cpukit/score/src/scheduleredfenqueuefirst.c b/cpukit/score/src/scheduleredfenqueuefirst.c
> deleted file mode 100644
> index aafc9b4..0000000
> --- a/cpukit/score/src/scheduleredfenqueuefirst.c
> +++ /dev/null
> @@ -1,32 +0,0 @@
> -/**
> - * @file
> - *
> - * @brief Enqueues a thread to the ready queue
> - *
> - * @ingroup ScoreScheduler
> - */
> -
> -/*
> - *  Copyright (C) 2011 Petr Benes.
> - *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/system.h>
> -#include <rtems/config.h>
> -#include <rtems/score/scheduleredf.h>
> -
> -void _Scheduler_EDF_Enqueue_first(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  _Scheduler_EDF_Enqueue( scheduler, the_thread );
> -}
> diff --git a/cpukit/score/src/scheduleredfextract.c b/cpukit/score/src/scheduleredfextract.c
> deleted file mode 100644
> index 94fde0a..0000000
> --- a/cpukit/score/src/scheduleredfextract.c
> +++ /dev/null
> @@ -1,34 +0,0 @@
> -/**
> - *  @file
> - *
> - *  @brief Scheduler EDF Extract
> - *  @ingroup ScoreScheduler
> - */
> -
> -/*
> - *  Copyright (C) 2011 Petr Benes.
> - *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/score/scheduleredfimpl.h>
> -
> -void _Scheduler_EDF_Extract(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  Scheduler_EDF_Context *context =
> -    _Scheduler_EDF_Get_context( scheduler );
> -  Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
> -
> -  _RBTree_Extract( &context->Ready, &node->Node );
> -  node->queue_state = SCHEDULER_EDF_QUEUE_STATE_NOT_PRESENTLY;
> -}
> diff --git a/cpukit/score/src/scheduleredfunblock.c b/cpukit/score/src/scheduleredfunblock.c
> index 7418b64..30fa4f0 100644
> --- a/cpukit/score/src/scheduleredfunblock.c
> +++ b/cpukit/score/src/scheduleredfunblock.c
> @@ -18,7 +18,7 @@
>   #include "config.h"
>   #endif
>
> -#include <rtems/score/scheduleredf.h>
> +#include <rtems/score/scheduleredfimpl.h>
>   #include <rtems/score/schedulerimpl.h>
>   #include <rtems/score/thread.h>
>
> diff --git a/cpukit/score/src/schedulerprioritychangepriority.c b/cpukit/score/src/schedulerprioritychangepriority.c
> new file mode 100644
> index 0000000..448c603
> --- /dev/null
> +++ b/cpukit/score/src/schedulerprioritychangepriority.c
> @@ -0,0 +1,61 @@
> +/**
> + * @file
> + *
> + * @brief Removes Thread from Thread Queue
> + *
> + * @ingroup ScoreScheduler
> + */
> +
> +/*
> + *  COPYRIGHT (c) 2011.
> + *  On-Line Applications Research Corporation (OAR).
> + *
> + *  The license and distribution terms for this file may be
> + *  found in the file LICENSE in this distribution or at
> + *  http://www.rtems.org/license/LICENSE.
> + */
> +
> +#if HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <rtems/score/schedulerpriorityimpl.h>
> +
> +void _Scheduler_priority_Change_priority(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Priority_Control         new_priority,
> +  bool                     prepend_it
> +)
> +{
> +  Scheduler_priority_Context *context =
> +    _Scheduler_priority_Get_context( scheduler );
> +  Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread );
> +
> +  _Scheduler_priority_Ready_queue_extract(
> +    the_thread,
> +    &node->Ready_queue,
> +    &context->Bit_map
> +  );
> +
> +  _Scheduler_priority_Ready_queue_update(
> +    &node->Ready_queue,
> +    new_priority,
> +    &context->Bit_map,
> +    &context->Ready[ 0 ]
> +  );
> +
> +  if ( prepend_it ) {
> +    _Scheduler_priority_Ready_queue_enqueue_first(
> +      the_thread,
> +      &node->Ready_queue,
> +      &context->Bit_map
> +    );
> +  } else {
> +    _Scheduler_priority_Ready_queue_enqueue(
> +      the_thread,
> +      &node->Ready_queue,
> +      &context->Bit_map
> +    );
> +  }
> +}
> diff --git a/cpukit/score/src/schedulerpriorityenqueue.c b/cpukit/score/src/schedulerpriorityenqueue.c
> deleted file mode 100644
> index aa901cc..0000000
> --- a/cpukit/score/src/schedulerpriorityenqueue.c
> +++ /dev/null
> @@ -1,37 +0,0 @@
> -/**
> - *  @file
> - *
> - *  @brief Scheduler Priority Enqueue
> - *  @ingroup ScoreScheduler
> - */
> -
> -/*
> - *  COPYRIGHT (c) 2011.
> - *  On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/score/schedulerpriorityimpl.h>
> -
> -void _Scheduler_priority_Enqueue(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  Scheduler_priority_Context *context =
> -    _Scheduler_priority_Get_context( scheduler );
> -  Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread );
> -
> -  _Scheduler_priority_Ready_queue_enqueue(
> -    the_thread,
> -    &node->Ready_queue,
> -    &context->Bit_map
> -  );
> -}
> diff --git a/cpukit/score/src/schedulerpriorityenqueuefirst.c b/cpukit/score/src/schedulerpriorityenqueuefirst.c
> deleted file mode 100644
> index 1714fe5..0000000
> --- a/cpukit/score/src/schedulerpriorityenqueuefirst.c
> +++ /dev/null
> @@ -1,38 +0,0 @@
> -/**
> - *  @file
> - *
> - *  @brief Scheduler Priority Enqueue First
> - *  @ingroup ScoreScheduler
> - */
> -
> -/*
> - *  COPYRIGHT (c) 2011.
> - *  On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/score/schedulerpriorityimpl.h>
> -
> -void _Scheduler_priority_Enqueue_first(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  Scheduler_priority_Context *context =
> -    _Scheduler_priority_Get_context( scheduler );
> -  Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread );
> -
> -  _Scheduler_priority_Ready_queue_enqueue_first(
> -    the_thread,
> -    &node->Ready_queue,
> -    &context->Bit_map
> -  );
> -}
> -
> diff --git a/cpukit/score/src/schedulerpriorityextract.c b/cpukit/score/src/schedulerpriorityextract.c
> deleted file mode 100644
> index 84dbaa4..0000000
> --- a/cpukit/score/src/schedulerpriorityextract.c
> +++ /dev/null
> @@ -1,30 +0,0 @@
> -/**
> - * @file
> - *
> - * @brief Removes Thread from Thread Queue
> - *
> - * @ingroup ScoreScheduler
> - */
> -
> -/*
> - *  COPYRIGHT (c) 2011.
> - *  On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/score/schedulerpriorityimpl.h>
> -
> -void _Scheduler_priority_Extract(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  _Scheduler_priority_Extract_body( scheduler, the_thread );
> -}
> diff --git a/cpukit/score/src/schedulerprioritysmp.c b/cpukit/score/src/schedulerprioritysmp.c
> index 8133956..0198511 100644
> --- a/cpukit/score/src/schedulerprioritysmp.c
> +++ b/cpukit/score/src/schedulerprioritysmp.c
> @@ -70,24 +70,39 @@ bool _Scheduler_priority_SMP_Allocate(
>     return true;
>   }
>
> -void _Scheduler_priority_SMP_Update(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control *thread
> +static void _Scheduler_priority_SMP_Do_update(
> +  Scheduler_Context *context,
> +  Thread_Control *thread,
> +  Priority_Control new_priority
>   )
>   {
>     Scheduler_priority_SMP_Context *self =
> -    _Scheduler_priority_SMP_Get_context( scheduler );
> +    _Scheduler_priority_SMP_Get_self( context );
>     Scheduler_priority_SMP_Node *node =
>       _Scheduler_priority_SMP_Node_get( thread );
>
>     _Scheduler_priority_Ready_queue_update(
> -    thread,
>       &node->Ready_queue,
> +    new_priority,
>       &self->Bit_map,
>       &self->Ready[ 0 ]
>     );
>   }
>
> +void _Scheduler_priority_SMP_Update(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control *thread
> +)
> +{
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  _Scheduler_priority_SMP_Do_update(
> +    context,
> +    thread,
> +    thread->current_priority
> +  );
> +}
> +
>   static Thread_Control *_Scheduler_priority_SMP_Get_highest_ready(
>     Scheduler_Context *context
>   )
> @@ -179,7 +194,7 @@ static void _Scheduler_priority_SMP_Insert_ready_fifo(
>     );
>   }
>
> -static void _Scheduler_priority_SMP_Do_extract(
> +static void _Scheduler_priority_SMP_Extract_from_ready(
>     Scheduler_Context *context,
>     Thread_Control *thread
>   )
> @@ -189,23 +204,11 @@ static void _Scheduler_priority_SMP_Do_extract(
>     Scheduler_priority_SMP_Node *node =
>       _Scheduler_priority_SMP_Node_get( thread );
>
> -  if ( node->Base.state == SCHEDULER_SMP_NODE_SCHEDULED ) {
> -    _Scheduler_SMP_Node_change_state(
> -      &node->Base,
> -      SCHEDULER_SMP_NODE_IN_THE_AIR
> -    );
> -    _Chain_Extract_unprotected( &thread->Object.Node );
> -  } else {
> -    _Scheduler_SMP_Node_change_state(
> -      &node->Base,
> -      SCHEDULER_SMP_NODE_BLOCKED
> -    );
> -    _Scheduler_priority_Ready_queue_extract(
> -      thread,
> -      &node->Ready_queue,
> -      &self->Bit_map
> -    );
> -  }
> +  _Scheduler_priority_Ready_queue_extract(
> +    thread,
> +    &node->Ready_queue,
> +    &self->Bit_map
> +  );
>   }
>
>   void _Scheduler_priority_SMP_Block(
> @@ -213,13 +216,12 @@ void _Scheduler_priority_SMP_Block(
>     Thread_Control *thread
>   )
>   {
> -  Scheduler_priority_SMP_Context *self =
> -    _Scheduler_priority_SMP_Get_context( scheduler );
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
>
>     _Scheduler_SMP_Block(
> -    &self->Base.Base,
> +    context,
>       thread,
> -    _Scheduler_priority_SMP_Do_extract,
> +    _Scheduler_priority_SMP_Extract_from_ready,
>       _Scheduler_priority_SMP_Get_highest_ready,
>       _Scheduler_priority_SMP_Move_from_ready_to_scheduled
>     );
> @@ -228,6 +230,7 @@ void _Scheduler_priority_SMP_Block(
>   static void _Scheduler_priority_SMP_Enqueue_ordered(
>     Scheduler_Context *context,
>     Thread_Control *thread,
> +  bool has_processor_allocated,
>     Chain_Node_order order,
>     Scheduler_SMP_Insert insert_ready,
>     Scheduler_SMP_Insert insert_scheduled
> @@ -236,6 +239,7 @@ static void _Scheduler_priority_SMP_Enqueue_ordered(
>     _Scheduler_SMP_Enqueue_ordered(
>       context,
>       thread,
> +    has_processor_allocated,
>       order,
>       _Scheduler_priority_SMP_Get_highest_ready,
>       insert_ready,
> @@ -245,52 +249,66 @@ static void _Scheduler_priority_SMP_Enqueue_ordered(
>     );
>   }
>
> -void _Scheduler_priority_SMP_Enqueue_lifo(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control *thread
> +static void _Scheduler_priority_SMP_Enqueue_lifo(
> +  Scheduler_Context *context,
> +  Thread_Control *thread,
> +  bool has_processor_allocated
>   )
>   {
> -  Scheduler_priority_SMP_Context *self =
> -    _Scheduler_priority_SMP_Get_context( scheduler );
> -
>     _Scheduler_priority_SMP_Enqueue_ordered(
> -    &self->Base.Base,
> +    context,
>       thread,
> +    has_processor_allocated,
>       _Scheduler_simple_Insert_priority_lifo_order,
>       _Scheduler_priority_SMP_Insert_ready_lifo,
>       _Scheduler_SMP_Insert_scheduled_lifo
>     );
>   }
>
> -void _Scheduler_priority_SMP_Enqueue_fifo(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control *thread
> +static void _Scheduler_priority_SMP_Enqueue_fifo(
> +  Scheduler_Context *context,
> +  Thread_Control *thread,
> +  bool has_processor_allocated
>   )
>   {
> -  Scheduler_priority_SMP_Context *self =
> -    _Scheduler_priority_SMP_Get_context( scheduler );
> -
>     _Scheduler_priority_SMP_Enqueue_ordered(
> -    &self->Base.Base,
> +    context,
>       thread,
> +    has_processor_allocated,
>       _Scheduler_simple_Insert_priority_fifo_order,
>       _Scheduler_priority_SMP_Insert_ready_fifo,
>       _Scheduler_SMP_Insert_scheduled_fifo
>     );
>   }
>
> -void _Scheduler_priority_SMP_Extract(
> +void _Scheduler_priority_SMP_Unblock(
>     const Scheduler_Control *scheduler,
>     Thread_Control *thread
>   )
>   {
> -  Scheduler_priority_SMP_Context *self =
> -    _Scheduler_priority_SMP_Get_context( scheduler );
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
>
> -  _Scheduler_SMP_Extract(
> -    &self->Base.Base,
> +  _Scheduler_priority_SMP_Enqueue_fifo( context, thread, false );
> +}
> +
> +void _Scheduler_priority_SMP_Change_priority(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *thread,
> +  Priority_Control         new_priority,
> +  bool                     prepend_it
> +)
> +{
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  _Scheduler_SMP_Change_priority(
> +    context,
>       thread,
> -    _Scheduler_priority_SMP_Do_extract
> +    new_priority,
> +    prepend_it,
> +    _Scheduler_priority_SMP_Extract_from_ready,
> +    _Scheduler_priority_SMP_Do_update,
> +    _Scheduler_priority_SMP_Enqueue_fifo,
> +    _Scheduler_priority_SMP_Enqueue_lifo
>     );
>   }
>
> @@ -299,12 +317,13 @@ void _Scheduler_priority_SMP_Yield(
>     Thread_Control *thread
>   )
>   {
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
>     ISR_Level level;
>
>     _ISR_Disable( level );
>
> -  _Scheduler_priority_SMP_Extract( scheduler, thread );
> -  _Scheduler_priority_SMP_Enqueue_fifo( scheduler, thread );
> +  _Scheduler_SMP_Extract_from_scheduled( thread );
> +  _Scheduler_priority_SMP_Enqueue_fifo( context, thread, true );
>
>     _ISR_Enable( level );
>   }
> @@ -314,15 +333,8 @@ void _Scheduler_priority_SMP_Schedule(
>     Thread_Control *thread
>   )
>   {
> -  Scheduler_priority_SMP_Context *self =
> -    _Scheduler_priority_SMP_Get_context( scheduler );
> -
> -  _Scheduler_SMP_Schedule(
> -    &self->Base.Base,
> -    thread,
> -    _Scheduler_priority_SMP_Get_highest_ready,
> -    _Scheduler_priority_SMP_Move_from_ready_to_scheduled
> -  );
> +  (void) scheduler;
> +  (void) thread;
>   }
>
>   void _Scheduler_priority_SMP_Start_idle(
> @@ -331,8 +343,7 @@ void _Scheduler_priority_SMP_Start_idle(
>     Per_CPU_Control *cpu
>   )
>   {
> -  Scheduler_priority_SMP_Context *self =
> -    _Scheduler_priority_SMP_Get_context( scheduler );
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
>
> -  _Scheduler_SMP_Start_idle( &self->Base.Base, thread, cpu );
> +  _Scheduler_SMP_Start_idle( context, thread, cpu );
>   }
> diff --git a/cpukit/score/src/schedulerpriorityupdate.c b/cpukit/score/src/schedulerpriorityupdate.c
> index 8a22ee6..e58a609 100644
> --- a/cpukit/score/src/schedulerpriorityupdate.c
> +++ b/cpukit/score/src/schedulerpriorityupdate.c
> @@ -30,8 +30,8 @@ void _Scheduler_priority_Update(
>     Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread );
>
>     _Scheduler_priority_Ready_queue_update(
> -    the_thread,
>       &node->Ready_queue,
> +    the_thread->current_priority,
>       &context->Bit_map,
>       &context->Ready[ 0 ]
>     );
> diff --git a/cpukit/score/src/schedulersimplechangepriority.c b/cpukit/score/src/schedulersimplechangepriority.c
> new file mode 100644
> index 0000000..010f1df
> --- /dev/null
> +++ b/cpukit/score/src/schedulersimplechangepriority.c
> @@ -0,0 +1,41 @@
> +/**
> + * @file
> + *
> + * @brief Removes a Thread from the Simple Queue
> + *
> + * @ingroup ScoreScheduler
> + */
> +
> +/*
> + *  COPYRIGHT (c) 2011.
> + *  On-Line Applications Research Corporation (OAR).
> + *
> + *  The license and distribution terms for this file may be
> + *  found in the file LICENSE in this distribution or at
> + *  http://www.rtems.org/license/LICENSE.
> + */
> +
> +#if HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <rtems/score/schedulersimpleimpl.h>
> +
> +void _Scheduler_simple_Change_priority(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Priority_Control         new_priority,
> +  bool                     prepend_it
> +)
> +{
> +  Scheduler_simple_Context *context =
> +    _Scheduler_simple_Get_context( scheduler );
> +
> +  _Scheduler_simple_Extract( scheduler, the_thread );
> +
> +  if ( prepend_it ) {
> +    _Scheduler_simple_Insert_priority_lifo( &context->Ready, the_thread );
> +  } else {
> +    _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );
> +  }
> +}
> diff --git a/cpukit/score/src/schedulersimpleenqueue.c b/cpukit/score/src/schedulersimpleenqueue.c
> deleted file mode 100644
> index 5dc8894..0000000
> --- a/cpukit/score/src/schedulersimpleenqueue.c
> +++ /dev/null
> @@ -1,30 +0,0 @@
> -/**
> - * @file
> - *
> - * @brief Puts Thread onto the Ready Queue
> - *
> - * @ingroup ScoreScheduler
> - */
> -
> -/*
> - *  COPYRIGHT (c) 2011.
> - *  On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/score/schedulersimpleimpl.h>
> -
> -void _Scheduler_simple_Enqueue(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  _Scheduler_simple_Ready_queue_enqueue( scheduler, the_thread );
> -}
> diff --git a/cpukit/score/src/schedulersimpleenqueuefirst.c b/cpukit/score/src/schedulersimpleenqueuefirst.c
> deleted file mode 100644
> index 2ea0a15..0000000
> --- a/cpukit/score/src/schedulersimpleenqueuefirst.c
> +++ /dev/null
> @@ -1,29 +0,0 @@
> -/**
> - *  @file
> - *
> - *  @brief Scheduler Simple Enqueue First
> - *  @ingroup ScoreScheduler
> - */
> -
> -/*
> - *  COPYRIGHT (c) 2011.
> - *  On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/score/schedulersimple.h>
> -
> -void _Scheduler_simple_Enqueue_first(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  _Scheduler_simple_Ready_queue_enqueue_first( scheduler, the_thread );
> -}
> diff --git a/cpukit/score/src/schedulersimpleextract.c b/cpukit/score/src/schedulersimpleextract.c
> deleted file mode 100644
> index 6b89c99..0000000
> --- a/cpukit/score/src/schedulersimpleextract.c
> +++ /dev/null
> @@ -1,32 +0,0 @@
> -/**
> - * @file
> - *
> - * @brief Removes a Thread from the Simple Queue
> - *
> - * @ingroup ScoreScheduler
> - */
> -
> -/*
> - *  COPYRIGHT (c) 2011.
> - *  On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/score/schedulersimpleimpl.h>
> -
> -void _Scheduler_simple_Extract(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  (void) scheduler;
> -
> -  _Chain_Extract_unprotected( &the_thread->Object.Node );
> -}
> diff --git a/cpukit/score/src/schedulersimplereadyqueueenqueue.c b/cpukit/score/src/schedulersimplereadyqueueenqueue.c
> deleted file mode 100644
> index 8e5f12d..0000000
> --- a/cpukit/score/src/schedulersimplereadyqueueenqueue.c
> +++ /dev/null
> @@ -1,32 +0,0 @@
> -/**
> - * @file
> - *
> - * @brief Scheduler Simple Priority Enqueue Ready Thread
> - * @ingroup ScoreScheduler
> - */
> -
> -/*
> - *  COPYRIGHT (c) 2011.
> - *  On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/score/schedulersimpleimpl.h>
> -
> -void _Scheduler_simple_Ready_queue_enqueue(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  Scheduler_simple_Context *context =
> -    _Scheduler_simple_Get_context( scheduler );
> -
> -  _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );
> -}
> diff --git a/cpukit/score/src/schedulersimplereadyqueueenqueuefirst.c b/cpukit/score/src/schedulersimplereadyqueueenqueuefirst.c
> deleted file mode 100644
> index c5f1e68..0000000
> --- a/cpukit/score/src/schedulersimplereadyqueueenqueuefirst.c
> +++ /dev/null
> @@ -1,32 +0,0 @@
> -/**
> - *  @file
> - *
> - *  @brief Scheduler Simple Ready Queue Enqueue First
> - *  @ingroup ScoreScheduler
> - */
> -
> -/*
> - *  COPYRIGHT (c) 2011.
> - *  On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/score/schedulersimpleimpl.h>
> -
> -void _Scheduler_simple_Ready_queue_enqueue_first(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control          *the_thread
> -)
> -{
> -  Scheduler_simple_Context *context =
> -    _Scheduler_simple_Get_context( scheduler );
> -
> -  _Scheduler_simple_Insert_priority_lifo( &context->Ready, the_thread );
> -}
> diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c
> index 8436659..a4abc7d 100644
> --- a/cpukit/score/src/schedulersimplesmp.c
> +++ b/cpukit/score/src/schedulersimplesmp.c
> @@ -55,6 +55,17 @@ bool _Scheduler_simple_SMP_Allocate(
>     return true;
>   }
>
> +static void _Scheduler_simple_SMP_Do_update(
> +  Scheduler_Context *context,
> +  Thread_Control *thread,
> +  Priority_Control new_priority
> +)
> +{
> +  (void) context;
> +  (void) thread;
> +  (void) new_priority;
> +}
> +
>   static Thread_Control *_Scheduler_simple_SMP_Get_highest_ready(
>     Scheduler_Context *context
>   )
> @@ -131,21 +142,13 @@ static void _Scheduler_simple_SMP_Insert_ready_fifo(
>     );
>   }
>
> -static void _Scheduler_simple_SMP_Do_extract(
> +static void _Scheduler_simple_SMP_Extract_from_ready(
>     Scheduler_Context *context,
>     Thread_Control *thread
>   )
>   {
> -  Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
> -
>     (void) context;
>
> -  if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) {
> -    _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_IN_THE_AIR );
> -  } else {
> -    _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
> -  }
> -
>     _Chain_Extract_unprotected( &thread->Object.Node );
>   }
>
> @@ -154,13 +157,12 @@ void _Scheduler_simple_SMP_Block(
>     Thread_Control *thread
>   )
>   {
> -  Scheduler_simple_SMP_Context *self =
> -    _Scheduler_simple_SMP_Get_context( scheduler );
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
>
>     _Scheduler_SMP_Block(
> -    &self->Base.Base,
> +    context,
>       thread,
> -    _Scheduler_simple_SMP_Do_extract,
> +    _Scheduler_simple_SMP_Extract_from_ready,
>       _Scheduler_simple_SMP_Get_highest_ready,
>       _Scheduler_simple_SMP_Move_from_ready_to_scheduled
>     );
> @@ -169,6 +171,7 @@ void _Scheduler_simple_SMP_Block(
>   static void _Scheduler_simple_SMP_Enqueue_ordered(
>     Scheduler_Context *context,
>     Thread_Control *thread,
> +  bool has_processor_allocated,
>     Chain_Node_order order,
>     Scheduler_SMP_Insert insert_ready,
>     Scheduler_SMP_Insert insert_scheduled
> @@ -177,6 +180,7 @@ static void _Scheduler_simple_SMP_Enqueue_ordered(
>     _Scheduler_SMP_Enqueue_ordered(
>       context,
>       thread,
> +    has_processor_allocated,
>       order,
>       _Scheduler_simple_SMP_Get_highest_ready,
>       insert_ready,
> @@ -186,52 +190,66 @@ static void _Scheduler_simple_SMP_Enqueue_ordered(
>     );
>   }
>
> -void _Scheduler_simple_SMP_Enqueue_priority_lifo(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control *thread
> +static void _Scheduler_simple_SMP_Enqueue_lifo(
> +  Scheduler_Context *context,
> +  Thread_Control *thread,
> +  bool has_processor_allocated
>   )
>   {
> -  Scheduler_simple_SMP_Context *self =
> -    _Scheduler_simple_SMP_Get_context( scheduler );
> -
>     _Scheduler_simple_SMP_Enqueue_ordered(
> -    &self->Base.Base,
> +    context,
>       thread,
> +    has_processor_allocated,
>       _Scheduler_simple_Insert_priority_lifo_order,
>       _Scheduler_simple_SMP_Insert_ready_lifo,
>       _Scheduler_SMP_Insert_scheduled_lifo
>     );
>   }
>
> -void _Scheduler_simple_SMP_Enqueue_priority_fifo(
> -  const Scheduler_Control *scheduler,
> -  Thread_Control *thread
> +static void _Scheduler_simple_SMP_Enqueue_fifo(
> +  Scheduler_Context *context,
> +  Thread_Control *thread,
> +  bool has_processor_allocated
>   )
>   {
> -  Scheduler_simple_SMP_Context *self =
> -    _Scheduler_simple_SMP_Get_context( scheduler );
> -
>     _Scheduler_simple_SMP_Enqueue_ordered(
> -    &self->Base.Base,
> +    context,
>       thread,
> +    has_processor_allocated,
>       _Scheduler_simple_Insert_priority_fifo_order,
>       _Scheduler_simple_SMP_Insert_ready_fifo,
>       _Scheduler_SMP_Insert_scheduled_fifo
>     );
>   }
>
> -void _Scheduler_simple_SMP_Extract(
> +void _Scheduler_simple_SMP_Unblock(
>     const Scheduler_Control *scheduler,
>     Thread_Control *thread
>   )
>   {
> -  Scheduler_simple_SMP_Context *self =
> -    _Scheduler_simple_SMP_Get_context( scheduler );
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  _Scheduler_simple_SMP_Enqueue_fifo( context, thread, false );
> +}
>
> -  _Scheduler_SMP_Extract(
> -    &self->Base.Base,
> +void _Scheduler_simple_SMP_Change_priority(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *thread,
> +  Priority_Control         new_priority,
> +  bool                     prepend_it
> +)
> +{
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  _Scheduler_SMP_Change_priority(
> +    context,
>       thread,
> -    _Scheduler_simple_SMP_Do_extract
> +    new_priority,
> +    prepend_it,
> +    _Scheduler_simple_SMP_Extract_from_ready,
> +    _Scheduler_simple_SMP_Do_update,
> +    _Scheduler_simple_SMP_Enqueue_fifo,
> +    _Scheduler_simple_SMP_Enqueue_lifo
>     );
>   }
>
> @@ -240,12 +258,13 @@ void _Scheduler_simple_SMP_Yield(
>     Thread_Control *thread
>   )
>   {
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
>     ISR_Level level;
>
>     _ISR_Disable( level );
>
> -  _Scheduler_simple_SMP_Extract( scheduler, thread );
> -  _Scheduler_simple_SMP_Enqueue_priority_fifo( scheduler, thread );
> +  _Scheduler_SMP_Extract_from_scheduled( thread );
> +  _Scheduler_simple_SMP_Enqueue_fifo( context, thread, true );
>
>     _ISR_Enable( level );
>   }
> @@ -255,15 +274,8 @@ void _Scheduler_simple_SMP_Schedule(
>     Thread_Control *thread
>   )
>   {
> -  Scheduler_simple_SMP_Context *self =
> -    _Scheduler_simple_SMP_Get_context( scheduler );
> -
> -  _Scheduler_SMP_Schedule(
> -    &self->Base.Base,
> -    thread,
> -    _Scheduler_simple_SMP_Get_highest_ready,
> -    _Scheduler_simple_SMP_Move_from_ready_to_scheduled
> -  );
> +  (void) scheduler;
> +  (void) thread;
>   }
>
>   void _Scheduler_simple_SMP_Start_idle(
> @@ -272,8 +284,7 @@ void _Scheduler_simple_SMP_Start_idle(
>     Per_CPU_Control *cpu
>   )
>   {
> -  Scheduler_simple_SMP_Context *self =
> -    _Scheduler_simple_SMP_Get_context( scheduler );
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
>
> -  _Scheduler_SMP_Start_idle( &self->Base.Base, thread, cpu );
> +  _Scheduler_SMP_Start_idle( context, thread, cpu );
>   }
> diff --git a/cpukit/score/src/schedulersimpleunblock.c b/cpukit/score/src/schedulersimpleunblock.c
> index 3a9528f..4e49bd6 100644
> --- a/cpukit/score/src/schedulersimpleunblock.c
> +++ b/cpukit/score/src/schedulersimpleunblock.c
> @@ -26,7 +26,10 @@ void _Scheduler_simple_Unblock(
>     Thread_Control          *the_thread
>   )
>   {
> -  _Scheduler_simple_Ready_queue_enqueue( scheduler, the_thread );
> +  Scheduler_simple_Context *context =
> +    _Scheduler_simple_Get_context( scheduler );
> +
> +  _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );
>
>     /*
>      *  If the thread that was unblocked is more important than the heir,
> diff --git a/cpukit/score/src/schedulersimpleyield.c b/cpukit/score/src/schedulersimpleyield.c
> index ea41892..65578d0 100644
> --- a/cpukit/score/src/schedulersimpleyield.c
> +++ b/cpukit/score/src/schedulersimpleyield.c
> @@ -26,11 +26,14 @@ void _Scheduler_simple_Yield(
>     Thread_Control          *the_thread
>   )
>   {
> +  Scheduler_simple_Context *context =
> +    _Scheduler_simple_Get_context( scheduler );
>     ISR_Level       level;
>
>     _ISR_Disable( level );
>
> -    _Scheduler_simple_Ready_queue_requeue( scheduler, the_thread );
> +    _Chain_Extract_unprotected( &the_thread->Object.Node );
> +    _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );
>
>       _ISR_Flash( level );
>
> diff --git a/cpukit/score/src/schedulersmpvalidstatechanges.c b/cpukit/score/src/schedulersmpvalidstatechanges.c
> index 61f6a7e..5e35d42 100644
> --- a/cpukit/score/src/schedulersmpvalidstatechanges.c
> +++ b/cpukit/score/src/schedulersmpvalidstatechanges.c
> @@ -30,10 +30,9 @@
>    * Table with all valid state transitions.  It is used in
>    * _Scheduler_SMP_Node_change_state() in case RTEMS_DEBUG is defined.
>    */
> -const bool _Scheduler_SMP_Node_valid_state_changes[ 4 ][ 4 ] = {
> -  /*                 BLOCKED SCHEDULED READY  IN THE AIR */
> -  /* BLOCKED    */ { false,  true,     true,  false },
> -  /* SCHEDULED  */ { false,  false,    true,  true },
> -  /* READY      */ { true,   true,     false, false },
> -  /* IN THE AIR */ { true,   true,     true,  false }
> +const bool _Scheduler_SMP_Node_valid_state_changes[ 3 ][ 3 ] = {
> +  /*                 BLOCKED SCHEDULED READY */
> +  /* BLOCKED    */ { false,  true,     true },
> +  /* SCHEDULED  */ { false,  false,    true },
> +  /* READY      */ { true,   true,     false }
>   };
> diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c
> index 68eb3e8..4480b53 100644
> --- a/cpukit/score/src/threadchangepriority.c
> +++ b/cpukit/score/src/threadchangepriority.c
> @@ -29,79 +29,40 @@ void _Thread_Change_priority(
>     bool              prepend_it
>   )
>   {
> -  const Scheduler_Control *scheduler = _Scheduler_Get( the_thread );
> -  ISR_Level                level;
> -  States_Control           state, original_state;
> -
> -  /*
> -   * Save original state
> -   */
> -  original_state = the_thread->current_state;
> -
> -  /*
> -   * Set a transient state for the thread so it is pulled off the Ready chains.
> -   * This will prevent it from being scheduled no matter what happens in an
> -   * ISR.
> -   */
> -  _Thread_Set_transient( the_thread );
> -
>     /*
>      *  Do not bother recomputing all the priority related information if
>      *  we are not REALLY changing priority.
>      */
> - if ( the_thread->current_priority != new_priority )
> -    _Thread_Set_priority( the_thread, new_priority );
> +  if ( the_thread->current_priority != new_priority ) {
> +    ISR_Level                level;
> +    const Scheduler_Control *scheduler;
>
> -  _ISR_Disable( level );
> +    _ISR_Disable( level );
>
> -  /*
> -   *  If the thread has more than STATES_TRANSIENT set, then it is blocked,
> -   *  If it is blocked on a thread queue, then we need to requeue it.
> -   */
> -  state = the_thread->current_state;
> -  if ( state != STATES_TRANSIENT ) {
> -    /* Only clear the transient state if it wasn't set already */
> -    if ( ! _States_Is_transient( original_state ) )
> -      the_thread->current_state = _States_Clear( STATES_TRANSIENT, state );
> +    scheduler = _Scheduler_Get( the_thread );
> +    the_thread->current_priority = new_priority;
>
> -    /*
> -     * The thread may have new blocking states added by interrupt service
> -     * routines after the change into the transient state.  This will not
> -     * result in a _Scheduler_Block() operation.  Make sure we select an heir
> -     * now.
> -     */
> -    _Scheduler_Schedule( scheduler, the_thread );
> +    if ( _States_Is_ready( the_thread->current_state ) ) {
> +      _Scheduler_Change_priority(
> +        scheduler,
> +        the_thread,
> +        new_priority,
> +        prepend_it
> +      );
>
> -    _ISR_Enable( level );
> -    if ( _States_Is_waiting_on_thread_queue( state ) ) {
> -      _Thread_queue_Requeue( the_thread->Wait.queue, the_thread );
> -    }
> -    return;
> -  }
> +      _ISR_Flash( level );
>
> -  /* Only clear the transient state if it wasn't set already */
> -  if ( ! _States_Is_transient( original_state ) ) {
> -    /*
> -     *  Interrupts are STILL disabled.
> -     *  We now know the thread will be in the READY state when we remove
> -     *  the TRANSIENT state.  So we have to place it on the appropriate
> -     *  Ready Queue with interrupts off.
> -     */
> -    the_thread->current_state = _States_Clear( STATES_TRANSIENT, state );
> +      /*
> +       *  We altered the set of thread priorities.  So let's figure out
> +       *  who is the heir and if we need to switch to them.
> +       */
> +      scheduler = _Scheduler_Get( the_thread );
> +      _Scheduler_Schedule( scheduler, the_thread );
> +    } else {
> +      _Scheduler_Update( scheduler, the_thread );
> +    }
> +    _ISR_Enable( level );
>
> -    if ( prepend_it )
> -      _Scheduler_Enqueue_first( scheduler, the_thread );
> -    else
> -      _Scheduler_Enqueue( scheduler, the_thread );
> +    _Thread_queue_Requeue( the_thread->Wait.queue, the_thread );
>     }
> -
> -  _ISR_Flash( level );
> -
> -  /*
> -   *  We altered the set of thread priorities.  So let's figure out
> -   *  who is the heir and if we need to switch to them.
> -   */
> -  _Scheduler_Schedule( scheduler, the_thread );
> -
> -  _ISR_Enable( level );
>   }
> diff --git a/cpukit/score/src/threadsettransient.c b/cpukit/score/src/threadsettransient.c
> deleted file mode 100644
> index ead3c45..0000000
> --- a/cpukit/score/src/threadsettransient.c
> +++ /dev/null
> @@ -1,44 +0,0 @@
> -/**
> - * @file
> - *
> - * @brief Sets the Transient State for a Thread
> - *
> - * @ingroup ScoreThread
> - */
> -
> -/*
> - *  COPYRIGHT (c) 1989-2011.
> - *  On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/score/threadimpl.h>
> -#include <rtems/score/isrlevel.h>
> -#include <rtems/score/schedulerimpl.h>
> -
> -void _Thread_Set_transient(
> -  Thread_Control *the_thread
> -)
> -{
> -  ISR_Level             level;
> -  uint32_t              old_state;
> -
> -  _ISR_Disable( level );
> -
> -  old_state = the_thread->current_state;
> -  the_thread->current_state = _States_Set( STATES_TRANSIENT, old_state );
> -
> -  if ( _States_Is_ready( old_state ) ) {
> -    _Scheduler_Extract( _Scheduler_Get( the_thread ), the_thread );
> -  }
> -
> -  _ISR_Enable( level );
> -
> -}
> diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am
> index 999c758..ef25b25 100644
> --- a/testsuites/sptests/Makefile.am
> +++ b/testsuites/sptests/Makefile.am
> @@ -50,7 +50,6 @@ _SUBDIRS += sptls02
>   endif
>   _SUBDIRS += sptls01
>   _SUBDIRS += spintrcritical20
> -_SUBDIRS += spintrcritical19
>   _SUBDIRS += spcontext01
>   _SUBDIRS += spfatal26
>   _SUBDIRS += speventtransient01
> diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac
> index 6be14e4..b40d4dd 100644
> --- a/testsuites/sptests/configure.ac
> +++ b/testsuites/sptests/configure.ac
> @@ -50,7 +50,6 @@ spcpucounter01/Makefile
>   sptls02/Makefile
>   sptls01/Makefile
>   spintrcritical20/Makefile
> -spintrcritical19/Makefile
>   spcontext01/Makefile
>   spfatal26/Makefile
>   spinternalerror02/Makefile
> diff --git a/testsuites/sptests/spintrcritical19/Makefile.am b/testsuites/sptests/spintrcritical19/Makefile.am
> deleted file mode 100644
> index a2350ca..0000000
> --- a/testsuites/sptests/spintrcritical19/Makefile.am
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -rtems_tests_PROGRAMS = spintrcritical19
> -spintrcritical19_SOURCES = init.c ../spintrcritical_support/intrcritical.c
> -
> -dist_rtems_tests_DATA = spintrcritical19.scn spintrcritical19.doc
> -
> -include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
> -include $(top_srcdir)/../automake/compile.am
> -include $(top_srcdir)/../automake/leaf.am
> -
> -AM_CPPFLAGS += -I$(top_srcdir)/../support/include
> -AM_CPPFLAGS += -I$(top_srcdir)/spintrcritical_support
> -
> -LINK_OBJS = $(spintrcritical19_OBJECTS)
> -LINK_LIBS = $(spintrcritical19_LDLIBS)
> -
> -spintrcritical19$(EXEEXT): $(spintrcritical19_OBJECTS) $(spintrcritical19_DEPENDENCIES)
> -       @rm -f spintrcritical19$(EXEEXT)
> -       $(make-exe)
> -
> -include $(top_srcdir)/../automake/local.am
> diff --git a/testsuites/sptests/spintrcritical19/init.c b/testsuites/sptests/spintrcritical19/init.c
> deleted file mode 100644
> index 4d2eca8..0000000
> --- a/testsuites/sptests/spintrcritical19/init.c
> +++ /dev/null
> @@ -1,136 +0,0 @@
> -/*
> - * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
> - *
> - *  embedded brains GmbH
> - *  Dornierstr. 4
> - *  82178 Puchheim
> - *  Germany
> - *  <rtems at embedded-brains.de>
> - *
> - * The license and distribution terms for this file may be
> - * found in the file LICENSE in this distribution or at
> - * http://www.rtems.org/license/LICENSE.
> - */
> -
> -#ifdef HAVE_CONFIG_H
> -  #include "config.h"
> -#endif
> -
> -#include <tmacros.h>
> -#include <intrcritical.h>
> -#include <rtems/score/statesimpl.h>
> -
> -const char rtems_test_name[] = "SPINTRCRITICAL 19";
> -
> -#define PRIORITY_RED 1
> -
> -#define PRIORITY_GREEN 2
> -
> -#define PRIORITY_RESUMER 3
> -
> -typedef struct {
> -  rtems_id master_task;
> -  rtems_id resumer_task;
> -  Thread_Control *master_task_tcb;
> -  bool test_case_hit;
> -} test_context;
> -
> -static test_context ctx_instance;
> -
> -static void resumer_task(rtems_task_argument arg)
> -{
> -  test_context *ctx = (test_context *) arg;
> -
> -  while (true) {
> -    rtems_status_code sc = rtems_task_resume(ctx->master_task);
> -    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> -  }
> -}
> -
> -static void suspend_master_task(rtems_id timer, void *arg)
> -{
> -  /* The arg is NULL */
> -  test_context *ctx = &ctx_instance;
> -  rtems_status_code sc;
> -
> -  if (_States_Is_transient(ctx->master_task_tcb->current_state)) {
> -    ctx->test_case_hit = true;
> -  }
> -
> -  sc = rtems_task_suspend(ctx->master_task);
> -  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> -}
> -
> -static void Init(rtems_task_argument ignored)
> -{
> -  test_context *ctx = &ctx_instance;
> -  rtems_task_priority priority = PRIORITY_RED;
> -  int resets = 0;
> -  rtems_status_code sc;
> -
> -  TEST_BEGIN();
> -
> -  ctx->master_task = rtems_task_self();
> -  ctx->master_task_tcb = _Thread_Get_executing();
> -
> -  sc = rtems_task_create(
> -    rtems_build_name('R', 'E', 'S', 'U'),
> -    PRIORITY_RESUMER,
> -    RTEMS_MINIMUM_STACK_SIZE,
> -    RTEMS_DEFAULT_MODES,
> -    RTEMS_DEFAULT_ATTRIBUTES,
> -    &ctx->resumer_task
> -  );
> -  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> -
> -  sc = rtems_task_start(
> -    ctx->resumer_task,
> -    resumer_task,
> -    (rtems_task_argument) ctx
> -  );
> -  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> -
> -  interrupt_critical_section_test_support_initialize(
> -    suspend_master_task
> -  );
> -
> -  while (resets < 3 && !ctx->test_case_hit) {
> -    if (interrupt_critical_section_test_support_delay()) {
> -      ++resets;
> -    }
> -
> -    sc = rtems_task_set_priority(RTEMS_SELF, priority, &priority);
> -    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> -
> -    rtems_test_assert(_States_Is_ready(ctx->master_task_tcb->current_state));
> -  }
> -
> -  rtems_test_assert(ctx->test_case_hit);
> -
> -  sc = rtems_task_delete(ctx->resumer_task);
> -  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> -
> -  TEST_END();
> -
> -  rtems_test_exit(0);
> -}
> -
> -#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
> -#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
> -
> -#define CONFIGURE_MICROSECONDS_PER_TICK 1000
> -
> -#define CONFIGURE_MAXIMUM_TASKS 2
> -#define CONFIGURE_MAXIMUM_TIMERS 1
> -
> -#define CONFIGURE_INIT_TASK_PRIORITY PRIORITY_GREEN
> -#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
> -#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
> -
> -#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
> -
> -#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
> -
> -#define CONFIGURE_INIT
> -
> -#include <rtems/confdefs.h>
> diff --git a/testsuites/sptests/spintrcritical19/spintrcritical19.doc b/testsuites/sptests/spintrcritical19/spintrcritical19.doc
> deleted file mode 100644
> index 4228ff2..0000000
> --- a/testsuites/sptests/spintrcritical19/spintrcritical19.doc
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -This file describes the directives and concepts tested by this test set.
> -
> -test set name: spintrcritical19
> -
> -directives:
> -
> -  - rtems_task_suspend()
> -  - rtems_task_set_priority()
> -
> -concepts:
> -
> -  - Ensure that a priority change works during suspend requests from an
> -    interrupt service routine.
> diff --git a/testsuites/sptests/spintrcritical19/spintrcritical19.scn b/testsuites/sptests/spintrcritical19/spintrcritical19.scn
> deleted file mode 100644
> index 3d7d209..0000000
> --- a/testsuites/sptests/spintrcritical19/spintrcritical19.scn
> +++ /dev/null
> @@ -1,4 +0,0 @@
> -*** TEST INTERRUPT CRITICAL SECTION 19 ***
> -
> -Support - rtems_timer_create - creating timer 1
> -*** END OF TEST INTERRUPT CRITICAL SECTION 19 ***
> --
> 1.7.7
>
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel


-- 
Joel Sherrill, Ph.D.             Director of Research & Development
joel.sherrill at OARcorp.com        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
Support Available                (256) 722-9985




More information about the devel mailing list