[rtems commit] score: Add thread priority to scheduler nodes

Sebastian Huber sebh at rtems.org
Wed Jun 22 12:48:40 UTC 2016


Module:    rtems
Branch:    master
Commit:    9bfad8cd519f17cbb26a672868169fcd304d5bd5
Changeset: http://git.rtems.org/rtems/commit/?id=9bfad8cd519f17cbb26a672868169fcd304d5bd5

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Jun  8 22:22:46 2016 +0200

score: Add thread priority to scheduler nodes

The thread priority is manifest in two independent areas.  One area is
the user visible thread priority along with a potential thread queue.
The other is the scheduler.  Currently, a thread priority update via
_Thread_Change_priority() first updates the user visble thread priority
and the thread queue, then the scheduler is notified if necessary.  The
priority is passed to the scheduler via a local variable.  A generation
counter ensures that the scheduler discards out-of-date priorities.

This use of a local variable ties the update in these two areas close
together.  For later enhancements and the OMIP locking protocol
implementation we need more flexibility.  Add a thread priority
information block to Scheduler_Node and synchronize priority value
updates via a sequence lock on SMP configurations.

Update #2556.

---

 cpukit/score/Makefile.am                           |   3 -
 cpukit/score/include/rtems/score/scheduler.h       |  74 +++++++-----
 cpukit/score/include/rtems/score/schedulercbs.h    |   6 +-
 cpukit/score/include/rtems/score/scheduleredf.h    |  27 +----
 cpukit/score/include/rtems/score/schedulerimpl.h   | 133 ++++++++++++---------
 .../score/include/rtems/score/schedulerpriority.h  |  30 +++--
 .../rtems/score/schedulerpriorityaffinitysmp.h     |  17 ++-
 .../include/rtems/score/schedulerpriorityimpl.h    |   1 +
 .../include/rtems/score/schedulerprioritysmp.h     |  18 +--
 cpukit/score/include/rtems/score/schedulersimple.h |   9 +-
 .../score/include/rtems/score/schedulersimplesmp.h |  18 +--
 .../score/include/rtems/score/schedulersmpimpl.h   |  53 +++++---
 .../score/include/rtems/score/schedulerstrongapa.h |  18 +--
 cpukit/score/include/rtems/score/thread.h          |  16 ---
 cpukit/score/include/rtems/score/threadimpl.h      |   5 +
 cpukit/score/src/schedulercbsnodeinit.c            |   5 +-
 cpukit/score/src/schedulercbsunblock.c             |   4 +-
 cpukit/score/src/schedulerdefaultnodeinit.c        |   5 +-
 cpukit/score/src/schedulerdefaultupdate.c          |  33 -----
 cpukit/score/src/scheduleredfchangepriority.c      |  31 +++--
 cpukit/score/src/scheduleredfnodeinit.c            |   5 +-
 cpukit/score/src/scheduleredfunblock.c             |  14 ++-
 cpukit/score/src/scheduleredfupdate.c              |  38 ------
 cpukit/score/src/schedulerpriority.c               |  21 ++++
 cpukit/score/src/schedulerpriorityaffinitysmp.c    |  20 ++--
 cpukit/score/src/schedulerprioritychangepriority.c |  30 +++--
 cpukit/score/src/schedulerprioritysmp.c            |  42 +++----
 cpukit/score/src/schedulerpriorityunblock.c        |  28 +++--
 cpukit/score/src/schedulerpriorityupdate.c         |  39 ------
 cpukit/score/src/schedulersimplechangepriority.c   |  20 +++-
 cpukit/score/src/schedulersimplesmp.c              |  28 ++---
 cpukit/score/src/schedulerstrongapa.c              |  42 +++----
 cpukit/score/src/thread.c                          |   1 -
 cpukit/score/src/threadchangepriority.c            |  21 +---
 cpukit/score/src/threadinitialize.c                |   4 +-
 testsuites/smptests/smpscheduler03/init.c          |  25 ++--
 testsuites/sptests/spintrcritical23/init.c         |  57 ++-------
 37 files changed, 419 insertions(+), 522 deletions(-)

diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index a58aedc..f2ebac2 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -234,7 +234,6 @@ libscore_a_SOURCES += src/schedulerdefaultreleasejob.c
 libscore_a_SOURCES += src/schedulerdefaultschedule.c
 libscore_a_SOURCES += src/schedulerdefaultstartidle.c
 libscore_a_SOURCES += src/schedulerdefaulttick.c
-libscore_a_SOURCES += src/schedulerdefaultupdate.c
 
 ## SCHEDULERPRIORITY_C_FILES
 libscore_a_SOURCES += src/schedulerpriority.c \
@@ -242,7 +241,6 @@ libscore_a_SOURCES += src/schedulerpriority.c \
     src/schedulerprioritychangepriority.c \
     src/schedulerpriorityschedule.c \
     src/schedulerpriorityunblock.c \
-    src/schedulerpriorityupdate.c \
     src/schedulerpriorityyield.c
 
 ## SCHEDULERSIMPLE_C_FILES
@@ -261,7 +259,6 @@ libscore_a_SOURCES += src/scheduleredf.c \
     src/scheduleredfreleasejob.c \
     src/scheduleredfschedule.c \
     src/scheduleredfunblock.c \
-    src/scheduleredfupdate.c \
     src/scheduleredfyield.c
 
 ## SCHEDULERCBS_C_FILES
diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
index 73e2873..9f31d7a 100644
--- a/cpukit/score/include/rtems/score/scheduler.h
+++ b/cpukit/score/include/rtems/score/scheduler.h
@@ -20,6 +20,7 @@
 #define _RTEMS_SCORE_SCHEDULER_H
 
 #include <rtems/score/priority.h>
+#include <rtems/score/smplockseq.h>
 #include <rtems/score/thread.h>
 #if defined(__RTEMS_HAVE_SYS_CPUSET_H__) && defined(RTEMS_SMP)
   #include <sys/cpuset.h>
@@ -83,12 +84,10 @@ typedef struct {
     Thread_Control *
   );
 
-  /** @see _Scheduler_Change_priority() */
-  Scheduler_Void_or_thread ( *change_priority )(
+  /** @see _Scheduler_Update_priority() */
+  Scheduler_Void_or_thread ( *update_priority )(
     const Scheduler_Control *,
-    Thread_Control *,
-    Priority_Control,
-    bool
+    Thread_Control *
   );
 
   /** @see _Scheduler_Map_priority() */
@@ -129,18 +128,15 @@ typedef struct {
 #endif
 
   /** @see _Scheduler_Node_initialize() */
-  void ( *node_initialize )( const Scheduler_Control *, Thread_Control * );
-
-  /** @see _Scheduler_Node_destroy() */
-  void ( *node_destroy )( const Scheduler_Control *, Thread_Control * );
-
-  /** @see _Scheduler_Update_priority() */
-  void ( *update_priority )(
+  void ( *node_initialize )(
     const Scheduler_Control *,
     Thread_Control *,
     Priority_Control
   );
 
+  /** @see _Scheduler_Node_destroy() */
+  void ( *node_destroy )( const Scheduler_Control *, Thread_Control * );
+
   /** @see _Scheduler_Release_job() */
   void ( *release_job ) (
     const Scheduler_Control *,
@@ -338,6 +334,41 @@ struct Scheduler_Node {
    */
   Thread_Control *accepts_help;
 #endif
+
+  /**
+   * @brief The thread priority information used by the scheduler.
+   *
+   * The thread priority is manifest in two independent areas.  One area is the
+   * user visible thread priority along with a potential thread queue.  The
+   * other is the scheduler.  During a thread priority change, the user visible
+   * thread priority and the thread queue are first updated and the thread
+   * priority value here is changed.  Once this is done the scheduler is
+   * notified via the update priority operation, so that it can update its
+   * internal state and honour a new thread priority value.
+   */
+  struct {
+    /**
+     * @brief The thread priority value of this scheduler node.
+     *
+     * The producer of this value is _Thread_Change_priority().  The consumer
+     * is the scheduler via the unblock and update priority operations.
+     */
+    Priority_Control value;
+
+#if defined(RTEMS_SMP)
+    /**
+     * @brief Sequence lock to synchronize priority value updates.
+     */
+    SMP_sequence_lock_Control Lock;
+#endif
+
+    /**
+     * @brief In case a priority update is necessary and 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.
+     */
+    bool prepend_it;
+  } Priority;
 };
 
 /**
@@ -464,14 +495,16 @@ void _Scheduler_default_Schedule(
 );
 
 /**
- * @brief Does nothing.
+ * @brief Performs the scheduler base node initialization.
  *
  * @param[in] scheduler Unused.
  * @param[in] the_thread Unused.
+ * @param[in] priority The thread priority.
  */
 void _Scheduler_default_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 );
 
 /**
@@ -490,19 +523,6 @@ void _Scheduler_default_Node_destroy(
  *
  * @param[in] scheduler Unused.
  * @param[in] the_thread Unused.
- * @param[in] new_priority Unused.
- */
-void _Scheduler_default_Update_priority(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority
-);
-
-/**
- * @brief Does nothing.
- *
- * @param[in] scheduler Unused.
- * @param[in] the_thread Unused.
  * @param[in] deadline Unused.
  */
 void _Scheduler_default_Release_job(
diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h
index fea10d5..91e69d0 100644
--- a/cpukit/score/include/rtems/score/schedulercbs.h
+++ b/cpukit/score/include/rtems/score/schedulercbs.h
@@ -54,13 +54,12 @@ 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_EDF_Update_priority,  /* update priority entry point */ \
     _Scheduler_EDF_Map_priority,     /* map priority entry point */ \
     _Scheduler_EDF_Unmap_priority,   /* unmap priority entry point */ \
     SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
     _Scheduler_CBS_Node_initialize,  /* node initialize entry point */ \
     _Scheduler_default_Node_destroy, /* node destroy entry point */ \
-    _Scheduler_EDF_Update_priority,  /* update priority entry point */ \
     _Scheduler_CBS_Release_job,      /* new period of task */ \
     _Scheduler_default_Tick,         /* tick entry point */ \
     _Scheduler_default_Start_idle    /* start idle entry point */ \
@@ -346,7 +345,8 @@ void _Scheduler_CBS_Budget_callout(
  */
 void _Scheduler_CBS_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 );
 
 #ifdef __cplusplus
diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h
index 4eb5f49..e1dce6f 100644
--- a/cpukit/score/include/rtems/score/scheduleredf.h
+++ b/cpukit/score/include/rtems/score/scheduleredf.h
@@ -47,13 +47,12 @@ 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_Update_priority,  /* update priority entry point */ \
     _Scheduler_EDF_Map_priority,     /* map priority entry point */ \
     _Scheduler_EDF_Unmap_priority,   /* unmap priority entry point */ \
     SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
     _Scheduler_EDF_Node_initialize,  /* node initialize entry point */ \
     _Scheduler_default_Node_destroy, /* node destroy entry point */ \
-    _Scheduler_EDF_Update_priority,  /* update priority entry point */ \
     _Scheduler_EDF_Release_job,      /* new period of task */ \
     _Scheduler_default_Tick,         /* tick entry point */ \
     _Scheduler_default_Start_idle    /* start idle entry point */ \
@@ -156,26 +155,12 @@ void _Scheduler_EDF_Schedule(
  *
  *  @param[in] scheduler The scheduler instance.
  *  @param[in] the_thread being initialized.
+ *  @param[in] priority The thread priority.
  */
 void _Scheduler_EDF_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
-);
-
-/**
- *  @brief Updates position in the ready queue of @a the_thread.
- *
- *  This routine updates position in the ready queue of @a the_thread.
- *
- *  @param[in] scheduler The scheduler instance.
- *  @param[in] the_thread will have its scheduler specific information
- *             structure updated.
- *  @param[in] new_priority is the desired new priority.
- */
-void _Scheduler_EDF_Update_priority(
-  const Scheduler_Control *scheduler,
   Thread_Control          *the_thread,
-  Priority_Control         new_priority
+  Priority_Control         priority
 );
 
 /**
@@ -193,11 +178,9 @@ Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
   Thread_Control          *the_thread
 );
 
-Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
+Scheduler_Void_or_thread _Scheduler_EDF_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *the_thread
 );
 
 Priority_Control _Scheduler_EDF_Map_priority(
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index edad0d3..11347fe 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -341,12 +341,12 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Block( Thread_Control *the_thread )
 /**
  * @brief Unblocks a thread with respect to the scheduler.
  *
- * This routine adds @a the_thread to the scheduling decision for
- * the scheduler.  The primary task is to add the thread to the
- * ready queue per the schedulering policy and update any appropriate
- * scheduling variables, for example the heir thread.
+ * This operation must fetch the latest thread priority value for this
+ * scheduler instance and update its internal state if necessary.
  *
  * @param[in] the_thread The thread.
+ *
+ * @see _Scheduler_Node_get_priority().
  */
 RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread )
 {
@@ -374,24 +374,18 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread )
 /**
  * @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.
+ * On uni-processor configurations, this operation must evaluate the thread
+ * state.  In case the thread is not ready, then the priority update should be
+ * deferred to the next scheduler unblock operation.
  *
  * The operation must update the heir and thread dispatch necessary variables
  * in case the set of scheduled threads changes.
  *
  * @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.
+ *
+ * @see _Scheduler_Node_get_priority().
  */
-RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority(
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
-)
+RTEMS_INLINE_ROUTINE void _Scheduler_Update_priority( Thread_Control *the_thread )
 {
   const Scheduler_Control *own_scheduler;
   ISR_lock_Context         lock_context;
@@ -405,12 +399,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority(
 #if defined(RTEMS_SMP)
   needs_help =
 #endif
-  ( *own_scheduler->Operations.change_priority )(
-    own_scheduler,
-    the_thread,
-    new_priority,
-    prepend_it
-  );
+  ( *own_scheduler->Operations.update_priority )( own_scheduler, the_thread );
 
 #if defined(RTEMS_SMP)
   _Scheduler_Ask_for_help_if_necessary( needs_help );
@@ -466,13 +455,19 @@ RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Unmap_priority(
  *
  * @param[in] scheduler The scheduler instance.
  * @param[in] the_thread The thread containing the scheduler node.
+ * @param[in] priority The thread priority.
  */
 RTEMS_INLINE_ROUTINE void _Scheduler_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 )
 {
-  return ( *scheduler->Operations.node_initialize )( scheduler, the_thread );
+  ( *scheduler->Operations.node_initialize )(
+    scheduler,
+    the_thread,
+    priority
+  );
 }
 
 /**
@@ -493,32 +488,6 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_destroy(
 }
 
 /**
- * @brief Updates the scheduler about a priority change of a not ready thread.
- *
- * @param[in] the_thread The thread.
- * @param[in] new_priority The new priority of the thread.
- */
-RTEMS_INLINE_ROUTINE void _Scheduler_Update_priority(
-  Thread_Control   *the_thread,
-  Priority_Control  new_priority
-)
-{
-  const Scheduler_Control *scheduler;
-  ISR_lock_Context         lock_context;
-
-  scheduler = _Scheduler_Get( the_thread );
-  _Scheduler_Acquire_critical( scheduler, &lock_context );
-
-  ( *scheduler->Operations.update_priority )(
-    scheduler,
-    the_thread,
-    new_priority
-  );
-
-  _Scheduler_Release_critical( scheduler, &lock_context );
-}
-
-/**
  * @brief Releases a job of a thread with respect to the scheduler.
  *
  * @param[in] the_thread The thread.
@@ -639,8 +608,11 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_Set(
   _Scheduler_Node_destroy( current_scheduler, the_thread );
   the_thread->Scheduler.own_control = scheduler;
   the_thread->Scheduler.control = scheduler;
-  _Scheduler_Node_initialize( scheduler, the_thread );
-  _Scheduler_Update_priority( the_thread, the_thread->current_priority );
+  _Scheduler_Node_initialize(
+    scheduler,
+    the_thread,
+    the_thread->current_priority
+  );
 
   if ( _States_Is_ready( current_state ) ) {
     _Scheduler_Unblock( the_thread );
@@ -827,22 +799,73 @@ RTEMS_INLINE_ROUTINE Scheduler_Node *_Scheduler_Thread_get_node(
 }
 
 RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize(
-  Scheduler_Node *node,
-  Thread_Control *the_thread
+  Scheduler_Node   *node,
+  Thread_Control   *the_thread,
+  Priority_Control  priority
 )
 {
+  node->Priority.value = priority;
+  node->Priority.prepend_it = false;
+
 #if defined(RTEMS_SMP)
   node->user = the_thread;
   node->help_state = SCHEDULER_HELP_YOURSELF;
   node->owner = the_thread;
   node->idle = NULL;
   node->accepts_help = the_thread;
+  _SMP_sequence_lock_Initialize( &node->Priority.Lock );
 #else
-  (void) node;
   (void) the_thread;
 #endif
 }
 
+RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Node_get_priority(
+  Scheduler_Node *node,
+  bool           *prepend_it_p
+)
+{
+  Priority_Control priority;
+  bool             prepend_it;
+
+#if defined(RTEMS_SMP)
+  unsigned int     seq;
+
+  do {
+    seq = _SMP_sequence_lock_Read_begin( &node->Priority.Lock );
+#endif
+
+    priority = node->Priority.value;
+    prepend_it = node->Priority.prepend_it;
+
+#if defined(RTEMS_SMP)
+  } while ( _SMP_sequence_lock_Read_retry( &node->Priority.Lock, seq ) );
+#endif
+
+  *prepend_it_p = prepend_it;
+
+  return priority;
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Node_set_priority(
+  Scheduler_Node   *node,
+  Priority_Control  new_priority,
+  bool              prepend_it
+)
+{
+#if defined(RTEMS_SMP)
+  unsigned int seq;
+
+  seq = _SMP_sequence_lock_Write_begin( &node->Priority.Lock );
+#endif
+
+  node->Priority.value = new_priority;
+  node->Priority.prepend_it = prepend_it;
+
+#if defined(RTEMS_SMP)
+  _SMP_sequence_lock_Write_end( &node->Priority.Lock, seq );
+#endif
+}
+
 #if defined(RTEMS_SMP)
 /**
  * @brief Gets an idle thread from the scheduler instance.
diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
index d5e73c1..f2e0459 100644
--- a/cpukit/score/include/rtems/score/schedulerpriority.h
+++ b/cpukit/score/include/rtems/score/schedulerpriority.h
@@ -44,13 +44,12 @@ extern "C" {
     _Scheduler_priority_Yield,            /* yield entry point */ \
     _Scheduler_priority_Block,            /* block entry point */ \
     _Scheduler_priority_Unblock,          /* unblock entry point */ \
-    _Scheduler_priority_Change_priority,  /* change priority entry point */ \
+    _Scheduler_priority_Update_priority,  /* update priority entry point */ \
     _Scheduler_default_Map_priority,      /* map priority entry point */ \
     _Scheduler_default_Unmap_priority,    /* unmap priority entry point */ \
     SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
-    _Scheduler_default_Node_initialize,   /* node initialize entry point */ \
+    _Scheduler_priority_Node_initialize,  /* node initialize entry point */ \
     _Scheduler_default_Node_destroy,      /* node destroy entry point */ \
-    _Scheduler_priority_Update_priority,  /* update priority entry point */ \
     _Scheduler_default_Release_job,       /* new period of task */ \
     _Scheduler_default_Tick,              /* tick entry point */ \
     _Scheduler_default_Start_idle         /* start idle entry point */ \
@@ -78,6 +77,11 @@ typedef struct {
  * @brief Data for ready queue operations.
  */
 typedef struct {
+  /**
+   * @brief The thread priority currently used by the scheduler.
+   */
+  unsigned int current_priority;
+
   /** This field points to the Ready FIFO for this thread's priority. */
   Chain_Control                        *ready_chain;
 
@@ -134,16 +138,6 @@ void _Scheduler_priority_Schedule(
 );
 
 /**
- *  @brief Updates the scheduler node to reflect the new priority of the
- *  thread.
- */
-void _Scheduler_priority_Update_priority(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority
-);
-
-/**
  *  @brief Add @a the_thread to the scheduling decision.
  *
  *  This routine adds @a the_thread to the scheduling decision,
@@ -158,11 +152,15 @@ Scheduler_Void_or_thread _Scheduler_priority_Unblock(
   Thread_Control          *the_thread
 );
 
-Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
+Scheduler_Void_or_thread _Scheduler_priority_Update_priority(
+  const Scheduler_Control *scheduler,
+  Thread_Control          *the_thread
+);
+
+void _Scheduler_priority_Node_initialize(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Priority_Control         priority
 );
 
 /**
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
index b0a7044..2c9b496 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
@@ -54,13 +54,12 @@ extern "C" {
     _Scheduler_priority_SMP_Yield, \
     _Scheduler_priority_affinity_SMP_Block, \
     _Scheduler_priority_affinity_SMP_Unblock, \
-    _Scheduler_priority_affinity_SMP_Change_priority, \
+    _Scheduler_priority_affinity_SMP_Update_priority, \
     _Scheduler_default_Map_priority, \
     _Scheduler_default_Unmap_priority, \
     _Scheduler_priority_affinity_SMP_Ask_for_help, \
     _Scheduler_priority_affinity_SMP_Node_initialize, \
     _Scheduler_default_Node_destroy, \
-    _Scheduler_priority_SMP_Update_priority, \
     _Scheduler_default_Release_job, \
     _Scheduler_default_Tick, \
     _Scheduler_SMP_Start_idle, \
@@ -76,10 +75,12 @@ extern "C" {
  *  @param[in] scheduler points to the scheduler specific information.
  *  @param[in] thread is the thread the scheduler is allocating
  *             management memory for.
+ *  @param[in] priority is the thread priority.
  */
 void _Scheduler_priority_affinity_SMP_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 );
 
 /**
@@ -127,18 +128,14 @@ bool _Scheduler_priority_affinity_SMP_Get_affinity(
 );
 
 /**
- * @brief Change priority for the priority affinity SMP scheduler.
+ * @brief Update priority for the priority affinity SMP scheduler.
  *
  * @param[in] scheduler The scheduler of the thread.
  * @param[in] the_thread The associated thread.
- * @param[in] new_priority The new priority for the thread.
- * @param[in] prepend_it Append or prepend the thread to its priority FIFO.
  */
-Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority(
+Thread_Control *_Scheduler_priority_affinity_SMP_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *the_thread
 );
 
 Thread_Control *_Scheduler_priority_affinity_SMP_Ask_for_help(
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
index d709818..0f576b6 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
@@ -210,6 +210,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_update(
   Chain_Control                  *ready_queues
 )
 {
+  ready_queue->current_priority = new_priority;
   ready_queue->ready_chain = &ready_queues[ new_priority ];
 
   _Priority_bit_map_Initialize_information(
diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
index 0af7000..051e44f 100644
--- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
@@ -83,13 +83,12 @@ typedef struct {
     _Scheduler_priority_SMP_Yield, \
     _Scheduler_priority_SMP_Block, \
     _Scheduler_priority_SMP_Unblock, \
-    _Scheduler_priority_SMP_Change_priority, \
+    _Scheduler_priority_SMP_Update_priority, \
     _Scheduler_default_Map_priority, \
     _Scheduler_default_Unmap_priority, \
     _Scheduler_priority_SMP_Ask_for_help, \
     _Scheduler_priority_SMP_Node_initialize, \
     _Scheduler_default_Node_destroy, \
-    _Scheduler_priority_SMP_Update_priority, \
     _Scheduler_default_Release_job, \
     _Scheduler_default_Tick, \
     _Scheduler_SMP_Start_idle \
@@ -100,7 +99,8 @@ void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler );
 
 void _Scheduler_priority_SMP_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control *thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 );
 
 void _Scheduler_priority_SMP_Block(
@@ -113,11 +113,9 @@ Thread_Control *_Scheduler_priority_SMP_Unblock(
   Thread_Control *thread
 );
 
-Thread_Control *_Scheduler_priority_SMP_Change_priority(
+Thread_Control *_Scheduler_priority_SMP_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *the_thread
 );
 
 Thread_Control *_Scheduler_priority_SMP_Ask_for_help(
@@ -126,12 +124,6 @@ Thread_Control *_Scheduler_priority_SMP_Ask_for_help(
   Thread_Control          *offers_help
 );
 
-void _Scheduler_priority_SMP_Update_priority(
-  const Scheduler_Control *scheduler,
-  Thread_Control *thread,
-  Priority_Control new_priority
-);
-
 Thread_Control *_Scheduler_priority_SMP_Yield(
   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 00f8dd7..3fa4b33 100644
--- a/cpukit/score/include/rtems/score/schedulersimple.h
+++ b/cpukit/score/include/rtems/score/schedulersimple.h
@@ -44,13 +44,12 @@ 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_simple_Update_priority,    /* update priority entry point */ \
     _Scheduler_default_Map_priority,      /* map priority entry point */ \
     _Scheduler_default_Unmap_priority,    /* unmap priority entry point */ \
     SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
     _Scheduler_default_Node_initialize,   /* node initialize entry point */ \
     _Scheduler_default_Node_destroy,      /* node destroy entry point */ \
-    _Scheduler_default_Update_priority,   /* update priority entry point */ \
     _Scheduler_default_Release_job,       /* new period of task */ \
     _Scheduler_default_Tick,              /* tick entry point */ \
     _Scheduler_default_Start_idle         /* start idle entry point */ \
@@ -145,11 +144,9 @@ Scheduler_Void_or_thread _Scheduler_simple_Unblock(
   Thread_Control          *the_thread
 );
 
-Scheduler_Void_or_thread _Scheduler_simple_Change_priority(
+Scheduler_Void_or_thread _Scheduler_simple_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *the_thread
 );
 
 /**@}*/
diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h
index 31c837d..0a05546 100644
--- a/cpukit/score/include/rtems/score/schedulersimplesmp.h
+++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h
@@ -66,13 +66,12 @@ typedef struct {
     _Scheduler_simple_SMP_Yield, \
     _Scheduler_simple_SMP_Block, \
     _Scheduler_simple_SMP_Unblock, \
-    _Scheduler_simple_SMP_Change_priority, \
+    _Scheduler_simple_SMP_Update_priority, \
     _Scheduler_default_Map_priority, \
     _Scheduler_default_Unmap_priority, \
     _Scheduler_simple_SMP_Ask_for_help, \
     _Scheduler_simple_SMP_Node_initialize, \
     _Scheduler_default_Node_destroy, \
-    _Scheduler_simple_SMP_Update_priority, \
     _Scheduler_default_Release_job, \
     _Scheduler_default_Tick, \
     _Scheduler_SMP_Start_idle \
@@ -83,7 +82,8 @@ void _Scheduler_simple_SMP_Initialize( const Scheduler_Control *scheduler );
 
 void _Scheduler_simple_SMP_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 );
 
 void _Scheduler_simple_SMP_Block(
@@ -96,11 +96,9 @@ Thread_Control *_Scheduler_simple_SMP_Unblock(
   Thread_Control *thread
 );
 
-Thread_Control *_Scheduler_simple_SMP_Change_priority(
+Thread_Control *_Scheduler_simple_SMP_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *the_thread
 );
 
 Thread_Control *_Scheduler_simple_SMP_Ask_for_help(
@@ -109,12 +107,6 @@ Thread_Control *_Scheduler_simple_SMP_Ask_for_help(
   Thread_Control          *needs_help
 );
 
-void _Scheduler_simple_SMP_Update_priority(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *thread,
-  Priority_Control         new_priority
-);
-
 Thread_Control *_Scheduler_simple_SMP_Yield(
   const Scheduler_Control *scheduler,
   Thread_Control *thread
diff --git a/cpukit/score/include/rtems/score/schedulersmpimpl.h b/cpukit/score/include/rtems/score/schedulersmpimpl.h
index a395f2c..a6796a5 100644
--- a/cpukit/score/include/rtems/score/schedulersmpimpl.h
+++ b/cpukit/score/include/rtems/score/schedulersmpimpl.h
@@ -387,11 +387,13 @@ static inline Scheduler_SMP_Node *_Scheduler_SMP_Node_downcast(
 
 static inline void _Scheduler_SMP_Node_initialize(
   Scheduler_SMP_Node *node,
-  Thread_Control     *thread
+  Thread_Control     *thread,
+  Priority_Control    priority
 )
 {
-  _Scheduler_Node_do_initialize( &node->Base, thread );
+  _Scheduler_Node_do_initialize( &node->Base, thread, priority );
   node->state = SCHEDULER_SMP_NODE_BLOCKED;
+  node->priority = priority;
 }
 
 static inline void _Scheduler_SMP_Node_update_priority(
@@ -889,23 +891,38 @@ static inline void _Scheduler_SMP_Block(
 }
 
 static inline Thread_Control *_Scheduler_SMP_Unblock(
-  Scheduler_Context             *context,
-  Thread_Control                *thread,
-  Scheduler_SMP_Enqueue          enqueue_fifo
+  Scheduler_Context     *context,
+  Thread_Control        *thread,
+  Scheduler_SMP_Update   update,
+  Scheduler_SMP_Enqueue  enqueue_fifo
 )
 {
-  Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node( thread );
-  bool is_scheduled = node->state == SCHEDULER_SMP_NODE_SCHEDULED;
-  bool unblock = _Scheduler_Unblock_node(
+  Scheduler_SMP_Node *node;
+  bool                is_scheduled;
+  bool                unblock;
+  Thread_Control     *needs_help;
+
+  node = _Scheduler_SMP_Thread_get_node( thread );
+  is_scheduled = ( node->state == SCHEDULER_SMP_NODE_SCHEDULED );
+  unblock = _Scheduler_Unblock_node(
     context,
     thread,
     &node->Base,
     is_scheduled,
     _Scheduler_SMP_Release_idle_thread
   );
-  Thread_Control *needs_help;
 
   if ( unblock ) {
+    Priority_Control new_priority;
+    bool             prepend_it;
+
+    new_priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
+    (void) prepend_it;
+
+    if ( new_priority != node->priority ) {
+      ( *update )( context, &node->Base, new_priority );
+    }
+
     if ( node->state == SCHEDULER_SMP_NODE_BLOCKED ) {
       _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
 
@@ -931,11 +948,9 @@ static inline Thread_Control *_Scheduler_SMP_Unblock(
   return needs_help;
 }
 
-static inline Thread_Control *_Scheduler_SMP_Change_priority(
+static inline Thread_Control *_Scheduler_SMP_Update_priority(
   Scheduler_Context               *context,
   Thread_Control                  *thread,
-  Priority_Control                 new_priority,
-  bool                             prepend_it,
   Scheduler_SMP_Extract            extract_from_ready,
   Scheduler_SMP_Update             update,
   Scheduler_SMP_Enqueue            enqueue_fifo,
@@ -944,8 +959,18 @@ static inline Thread_Control *_Scheduler_SMP_Change_priority(
   Scheduler_SMP_Enqueue_scheduled  enqueue_scheduled_lifo
 )
 {
-  Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( thread );
-  Thread_Control *needs_help;
+  Scheduler_SMP_Node *node;
+  Thread_Control     *needs_help;
+  Priority_Control    new_priority;
+  bool                prepend_it;
+
+  node = _Scheduler_SMP_Thread_get_own_node( thread );
+  new_priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
+
+  if ( new_priority == node->priority ) {
+    /* Nothing to do */
+    return NULL;
+  }
 
   if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) {
     _Scheduler_SMP_Extract_from_scheduled( &node->Base );
diff --git a/cpukit/score/include/rtems/score/schedulerstrongapa.h b/cpukit/score/include/rtems/score/schedulerstrongapa.h
index d7c3888..e2a33af 100644
--- a/cpukit/score/include/rtems/score/schedulerstrongapa.h
+++ b/cpukit/score/include/rtems/score/schedulerstrongapa.h
@@ -83,13 +83,12 @@ typedef struct {
     _Scheduler_strong_APA_Yield, \
     _Scheduler_strong_APA_Block, \
     _Scheduler_strong_APA_Unblock, \
-    _Scheduler_strong_APA_Change_priority, \
+    _Scheduler_strong_APA_Update_priority, \
     _Scheduler_default_Map_priority, \
     _Scheduler_default_Unmap_priority, \
     _Scheduler_strong_APA_Ask_for_help, \
     _Scheduler_strong_APA_Node_initialize, \
     _Scheduler_default_Node_destroy, \
-    _Scheduler_strong_APA_Update_priority, \
     _Scheduler_default_Release_job, \
     _Scheduler_default_Tick, \
     _Scheduler_SMP_Start_idle \
@@ -100,7 +99,8 @@ void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler );
 
 void _Scheduler_strong_APA_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 );
 
 void _Scheduler_strong_APA_Block(
@@ -113,11 +113,9 @@ Thread_Control *_Scheduler_strong_APA_Unblock(
   Thread_Control          *the_thread
 );
 
-Thread_Control *_Scheduler_strong_APA_Change_priority(
+Thread_Control *_Scheduler_strong_APA_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *the_thread
 );
 
 Thread_Control *_Scheduler_strong_APA_Ask_for_help(
@@ -126,12 +124,6 @@ Thread_Control *_Scheduler_strong_APA_Ask_for_help(
   Thread_Control          *offers_help
 );
 
-void _Scheduler_strong_APA_Update_priority(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority
-);
-
 Thread_Control *_Scheduler_strong_APA_Yield(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index cde31b4..4d498e5 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -363,14 +363,6 @@ typedef struct {
   Priority_Control         real_priority;
 
   /**
-   * @brief Generation of the current priority value.
-   *
-   * It is used in _Thread_Change_priority() to serialize the update of
-   * priority related data structures.
-   */
-  uint32_t                 priority_generation;
-
-  /**
    * @brief Hints if a priority restore is necessary once the resource count
    * changes from one to zero.
    *
@@ -744,14 +736,6 @@ struct _Thread_Control {
   Priority_Control         real_priority;
 
   /**
-   * @brief Generation of the current priority value.
-   *
-   * It is used in _Thread_Change_priority() to serialize the update of
-   * priority related data structures.
-   */
-  uint32_t                 priority_generation;
-
-  /**
    * @brief Hints if a priority restore is necessary once the resource count
    * changes from one to zero.
    *
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 164773a..6bb7815 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -253,6 +253,11 @@ void _Thread_Cancel(
  */
 void _Thread_Close( Thread_Control *the_thread, Thread_Control *executing );
 
+RTEMS_INLINE_ROUTINE bool _Thread_Is_ready( const Thread_Control *the_thread )
+{
+  return _States_Is_ready( the_thread->current_state );
+}
+
 States_Control _Thread_Clear_state_locked(
   Thread_Control *the_thread,
   States_Control  state
diff --git a/cpukit/score/src/schedulercbsnodeinit.c b/cpukit/score/src/schedulercbsnodeinit.c
index df679b6..3aa825b 100644
--- a/cpukit/score/src/schedulercbsnodeinit.c
+++ b/cpukit/score/src/schedulercbsnodeinit.c
@@ -22,12 +22,13 @@
 
 void _Scheduler_CBS_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 )
 {
   Scheduler_CBS_Node *node;
 
-  _Scheduler_EDF_Node_initialize( scheduler, the_thread );
+  _Scheduler_EDF_Node_initialize( scheduler, the_thread, priority );
 
   node = _Scheduler_CBS_Thread_get_node( the_thread );
   node->cbs_server = NULL;
diff --git a/cpukit/score/src/schedulercbsunblock.c b/cpukit/score/src/schedulercbsunblock.c
index 3f5bd33..70db651 100644
--- a/cpukit/score/src/schedulercbsunblock.c
+++ b/cpukit/score/src/schedulercbsunblock.c
@@ -34,11 +34,13 @@ Scheduler_Void_or_thread _Scheduler_CBS_Unblock(
   Scheduler_CBS_Node    *node;
   Scheduler_CBS_Server  *serv_info;
   Priority_Control       priority;
+  bool                   prepend_it;
 
   context = _Scheduler_EDF_Get_context( scheduler );
   node = _Scheduler_CBS_Thread_get_node( the_thread );
   serv_info = node->cbs_server;
-  priority = node->Base.current_priority;
+  priority = _Scheduler_Node_get_priority( &node->Base.Base, &prepend_it );
+  (void) prepend_it;
 
   /*
    * Late unblock rule for deadline-driven tasks. The remaining time to
diff --git a/cpukit/score/src/schedulerdefaultnodeinit.c b/cpukit/score/src/schedulerdefaultnodeinit.c
index a96a528..de2b6c8 100644
--- a/cpukit/score/src/schedulerdefaultnodeinit.c
+++ b/cpukit/score/src/schedulerdefaultnodeinit.c
@@ -23,12 +23,13 @@
 
 void _Scheduler_default_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 )
 {
   Scheduler_Node *node = _Scheduler_Thread_get_own_node( the_thread );
 
   (void) scheduler;
 
-  _Scheduler_Node_do_initialize( node, the_thread );
+  _Scheduler_Node_do_initialize( node, the_thread, priority );
 }
diff --git a/cpukit/score/src/schedulerdefaultupdate.c b/cpukit/score/src/schedulerdefaultupdate.c
deleted file mode 100644
index fcdc838..0000000
--- a/cpukit/score/src/schedulerdefaultupdate.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @file
- *
- * @brief Scheduler Default Update Operation
- *
- * @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/scheduler.h>
-
-void _Scheduler_default_Update_priority(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority
-)
-{
-  (void) scheduler;
-  (void) the_thread;
-  (void) new_priority;
-}
diff --git a/cpukit/score/src/scheduleredfchangepriority.c b/cpukit/score/src/scheduleredfchangepriority.c
index a0f5ec7..9a73128 100644
--- a/cpukit/score/src/scheduleredfchangepriority.c
+++ b/cpukit/score/src/scheduleredfchangepriority.c
@@ -36,31 +36,42 @@ Priority_Control _Scheduler_EDF_Unmap_priority(
   return priority & ~SCHEDULER_EDF_PRIO_MSB;
 }
 
-Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
+Scheduler_Void_or_thread _Scheduler_EDF_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *the_thread
 )
 {
   Scheduler_EDF_Context *context;
   Scheduler_EDF_Node    *node;
+  Priority_Control       priority;
+  bool                   prepend_it;
+
+  if ( !_Thread_Is_ready( the_thread ) ) {
+    /* Nothing to do */
+    SCHEDULER_RETURN_VOID_OR_NULL;
+  }
 
-  context = _Scheduler_EDF_Get_context( scheduler );
   node = _Scheduler_EDF_Thread_get_node( the_thread );
+  priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
 
-  if ( ( new_priority & SCHEDULER_EDF_PRIO_MSB ) != 0 ) {
-    node->background_priority = new_priority;
+  if ( priority == node->current_priority ) {
+    /* Nothing to do */
+    SCHEDULER_RETURN_VOID_OR_NULL;
   }
 
-  node->current_priority = new_priority;
+  if ( ( priority & SCHEDULER_EDF_PRIO_MSB ) != 0 ) {
+    node->background_priority = priority;
+  }
+
+  node->current_priority = priority;
+  context = _Scheduler_EDF_Get_context( scheduler );
 
   _Scheduler_EDF_Extract( context, node );
 
   if ( prepend_it ) {
-    _Scheduler_EDF_Enqueue_first( context, node, new_priority );
+    _Scheduler_EDF_Enqueue_first( context, node, priority );
   } else {
-    _Scheduler_EDF_Enqueue( context, node, new_priority );
+    _Scheduler_EDF_Enqueue( context, node, priority );
   }
 
   _Scheduler_EDF_Schedule_body( scheduler, the_thread, false );
diff --git a/cpukit/score/src/scheduleredfnodeinit.c b/cpukit/score/src/scheduleredfnodeinit.c
index ec6d9ba..6005fa0 100644
--- a/cpukit/score/src/scheduleredfnodeinit.c
+++ b/cpukit/score/src/scheduleredfnodeinit.c
@@ -22,14 +22,15 @@
 
 void _Scheduler_EDF_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 )
 {
   Scheduler_EDF_Node *node = _Scheduler_EDF_Thread_get_node( the_thread );
 
   (void) scheduler;
 
-  _Scheduler_Node_do_initialize( &node->Base, the_thread );
+  _Scheduler_Node_do_initialize( &node->Base, the_thread, priority );
 
   node->thread = the_thread;
 }
diff --git a/cpukit/score/src/scheduleredfunblock.c b/cpukit/score/src/scheduleredfunblock.c
index b3acbcd..9f80fa9 100644
--- a/cpukit/score/src/scheduleredfunblock.c
+++ b/cpukit/score/src/scheduleredfunblock.c
@@ -29,11 +29,16 @@ Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
 {
   Scheduler_EDF_Context *context;
   Scheduler_EDF_Node    *node;
+  Priority_Control       priority;
+  bool                   prepend_it;
 
   context = _Scheduler_EDF_Get_context( scheduler );
   node = _Scheduler_EDF_Thread_get_node( the_thread );
+  priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
+  (void) prepend_it;
 
-  _Scheduler_EDF_Enqueue( context, node, node->current_priority );
+  node->current_priority = priority;
+  _Scheduler_EDF_Enqueue( context, node, priority );
 
   /*
    *  If the thread that was unblocked is more important than the heir,
@@ -47,11 +52,8 @@ Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
    *    Even if the thread isn't preemptible, if the new heir is
    *    a pseudo-ISR system task, we need to do a context switch.
    */
-  if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
-    _Scheduler_Update_heir(
-      the_thread,
-      the_thread->current_priority == PRIORITY_PSEUDO_ISR
-    );
+  if ( priority < _Thread_Heir->current_priority ) {
+    _Scheduler_Update_heir( the_thread, priority == PRIORITY_PSEUDO_ISR );
   }
 
   SCHEDULER_RETURN_VOID_OR_NULL;
diff --git a/cpukit/score/src/scheduleredfupdate.c b/cpukit/score/src/scheduleredfupdate.c
deleted file mode 100644
index 5d475fe..0000000
--- a/cpukit/score/src/scheduleredfupdate.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- *  @file
- *
- *  @brief Scheduler EDF Update
- *  @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_Update_priority(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority
-)
-{
-  Scheduler_EDF_Node *node;
-
-  node = _Scheduler_EDF_Thread_get_node( the_thread );
-
-  if ( ( new_priority & SCHEDULER_EDF_PRIO_MSB ) != 0 ) {
-    node->background_priority = new_priority;
-  }
-
-  node->current_priority = new_priority;
-}
diff --git a/cpukit/score/src/schedulerpriority.c b/cpukit/score/src/schedulerpriority.c
index 61505a4..2719697 100644
--- a/cpukit/score/src/schedulerpriority.c
+++ b/cpukit/score/src/schedulerpriority.c
@@ -32,3 +32,24 @@ void _Scheduler_priority_Initialize( const Scheduler_Control *scheduler )
     scheduler->maximum_priority
   );
 }
+
+void _Scheduler_priority_Node_initialize(
+  const Scheduler_Control *scheduler,
+  Thread_Control          *the_thread,
+  Priority_Control         priority
+)
+{
+  Scheduler_priority_Context *context;
+  Scheduler_priority_Node    *node;
+
+  context = _Scheduler_priority_Get_context( scheduler );
+  node = _Scheduler_priority_Thread_get_node( the_thread );
+
+  _Scheduler_Node_do_initialize( &node->Base, the_thread, priority );
+  _Scheduler_priority_Ready_queue_update(
+    &node->Ready_queue,
+    priority,
+    &context->Bit_map,
+    &context->Ready[ 0 ]
+  );
+}
diff --git a/cpukit/score/src/schedulerpriorityaffinitysmp.c b/cpukit/score/src/schedulerpriorityaffinitysmp.c
index fa56e2b..3618f4c 100644
--- a/cpukit/score/src/schedulerpriorityaffinitysmp.c
+++ b/cpukit/score/src/schedulerpriorityaffinitysmp.c
@@ -96,15 +96,14 @@ _Scheduler_priority_affinity_SMP_Node_downcast(
  */
 void _Scheduler_priority_affinity_SMP_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 )
 {
   Scheduler_priority_affinity_SMP_Node *node =
-    _Scheduler_priority_affinity_SMP_Thread_get_own_node( thread );
-
-  (void) scheduler;
+    _Scheduler_priority_affinity_SMP_Thread_get_own_node( the_thread );
 
-  _Scheduler_SMP_Node_initialize( &node->Base.Base, thread );
+  _Scheduler_priority_SMP_Node_initialize( scheduler, the_thread, priority );
 
   /*
    *  All we add is affinity information to the basic SMP node.
@@ -409,6 +408,7 @@ Thread_Control *_Scheduler_priority_affinity_SMP_Unblock(
   needs_help = _Scheduler_SMP_Unblock(
     context,
     thread,
+    _Scheduler_priority_SMP_Do_update,
     _Scheduler_priority_affinity_SMP_Enqueue_fifo
   );
 
@@ -535,21 +535,17 @@ static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo(
 /*
  * This is the public scheduler specific Change Priority operation.
  */
-Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority(
+Thread_Control *_Scheduler_priority_affinity_SMP_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *thread
 )
 {
   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
   Thread_Control    *displaced;
 
-  displaced = _Scheduler_SMP_Change_priority(
+  displaced = _Scheduler_SMP_Update_priority(
     context,
     thread,
-    new_priority,
-    prepend_it,
     _Scheduler_priority_SMP_Extract_from_ready,
     _Scheduler_priority_SMP_Do_update,
     _Scheduler_priority_affinity_SMP_Enqueue_fifo,
diff --git a/cpukit/score/src/schedulerprioritychangepriority.c b/cpukit/score/src/schedulerprioritychangepriority.c
index f883e02..04599f5 100644
--- a/cpukit/score/src/schedulerprioritychangepriority.c
+++ b/cpukit/score/src/schedulerprioritychangepriority.c
@@ -21,16 +21,30 @@
 
 #include <rtems/score/schedulerpriorityimpl.h>
 
-Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
+Scheduler_Void_or_thread _Scheduler_priority_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *the_thread
 )
 {
-  Scheduler_priority_Context *context =
-    _Scheduler_priority_Get_context( scheduler );
-  Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread );
+  Scheduler_priority_Context *context;
+  Scheduler_priority_Node    *node;
+  unsigned int                priority;
+  bool                        prepend_it;
+
+  if ( !_Thread_Is_ready( the_thread ) ) {
+    /* Nothing to do */
+    SCHEDULER_RETURN_VOID_OR_NULL;
+  }
+
+  node = _Scheduler_priority_Thread_get_node( the_thread );
+  priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
+
+  if ( priority == node->Ready_queue.current_priority ) {
+    /* Nothing to do */
+    SCHEDULER_RETURN_VOID_OR_NULL;
+  }
+
+  context = _Scheduler_priority_Get_context( scheduler );
 
   _Scheduler_priority_Ready_queue_extract(
     &the_thread->Object.Node,
@@ -40,7 +54,7 @@ Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
 
   _Scheduler_priority_Ready_queue_update(
     &node->Ready_queue,
-    new_priority,
+    priority,
     &context->Bit_map,
     &context->Ready[ 0 ]
   );
diff --git a/cpukit/score/src/schedulerprioritysmp.c b/cpukit/score/src/schedulerprioritysmp.c
index bd042d2..aba863e 100644
--- a/cpukit/score/src/schedulerprioritysmp.c
+++ b/cpukit/score/src/schedulerprioritysmp.c
@@ -47,24 +47,27 @@ void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler )
 
 void _Scheduler_priority_SMP_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control *thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 )
 {
-  Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( thread );
-
-  _Scheduler_SMP_Node_initialize( node, thread );
-}
+  Scheduler_Context              *context;
+  Scheduler_priority_SMP_Context *self;
+  Scheduler_priority_SMP_Node    *node;
 
-void _Scheduler_priority_SMP_Update_priority(
-  const Scheduler_Control *scheduler,
-  Thread_Control *thread,
-  Priority_Control new_priority
-)
-{
-  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
-  Scheduler_Node *node = _Scheduler_Thread_get_node( thread );
+  context = _Scheduler_Get_context( scheduler );
+  self = _Scheduler_priority_SMP_Get_self( context );
+  node = _Scheduler_priority_SMP_Node_downcast(
+    _Scheduler_Thread_get_own_node( the_thread )
+  );
 
-  _Scheduler_priority_SMP_Do_update( context, node, new_priority );
+  _Scheduler_SMP_Node_initialize( &node->Base, the_thread, priority );
+  _Scheduler_priority_Ready_queue_update(
+    &node->Ready_queue,
+    priority,
+    &self->Bit_map,
+    &self->Ready[ 0 ]
+  );
 }
 
 static Scheduler_Node *_Scheduler_priority_SMP_Get_highest_ready(
@@ -213,24 +216,21 @@ Thread_Control *_Scheduler_priority_SMP_Unblock(
   return _Scheduler_SMP_Unblock(
     context,
     thread,
+    _Scheduler_priority_SMP_Do_update,
     _Scheduler_priority_SMP_Enqueue_fifo
   );
 }
 
-Thread_Control *_Scheduler_priority_SMP_Change_priority(
+Thread_Control *_Scheduler_priority_SMP_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *thread
 )
 {
   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
 
-  return _Scheduler_SMP_Change_priority(
+  return _Scheduler_SMP_Update_priority(
     context,
     thread,
-    new_priority,
-    prepend_it,
     _Scheduler_priority_SMP_Extract_from_ready,
     _Scheduler_priority_SMP_Do_update,
     _Scheduler_priority_SMP_Enqueue_fifo,
diff --git a/cpukit/score/src/schedulerpriorityunblock.c b/cpukit/score/src/schedulerpriorityunblock.c
index a912ebf..ba8501b 100644
--- a/cpukit/score/src/schedulerpriorityunblock.c
+++ b/cpukit/score/src/schedulerpriorityunblock.c
@@ -27,9 +27,24 @@ Scheduler_Void_or_thread _Scheduler_priority_Unblock (
   Thread_Control          *the_thread
 )
 {
-  Scheduler_priority_Context *context =
-    _Scheduler_priority_Get_context( scheduler );
-  Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread );
+  Scheduler_priority_Context *context;
+  Scheduler_priority_Node    *node;
+  unsigned int                priority;
+  bool                        prepend_it;
+
+  context = _Scheduler_priority_Get_context( scheduler );
+  node = _Scheduler_priority_Thread_get_node( the_thread );
+  priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
+  (void) prepend_it;
+
+  if ( priority != node->Ready_queue.current_priority ) {
+    _Scheduler_priority_Ready_queue_update(
+      &node->Ready_queue,
+      priority,
+      &context->Bit_map,
+      &context->Ready[ 0 ]
+    );
+  }
 
   _Scheduler_priority_Ready_queue_enqueue(
     &the_thread->Object.Node,
@@ -51,11 +66,8 @@ Scheduler_Void_or_thread _Scheduler_priority_Unblock (
    *    Even if the thread isn't preemptible, if the new heir is
    *    a pseudo-ISR system task, we need to do a context switch.
    */
-  if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
-    _Scheduler_Update_heir(
-      the_thread,
-      the_thread->current_priority == PRIORITY_PSEUDO_ISR
-    );
+  if ( priority < _Thread_Heir->current_priority ) {
+    _Scheduler_Update_heir( the_thread, priority == PRIORITY_PSEUDO_ISR );
   }
 
   SCHEDULER_RETURN_VOID_OR_NULL;
diff --git a/cpukit/score/src/schedulerpriorityupdate.c b/cpukit/score/src/schedulerpriorityupdate.c
deleted file mode 100644
index d2a7e6c..0000000
--- a/cpukit/score/src/schedulerpriorityupdate.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * @file
- *
- * @brief Update Scheduler Priority 
- * @ingroup ScoreScheduler
- */
-
-/*
- *  Copyright (C) 2010 Gedare Bloom.
- *  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_Update_priority(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority
-)
-{
-  Scheduler_priority_Context *context =
-    _Scheduler_priority_Get_context( scheduler );
-  Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread );
-
-  _Scheduler_priority_Ready_queue_update(
-    &node->Ready_queue,
-    new_priority,
-    &context->Bit_map,
-    &context->Ready[ 0 ]
-  );
-}
diff --git a/cpukit/score/src/schedulersimplechangepriority.c b/cpukit/score/src/schedulersimplechangepriority.c
index 9b94b3a..9d4a565 100644
--- a/cpukit/score/src/schedulersimplechangepriority.c
+++ b/cpukit/score/src/schedulersimplechangepriority.c
@@ -21,15 +21,23 @@
 
 #include <rtems/score/schedulersimpleimpl.h>
 
-Scheduler_Void_or_thread _Scheduler_simple_Change_priority(
+Scheduler_Void_or_thread _Scheduler_simple_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *the_thread
 )
 {
-  Scheduler_simple_Context *context =
-    _Scheduler_simple_Get_context( scheduler );
+  Scheduler_simple_Context *context;
+  Scheduler_Node           *node;
+  bool                      prepend_it;
+
+  if ( !_Thread_Is_ready( the_thread ) ) {
+    /* Nothing to do */
+    SCHEDULER_RETURN_VOID_OR_NULL;
+  }
+
+  context = _Scheduler_simple_Get_context( scheduler );
+  node = _Scheduler_Thread_get_node( the_thread );
+  _Scheduler_Node_get_priority( node, &prepend_it );
 
   _Scheduler_simple_Extract( scheduler, the_thread );
 
diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c
index 0f05a7d..f368ead 100644
--- a/cpukit/score/src/schedulersimplesmp.c
+++ b/cpukit/score/src/schedulersimplesmp.c
@@ -44,12 +44,13 @@ void _Scheduler_simple_SMP_Initialize( const Scheduler_Control *scheduler )
 
 void _Scheduler_simple_SMP_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
+  Thread_Control          *the_thread,
+  Priority_Control         priority
 )
 {
   Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( the_thread );
 
-  _Scheduler_SMP_Node_initialize( node, the_thread );
+  _Scheduler_SMP_Node_initialize( node, the_thread, priority );
 }
 
 static void _Scheduler_simple_SMP_Do_update(
@@ -65,18 +66,6 @@ static void _Scheduler_simple_SMP_Do_update(
   _Scheduler_SMP_Node_update_priority( node, new_priority );
 }
 
-void _Scheduler_simple_SMP_Update_priority(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *thread,
-  Priority_Control         new_priority
-)
-{
-  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
-  Scheduler_Node *node = _Scheduler_Thread_get_node( thread );
-
-  _Scheduler_simple_SMP_Do_update( context, node, new_priority );
-}
-
 static Scheduler_Node *_Scheduler_simple_SMP_Get_highest_ready(
   Scheduler_Context *context,
   Scheduler_Node    *node
@@ -295,24 +284,21 @@ Thread_Control *_Scheduler_simple_SMP_Unblock(
   return _Scheduler_SMP_Unblock(
     context,
     thread,
+    _Scheduler_simple_SMP_Do_update,
     _Scheduler_simple_SMP_Enqueue_fifo
   );
 }
 
-Thread_Control *_Scheduler_simple_SMP_Change_priority(
+Thread_Control *_Scheduler_simple_SMP_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *thread
 )
 {
   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
 
-  return _Scheduler_SMP_Change_priority(
+  return _Scheduler_SMP_Update_priority(
     context,
     thread,
-    new_priority,
-    prepend_it,
     _Scheduler_simple_SMP_Extract_from_ready,
     _Scheduler_simple_SMP_Do_update,
     _Scheduler_simple_SMP_Enqueue_fifo,
diff --git a/cpukit/score/src/schedulerstrongapa.c b/cpukit/score/src/schedulerstrongapa.c
index dd44097..51dac67 100644
--- a/cpukit/score/src/schedulerstrongapa.c
+++ b/cpukit/score/src/schedulerstrongapa.c
@@ -173,24 +173,27 @@ void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler )
 
 void _Scheduler_strong_APA_Node_initialize(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
-)
-{
-  Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( the_thread );
-
-  _Scheduler_SMP_Node_initialize( node, the_thread );
-}
-
-void _Scheduler_strong_APA_Update_priority(
-  const Scheduler_Control *scheduler,
   Thread_Control          *the_thread,
-  Priority_Control         new_priority
+  Priority_Control         priority
 )
 {
-  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
-  Scheduler_Node *node = _Scheduler_Thread_get_node( the_thread );
+  Scheduler_Context            *context;
+  Scheduler_strong_APA_Context *self;
+  Scheduler_strong_APA_Node    *node;
+
+  context = _Scheduler_Get_context( scheduler );
+  self = _Scheduler_strong_APA_Get_self( context );
+  node = _Scheduler_strong_APA_Node_downcast(
+    _Scheduler_Thread_get_own_node( the_thread )
+  );
 
-  _Scheduler_strong_APA_Do_update( context, node, new_priority );
+  _Scheduler_SMP_Node_initialize( &node->Base, the_thread, priority );
+  _Scheduler_priority_Ready_queue_update(
+    &node->Ready_queue,
+    priority,
+    &self->Bit_map,
+    &self->Ready[ 0 ]
+  );
 }
 
 static Scheduler_Node *_Scheduler_strong_APA_Get_highest_ready(
@@ -339,24 +342,21 @@ Thread_Control *_Scheduler_strong_APA_Unblock(
   return _Scheduler_SMP_Unblock(
     context,
     the_thread,
+    _Scheduler_strong_APA_Do_update,
     _Scheduler_strong_APA_Enqueue_fifo
   );
 }
 
-Thread_Control *_Scheduler_strong_APA_Change_priority(
+Thread_Control *_Scheduler_strong_APA_Update_priority(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread,
-  Priority_Control         new_priority,
-  bool                     prepend_it
+  Thread_Control          *the_thread
 )
 {
   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
 
-  return _Scheduler_SMP_Change_priority(
+  return _Scheduler_SMP_Update_priority(
     context,
     the_thread,
-    new_priority,
-    prepend_it,
     _Scheduler_strong_APA_Extract_from_ready,
     _Scheduler_strong_APA_Do_update,
     _Scheduler_strong_APA_Enqueue_fifo,
diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c
index 2e0bbd9..8028540 100644
--- a/cpukit/score/src/thread.c
+++ b/cpukit/score/src/thread.c
@@ -34,7 +34,6 @@ THREAD_OFFSET_ASSERT( Join_queue );
 THREAD_OFFSET_ASSERT( current_state );
 THREAD_OFFSET_ASSERT( current_priority );
 THREAD_OFFSET_ASSERT( real_priority );
-THREAD_OFFSET_ASSERT( priority_generation );
 THREAD_OFFSET_ASSERT( priority_restore_hint );
 THREAD_OFFSET_ASSERT( resource_count );
 THREAD_OFFSET_ASSERT( Wait );
diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c
index 152646f..7b22371 100644
--- a/cpukit/score/src/threadchangepriority.c
+++ b/cpukit/score/src/threadchangepriority.c
@@ -50,11 +50,12 @@ void _Thread_Change_priority(
    *  we are not REALLY changing priority.
    */
   if ( ( *filter )( the_thread, &new_priority, arg ) ) {
-    uint32_t my_generation;
+    Scheduler_Node *own_node;
+
+    own_node = _Scheduler_Thread_get_own_node( the_thread );
+    _Scheduler_Node_set_priority( own_node, new_priority, prepend_it );
 
-    my_generation = the_thread->priority_generation + 1;
     the_thread->current_priority = new_priority;
-    the_thread->priority_generation = my_generation;
 
     ( *the_thread->Wait.operations->priority_change )(
       the_thread,
@@ -65,19 +66,7 @@ void _Thread_Change_priority(
     _Thread_Lock_release( lock, &lock_context );
 
     _Thread_State_acquire( the_thread, &lock_context );
-
-    if ( the_thread->priority_generation == my_generation ) {
-      if ( _States_Is_ready( the_thread->current_state ) ) {
-        _Scheduler_Change_priority(
-          the_thread,
-          new_priority,
-          prepend_it
-        );
-      } else {
-        _Scheduler_Update_priority( the_thread, new_priority );
-      }
-    }
-
+    _Scheduler_Update_priority( the_thread );
     _Thread_State_release( the_thread, &lock_context );
   } else {
     _Thread_Lock_release( lock, &lock_context );
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index 229d68b..10dbf02 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -200,11 +200,9 @@ bool _Thread_Initialize(
 
   RTEMS_STATIC_ASSERT( THREAD_WAIT_FLAGS_INITIAL == 0, Wait_flags );
 
-  _Scheduler_Node_initialize( scheduler, the_thread );
+  _Scheduler_Node_initialize( scheduler, the_thread, priority );
   scheduler_node_initialized = true;
 
-  _Scheduler_Update_priority( the_thread, priority );
-
   /* POSIX Keys */
   _RBTree_Initialize_empty( &the_thread->Keys.Key_value_pairs );
   _ISR_lock_Initialize( &the_thread->Keys.Lock, "POSIX Key Value Pairs" );
diff --git a/testsuites/smptests/smpscheduler03/init.c b/testsuites/smptests/smpscheduler03/init.c
index d6a145c..f610b62 100644
--- a/testsuites/smptests/smpscheduler03/init.c
+++ b/testsuites/smptests/smpscheduler03/init.c
@@ -187,7 +187,7 @@ static void test_change_priority(void)
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 }
 
-static Thread_Control *change_priority_op(
+static Thread_Control *update_priority_op(
   Thread_Control *thread,
   Priority_Control new_priority,
   bool prepend_it
@@ -197,18 +197,17 @@ static Thread_Control *change_priority_op(
   ISR_lock_Context state_lock_context;
   ISR_lock_Context scheduler_lock_context;
   Thread_Control *needs_help;
+  Scheduler_Node *node;
+
+  thread->current_priority = new_priority;
+  node = _Scheduler_Thread_get_node(thread);
+  _Scheduler_Node_set_priority(node, new_priority, prepend_it);
 
   _Thread_State_acquire( thread, &state_lock_context );
   scheduler = _Scheduler_Get( thread );
   _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
 
-  thread->current_priority = new_priority;
-  needs_help = (*scheduler->Operations.change_priority)(
-    scheduler,
-    thread,
-    new_priority,
-    prepend_it
-  );
+  needs_help = (*scheduler->Operations.update_priority)( scheduler, thread);
 
   _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
   _Thread_State_release( thread, &state_lock_context );
@@ -216,7 +215,7 @@ static Thread_Control *change_priority_op(
   return needs_help;
 }
 
-static void test_case_change_priority_op(
+static void test_case_update_priority_op(
   Thread_Control *executing,
   Scheduler_SMP_Node *executing_node,
   Thread_Control *other,
@@ -244,7 +243,7 @@ static void test_case_change_priority_op(
   }
   rtems_test_assert(executing_node->state == start_state);
 
-  needs_help = change_priority_op(executing, prio, prepend_it);
+  needs_help = update_priority_op(executing, prio, prepend_it);
   rtems_test_assert(executing_node->state == new_state);
 
   if (start_state != new_state) {
@@ -269,7 +268,7 @@ static void test_case_change_priority_op(
   _Thread_Dispatch_enable( cpu_self );
 }
 
-static void test_change_priority_op(void)
+static void test_update_priority_op(void)
 {
   rtems_status_code sc;
   rtems_id task_id;
@@ -289,7 +288,7 @@ static void test_change_priority_op(void)
   for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
     for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) {
       for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) {
-        test_case_change_priority_op(
+        test_case_update_priority_op(
           executing,
           executing_node,
           other,
@@ -555,7 +554,7 @@ static void test_unblock_op(void)
 static void tests(void)
 {
   test_change_priority();
-  test_change_priority_op();
+  test_update_priority_op();
   test_yield_op();
   test_unblock_op();
 }
diff --git a/testsuites/sptests/spintrcritical23/init.c b/testsuites/sptests/spintrcritical23/init.c
index 7b00786..b485674 100644
--- a/testsuites/sptests/spintrcritical23/init.c
+++ b/testsuites/sptests/spintrcritical23/init.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2015, 2016 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -22,7 +22,7 @@
 #include <string.h>
 
 #include <rtems.h>
-#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/schedulerpriorityimpl.h>
 #include <rtems/score/threadimpl.h>
 
 const char rtems_test_name[] = "SPINTRCRITICAL 23";
@@ -30,37 +30,14 @@ const char rtems_test_name[] = "SPINTRCRITICAL 23";
 typedef struct {
   RTEMS_INTERRUPT_LOCK_MEMBER(lock)
   rtems_id task_id;
-  Thread_Control *tcb;
+  Scheduler_priority_Node *scheduler_node;
   rtems_task_priority priority_task;
   rtems_task_priority priority_interrupt;
-  uint32_t priority_generation;
-  Scheduler_priority_Node scheduler_node;
   bool done;
 } test_context;
 
 static test_context ctx_instance;
 
-static Thread_Control *get_tcb(rtems_id id)
-{
-  ISR_lock_Context lock_context;
-  Thread_Control *tcb;
-
-  tcb = _Thread_Get(id, &lock_context);
-  rtems_test_assert(tcb != NULL);
-  _ISR_lock_ISR_enable(&lock_context);
-
-  return tcb;
-}
-
-static bool scheduler_node_unchanged(const test_context *ctx)
-{
-   return memcmp(
-     &ctx->scheduler_node,
-     ctx->tcb->Scheduler.node,
-     sizeof(ctx->scheduler_node)
-   ) == 0;
-}
-
 static void change_priority(rtems_id timer, void *arg)
 {
   /* The arg is NULL */
@@ -69,8 +46,8 @@ static void change_priority(rtems_id timer, void *arg)
 
   rtems_interrupt_lock_acquire(&ctx->lock, &lock_context);
   if (
-    ctx->priority_generation != ctx->tcb->priority_generation
-      && scheduler_node_unchanged(ctx)
+    ctx->scheduler_node->Ready_queue.current_priority
+      != ctx->scheduler_node->Base.Priority.value
   ) {
     rtems_task_priority priority_interrupt;
     rtems_task_priority priority_task;
@@ -112,12 +89,6 @@ static bool test_body(void *arg)
   priority_interrupt = 1 + (priority_task + 1) % 3;
   ctx->priority_task = priority_task;
   ctx->priority_interrupt = priority_interrupt;
-  ctx->priority_generation = ctx->tcb->priority_generation;
-  memcpy(
-    &ctx->scheduler_node,
-    ctx->tcb->Scheduler.node,
-    sizeof(ctx->scheduler_node)
-  );
   rtems_interrupt_lock_release(&ctx->lock, &lock_context);
 
   sc = rtems_task_set_priority(
@@ -144,24 +115,14 @@ static bool test_body(void *arg)
 static void Init(rtems_task_argument arg)
 {
   test_context *ctx = &ctx_instance;
-  rtems_status_code sc;
 
   TEST_BEGIN();
 
   rtems_interrupt_lock_initialize(&ctx->lock, "Test");
   ctx->priority_task = 1;
-
-  sc = rtems_task_create(
-    rtems_build_name('T', 'E', 'S', 'T'),
-    ctx->priority_task,
-    RTEMS_MINIMUM_STACK_SIZE,
-    RTEMS_DEFAULT_MODES,
-    RTEMS_DEFAULT_ATTRIBUTES,
-    &ctx->task_id
-  );
-  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
-  ctx->tcb = get_tcb(ctx->task_id);
+  ctx->task_id = rtems_task_self();
+  ctx->scheduler_node =
+    _Scheduler_priority_Thread_get_node(_Thread_Get_executing());
 
   interrupt_critical_section_test(test_body, ctx, change_priority);
   rtems_test_assert(ctx->done);
@@ -175,7 +136,7 @@ static void Init(rtems_task_argument arg)
 
 #define CONFIGURE_MICROSECONDS_PER_TICK 1000
 
-#define CONFIGURE_MAXIMUM_TASKS 2
+#define CONFIGURE_MAXIMUM_TASKS 1
 #define CONFIGURE_MAXIMUM_TIMERS 1
 #define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
 



More information about the vc mailing list