Index: cpukit/libmisc/monitor/mon-task.c
===================================================================
--- cpukit/libmisc/monitor/mon-task.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/libmisc/monitor/mon-task.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -21,8 +21,7 @@
 )
 {
-    ISR_lock_Context  lock_context;
-    void             *lock;
+    Thread_queue_Context queue_context;
 
-    lock = _Thread_Lock_acquire( rtems_thread, &lock_context );
+    _Thread_Wait_acquire( rtems_thread, &queue_context );
 
     canonical_task->state = rtems_thread->current_state;
@@ -31,5 +30,5 @@
     canonical_task->wait_operations = rtems_thread->Wait.operations;
 
-    _Thread_Lock_release( lock, &lock_context );
+    _Thread_Wait_release( rtems_thread, &queue_context );
 }
 
Index: cpukit/posix/src/pthreadgetschedparam.c
===================================================================
--- cpukit/posix/src/pthreadgetschedparam.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/posix/src/pthreadgetschedparam.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -37,5 +37,5 @@
 {
   Thread_Control          *the_thread;
-  ISR_lock_Context         lock_context;
+  Thread_queue_Context     queue_context;
   POSIX_API_Control       *api;
   const Scheduler_Control *scheduler;
@@ -46,5 +46,5 @@
   }
 
-  the_thread = _Thread_Get( thread, &lock_context );
+  the_thread = _Thread_Get( thread, &queue_context.Lock_context );
 
   if ( the_thread == NULL ) {
@@ -54,5 +54,5 @@
   api = the_thread->API_Extensions[ THREAD_API_POSIX ];
 
-  _Thread_Lock_acquire_default_critical( the_thread, &lock_context );
+  _Thread_Wait_acquire_critical( the_thread, &queue_context );
 
   *policy = api->Attributes.schedpolicy;
@@ -62,5 +62,5 @@
   priority = the_thread->real_priority;
 
-  _Thread_Lock_release_default( the_thread, &lock_context );
+  _Thread_Wait_release( the_thread, &queue_context );
 
   param->sched_priority = _POSIX_Priority_From_core( scheduler, priority );
Index: cpukit/rtems/include/rtems/rtems/ratemonimpl.h
===================================================================
--- cpukit/rtems/include/rtems/rtems/ratemonimpl.h	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/rtems/include/rtems/rtems/ratemonimpl.h	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -74,5 +74,5 @@
 )
 {
-  _Thread_Lock_acquire_default_critical( the_thread, lock_context );
+  _Thread_Wait_acquire_default_critical( the_thread, lock_context );
 }
 
@@ -82,5 +82,5 @@
 )
 {
-  _Thread_Lock_release_default( the_thread, lock_context );
+  _Thread_Wait_release_default( the_thread, lock_context );
 }
 
Index: cpukit/rtems/src/eventreceive.c
===================================================================
--- cpukit/rtems/src/eventreceive.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/rtems/src/eventreceive.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -39,5 +39,5 @@
     Event_Control     *event;
 
-    executing = _Thread_Lock_acquire_default_for_executing( &lock_context );
+    executing = _Thread_Wait_acquire_default_for_executing( &lock_context );
     api = executing->API_Extensions[ THREAD_API_RTEMS ];
     event = &api->Event;
@@ -57,5 +57,5 @@
     } else {
       *event_out = event->pending_events;
-      _Thread_Lock_release_default( executing, &lock_context );
+      _Thread_Wait_release_default( executing, &lock_context );
       sc = RTEMS_SUCCESSFUL;
     }
Index: cpukit/rtems/src/eventseize.c
===================================================================
--- cpukit/rtems/src/eventseize.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/rtems/src/eventseize.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -51,5 +51,5 @@
     event->pending_events =
       _Event_sets_Clear( pending_events, seized_events );
-    _Thread_Lock_release_default( executing, lock_context );
+    _Thread_Wait_release_default( executing, lock_context );
     *event_out = seized_events;
     return RTEMS_SUCCESSFUL;
@@ -57,5 +57,5 @@
 
   if ( _Options_Is_no_wait( option_set ) ) {
-    _Thread_Lock_release_default( executing, lock_context );
+    _Thread_Wait_release_default( executing, lock_context );
     *event_out = seized_events;
     return RTEMS_UNSATISFIED;
@@ -79,5 +79,5 @@
 
   cpu_self = _Thread_Dispatch_disable_critical( lock_context );
-  _Thread_Lock_release_default( executing, lock_context );
+  _Thread_Wait_release_default( executing, lock_context );
 
   if ( ticks ) {
Index: cpukit/rtems/src/eventsurrender.c
===================================================================
--- cpukit/rtems/src/eventsurrender.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/rtems/src/eventsurrender.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -78,5 +78,5 @@
   bool            unblock;
 
-  _Thread_Lock_acquire_default_critical( the_thread, lock_context );
+  _Thread_Wait_acquire_default_critical( the_thread, lock_context );
 
   _Event_sets_Post( event_in, &event->pending_events );
@@ -117,5 +117,5 @@
 
     cpu_self = _Thread_Dispatch_disable_critical( lock_context );
-    _Thread_Lock_release_default( the_thread, lock_context );
+    _Thread_Wait_release_default( the_thread, lock_context );
 
     _Thread_Timer_remove( the_thread );
@@ -124,5 +124,5 @@
     _Thread_Dispatch_enable( cpu_self );
   } else {
-    _Thread_Lock_release_default( the_thread, lock_context );
+    _Thread_Wait_release_default( the_thread, lock_context );
   }
 
Index: cpukit/rtems/src/systemeventreceive.c
===================================================================
--- cpukit/rtems/src/systemeventreceive.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/rtems/src/systemeventreceive.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -45,5 +45,5 @@
     Event_Control     *event;
 
-    executing = _Thread_Lock_acquire_default_for_executing( &lock_context );
+    executing = _Thread_Wait_acquire_default_for_executing( &lock_context );
     api = executing->API_Extensions[ THREAD_API_RTEMS ];
     event = &api->System_event;
@@ -63,5 +63,5 @@
     } else {
       *event_out = event->pending_events;
-      _Thread_Lock_release_default( executing, &lock_context );
+      _Thread_Wait_release_default( executing, &lock_context );
       sc = RTEMS_SUCCESSFUL;
     }
Index: cpukit/rtems/src/tasksetscheduler.c
===================================================================
--- cpukit/rtems/src/tasksetscheduler.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/rtems/src/tasksetscheduler.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -29,8 +29,7 @@
   const Scheduler_Control *scheduler;
   Thread_Control          *the_thread;
-  ISR_lock_Context         lock_context;
-  ISR_lock_Context         state_lock_context;
+  Thread_queue_Context     queue_context;
+  ISR_lock_Context         state_context;
   Per_CPU_Control         *cpu_self;
-  void                    *lock;
   bool                     valid;
   Priority_Control         core_priority;
@@ -46,5 +45,5 @@
   }
 
-  the_thread = _Thread_Get( task_id, &lock_context );
+  the_thread = _Thread_Get( task_id, &queue_context.Lock_context );
 
   if ( the_thread == NULL ) {
@@ -58,14 +57,13 @@
   }
 
-  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
-  _ISR_lock_ISR_enable( &lock_context );
+  cpu_self = _Thread_Dispatch_disable_critical( &queue_context.Lock_context );
 
-  lock = _Thread_Lock_acquire( the_thread, &lock_context );
-  _Thread_State_acquire_critical( the_thread, &state_lock_context );
+  _Thread_Wait_acquire_critical( the_thread, &queue_context );
+  _Thread_State_acquire_critical( the_thread, &state_context );
 
   status = _Scheduler_Set( scheduler, the_thread, core_priority );
 
-  _Thread_State_release_critical( the_thread, &state_lock_context );
-  _Thread_Lock_release( lock, &lock_context );
+  _Thread_State_release_critical( the_thread, &state_context );
+  _Thread_Wait_release( the_thread, &queue_context );
   _Thread_Dispatch_enable( cpu_self );
   return _Status_Get( status );
Index: cpukit/score/include/rtems/score/schedulerimpl.h
===================================================================
--- cpukit/score/include/rtems/score/schedulerimpl.h	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/score/include/rtems/score/schedulerimpl.h	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -824,4 +824,18 @@
   _SMP_sequence_lock_Write_end( &node->Priority.Lock, seq );
 #endif
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Thread_set_priority(
+  Thread_Control   *the_thread,
+  Priority_Control  new_priority,
+  bool              prepend_it
+)
+{
+  Scheduler_Node *own_node;
+
+  own_node = _Scheduler_Thread_get_own_node( the_thread );
+  _Scheduler_Node_set_priority( own_node, new_priority, prepend_it );
+
+  the_thread->current_priority = new_priority;
 }
 
Index: cpukit/score/include/rtems/score/thread.h
===================================================================
--- cpukit/score/include/rtems/score/thread.h	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/score/include/rtems/score/thread.h	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -12,5 +12,5 @@
  *  On-Line Applications Research Corporation (OAR).
  *
- *  Copyright (c) 2014 embedded brains GmbH.
+ *  Copyright (c) 2014, 2016 embedded brains GmbH.
  *
  *  The license and distribution terms for this file may be
@@ -289,14 +289,4 @@
 
   /**
-   * @brief The current thread queue.
-   *
-   * In case this field is @c NULL, then the thread is not blocked on a thread
-   * queue.  This field is protected by the thread lock.
-   *
-   * @see _Thread_Lock_set() and _Thread_Wait_set_queue().
-   */
-  Thread_queue_Queue *queue;
-
-  /**
    * @brief This field contains several flags used to control the wait class
    * and state of a thread in case fine-grained locking is used.
@@ -308,10 +298,52 @@
 #endif
 
+#if defined(RTEMS_SMP)
+  /**
+   * @brief Thread wait lock control block.
+   *
+   * Parts of the thread wait information are protected by the thread wait
+   * default lock and additionally a thread queue lock in case the thread
+   * is enqueued on a thread queue.
+   *
+   * The thread wait lock mechanism protects the following thread variables
+   *  - POSIX_API_Control::Attributes,
+   *  - Thread_Control::current_priority,
+   *  - Thread_Control::Wait::Lock::Pending_requests,
+   *  - Thread_Control::Wait::queue, and
+   *  - Thread_Control::Wait::operations.
+   *
+   * @see _Thread_Wait_acquire(), _Thread_Wait_release(), _Thread_Wait_claim(),
+   *   _Thread_Wait_restore_default() and _Thread_Wait_tranquilize().
+   */
+  struct {
+    /**
+     * @brief Thread wait default lock.
+     */
+    ISR_lock_Control Default;
+
+    /**
+     * @brief The pending thread wait lock acquire or tranquilize requests in
+     * case the thread is enqueued on a thread queue.
+     */
+    Chain_Control Pending_requests;
+  } Lock;
+#endif
+
+  /**
+   * @brief The current thread queue.
+   *
+   * If this field is NULL the thread is not enqueued on a thread queue.  This
+   * field is protected by the thread wait default lock.
+   *
+   * @see _Thread_Wait_claim().
+   */
+  Thread_queue_Queue *queue;
+
   /**
    * @brief The current thread queue operations.
    *
-   * This field is protected by the thread lock.
-   *
-   * @see _Thread_Lock_set() and _Thread_Wait_set_operations().
+   * This field is protected by the thread lock wait default lock.
+   *
+   * @see _Thread_Wait_claim().
    */
   const Thread_queue_Operations *operations;
@@ -639,64 +671,4 @@
   void *        control;
 }Thread_Capture_control;
-
-#if defined(RTEMS_SMP)
-/**
- * @brief Thread lock control.
- *
- * The thread lock is either the default lock or the lock of the resource on
- * which the thread is currently blocked.  The generation number takes care
- * that the up to date lock is used.  Only resources using fine grained locking
- * provide their own lock.
- *
- * The thread lock protects the following thread variables
- *  - POSIX_API_Control::Attributes,
- *  - Thread_Control::current_priority,
- *  - Thread_Control::Wait::queue, and
- *  - Thread_Control::Wait::operations.
- *
- * @see _Thread_Lock_acquire(), _Thread_Lock_release(), _Thread_Lock_set() and
- * _Thread_Lock_restore_default().
- */
-typedef struct {
-  /**
-   * @brief The current thread lock.
-   *
-   * This is a plain ticket lock without SMP lock statistics support.  This
-   * enables external libraries to use thread locks since they are independent
-   * of the actual RTEMS build configuration, e.g. profiling enabled or
-   * disabled.
-   */
-  union {
-    /**
-     * @brief The current thread lock as an atomic unsigned integer pointer value.
-     */
-    Atomic_Uintptr atomic;
-
-    /**
-     * @brief The current thread lock as a normal pointer.
-     *
-     * Only provided for debugging purposes.
-     */
-    SMP_ticket_lock_Control *normal;
-  } current;
-
-  /**
-   * @brief The default thread lock in case the thread is not blocked on a
-   * resource.
-   */
-  SMP_ticket_lock_Control Default;
-
-#if defined(RTEMS_PROFILING)
-  /**
-   * @brief The thread lock statistics.
-   *
-   * These statistics are used by the executing thread in case it acquires a
-   * thread lock.  Thus the statistics are an aggregation of acquire and
-   * release operations of different locks.
-   */
-  SMP_lock_Stats Stats;
-#endif
-} Thread_Lock_control;
-#endif
 
 /**
@@ -771,11 +743,4 @@
      /*================= end of common block =================*/
 
-#if defined(RTEMS_SMP)
-  /**
-   * @brief Thread lock control.
-   */
-  Thread_Lock_control Lock;
-#endif
-
 #if defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
   /**
Index: cpukit/score/include/rtems/score/threadimpl.h
===================================================================
--- cpukit/score/include/rtems/score/threadimpl.h	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/score/include/rtems/score/threadimpl.h	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -12,5 +12,5 @@
  *  On-Line Applications Research Corporation (OAR).
  *
- *  Copyright (c) 2014-2015 embedded brains GmbH.
+ *  Copyright (c) 2014, 2016 embedded brains GmbH.
  *
  *  The license and distribution terms for this file may be
@@ -934,290 +934,435 @@
 
 /**
- * @brief Acquires the default thread lock inside a critical section
+ * @brief Acquires the thread wait default lock inside a critical section
  * (interrupts disabled).
  *
  * @param[in] the_thread The thread.
  * @param[in] lock_context The lock context used for the corresponding lock
- * release.
- *
- * @see _Thread_Lock_release_default().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Lock_acquire_default_critical(
+ *   release.
+ *
+ * @see _Thread_Wait_release_default_critical().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_default_critical(
   Thread_Control   *the_thread,
   ISR_lock_Context *lock_context
 )
 {
-  _Assert( _ISR_Get_level() != 0 );
-#if defined(RTEMS_SMP)
+  _ISR_lock_Acquire( &the_thread->Wait.Lock.Default, lock_context );
+}
+
+/**
+ * @brief Acquires the thread wait default lock and returns the executing
+ * thread.
+ *
+ * @param[in] lock_context The lock context used for the corresponding lock
+ *   release.
+ *
+ * @return The executing thread.
+ *
+ * @see _Thread_Wait_release_default().
+ */
+RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Wait_acquire_default_for_executing(
+  ISR_lock_Context *lock_context
+)
+{
+  Thread_Control *executing;
+
+  _ISR_lock_ISR_disable( lock_context );
+  executing = _Thread_Executing;
+  _Thread_Wait_acquire_default_critical( executing, lock_context );
+
+  return executing;
+}
+
+/**
+ * @brief Acquires the thread wait default lock and disables interrupts.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] lock_context The lock context used for the corresponding lock
+ *   release.
+ *
+ * @see _Thread_Wait_release_default().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_default(
+  Thread_Control   *the_thread,
+  ISR_lock_Context *lock_context
+)
+{
+  _ISR_lock_ISR_disable( lock_context );
+  _Thread_Wait_acquire_default_critical( the_thread, lock_context );
+}
+
+/**
+ * @brief Releases the thread wait default lock inside a critical section
+ * (interrupts disabled).
+ *
+ * The previous interrupt status is not restored.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] lock_context The lock context used for the corresponding lock
+ *   acquire.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_release_default_critical(
+  Thread_Control   *the_thread,
+  ISR_lock_Context *lock_context
+)
+{
+  _ISR_lock_Release( &the_thread->Wait.Lock.Default, lock_context );
+}
+
+/**
+ * @brief Releases the thread wait default lock and restores the previous
+ * interrupt status.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] lock_context The lock context used for the corresponding lock
+ *   acquire.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_release_default(
+  Thread_Control   *the_thread,
+  ISR_lock_Context *lock_context
+)
+{
+  _Thread_Wait_release_default_critical( the_thread, lock_context );
+  _ISR_lock_ISR_enable( lock_context );
+}
+
+#if defined(RTEMS_SMP)
+#define THREAD_QUEUE_CONTEXT_OF_REQUEST( node ) \
+  RTEMS_CONTAINER_OF( node, Thread_queue_Context, Wait.Gate.Node )
+
+RTEMS_INLINE_ROUTINE void _Thread_Wait_remove_request_locked(
+  Thread_Control       *the_thread,
+  Thread_queue_Context *queue_context
+)
+{
+  _Chain_Extract_unprotected( &queue_context->Wait.Gate.Node );
+
+  if ( !_Chain_Is_empty( &the_thread->Wait.Lock.Pending_requests ) ) {
+    Thread_queue_Context *first;
+
+    first = THREAD_QUEUE_CONTEXT_OF_REQUEST(
+      _Chain_First( &the_thread->Wait.Lock.Pending_requests )
+    );
+
+    _Thread_queue_Gate_open( &first->Wait.Gate );
+  }
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_queue_critical(
+  SMP_ticket_lock_Control *queue_lock,
+  Thread_queue_Context    *queue_context
+)
+{
   _SMP_ticket_lock_Acquire(
-    &the_thread->Lock.Default,
-    &_Thread_Executing->Lock.Stats,
-    &lock_context->Lock_context.Stats_context
+    queue_lock,
+    &_Thread_Executing->Potpourri_stats,
+    &queue_context->Lock_context.Lock_context.Stats_context
+  );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Wait_release_queue_critical(
+  SMP_ticket_lock_Control *queue_lock,
+  Thread_queue_Context    *queue_context
+)
+{
+  _SMP_ticket_lock_Release(
+    queue_lock,
+    &queue_context->Lock_context.Lock_context.Stats_context
+  );
+}
+#endif
+
+/**
+ * @brief Acquires the thread wait lock inside a critical section (interrupts
+ * disabled).
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context for the corresponding
+ *   _Thread_Wait_release_critical().
+ *
+ * @see _Thread_queue_Context_initialize().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_critical(
+  Thread_Control       *the_thread,
+  Thread_queue_Context *queue_context
+)
+{
+#if defined(RTEMS_SMP)
+  Thread_queue_Queue *queue;
+
+  _Thread_Wait_acquire_default_critical(
+    the_thread,
+    &queue_context->Lock_context
+  );
+
+  queue = the_thread->Wait.queue;
+  queue_context->Wait.queue = queue;
+  queue_context->Wait.operations = the_thread->Wait.operations;
+
+  if ( queue != NULL ) {
+    queue_context->Wait.queue_lock = &queue->Lock;
+    _Chain_Initialize_node( &queue_context->Wait.Gate.Node );
+    _Chain_Append_unprotected(
+      &the_thread->Wait.Lock.Pending_requests,
+      &queue_context->Wait.Gate.Node
+    );
+    _Thread_Wait_release_default_critical(
+      the_thread,
+      &queue_context->Lock_context
+    );
+    _Thread_Wait_acquire_queue_critical( &queue->Lock, queue_context );
+  } else {
+    queue_context->Wait.queue_lock = NULL;
+  }
+#else
+  (void) the_thread;
+  (void) queue_context;
+#endif
+}
+
+/**
+ * @brief Acquires the thread wait default lock and disables interrupts.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context for the corresponding
+ *   _Thread_Wait_release().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire(
+  Thread_Control       *the_thread,
+  Thread_queue_Context *queue_context
+)
+{
+  _Thread_queue_Context_initialize( queue_context );
+  _ISR_lock_ISR_disable( &queue_context->Lock_context );
+  _Thread_Wait_acquire_critical( the_thread, queue_context );
+}
+
+/**
+ * @brief Releases the thread wait lock inside a critical section (interrupts
+ * disabled).
+ *
+ * The previous interrupt status is not restored.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context used for corresponding
+ *   _Thread_Wait_acquire_critical().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_release_critical(
+  Thread_Control       *the_thread,
+  Thread_queue_Context *queue_context
+)
+{
+#if defined(RTEMS_SMP)
+  SMP_ticket_lock_Control *queue_lock;
+
+  queue_lock = queue_context->Wait.queue_lock;
+
+  if ( queue_lock != NULL ) {
+    _Thread_Wait_release_queue_critical( queue_lock, queue_context );
+    _Thread_Wait_acquire_default_critical(
+      the_thread,
+      &queue_context->Lock_context
+    );
+
+    _Thread_Wait_remove_request_locked( the_thread, queue_context );
+  }
+
+  _Thread_Wait_release_default_critical(
+    the_thread,
+    &queue_context->Lock_context
   );
 #else
   (void) the_thread;
-  (void) lock_context;
-#endif
-}
-
-/**
- * @brief Acquires the default thread lock and returns the executing thread.
- *
- * @param[in] lock_context The lock context used for the corresponding lock
- * release.
- *
- * @return The executing thread.
- *
- * @see _Thread_Lock_release_default().
- */
-RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Lock_acquire_default_for_executing(
-  ISR_lock_Context *lock_context
-)
-{
-  Thread_Control *executing;
-
-  _ISR_lock_ISR_disable( lock_context );
-  executing = _Thread_Executing;
-  _Thread_Lock_acquire_default_critical( executing, lock_context );
-
-  return executing;
-}
-
-/**
- * @brief Acquires the default thread lock.
- *
- * @param[in] the_thread The thread.
- * @param[in] lock_context The lock context used for the corresponding lock
- * release.
- *
- * @see _Thread_Lock_release_default().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Lock_acquire_default(
-  Thread_Control   *the_thread,
-  ISR_lock_Context *lock_context
-)
-{
-  _ISR_lock_ISR_disable( lock_context );
-  _Thread_Lock_acquire_default_critical( the_thread, lock_context );
-}
-
-/**
- * @brief Releases the thread lock inside a critical section (interrupts
- * disabled).
- *
- * The previous interrupt status is not restored.
- *
- * @param[in] lock The lock.
- * @param[in] lock_context The lock context used for the corresponding lock
- * acquire.
- */
-RTEMS_INLINE_ROUTINE void _Thread_Lock_release_critical(
-  void             *lock,
-  ISR_lock_Context *lock_context
-)
-{
-#if defined(RTEMS_SMP)
-  _SMP_ticket_lock_Release(
-    (SMP_ticket_lock_Control *) lock,
-    &lock_context->Lock_context.Stats_context
+  (void) queue_context;
+#endif
+}
+
+/**
+ * @brief Releases the thread wait lock and restores the previous interrupt
+ * status.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context used for corresponding
+ *   _Thread_Wait_acquire().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_release(
+  Thread_Control       *the_thread,
+  Thread_queue_Context *queue_context
+)
+{
+  _Thread_Wait_release_critical( the_thread, queue_context );
+  _ISR_lock_ISR_enable( &queue_context->Lock_context );
+}
+
+/**
+ * @brief Claims the thread wait queue and operations.
+ *
+ * The caller must not be the owner of the default thread wait lock.  The
+ * caller must be the owner of the corresponding thread queue lock.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue The new thread queue.
+ * @param[in] operations The new thread operations.
+ *
+ * @see _Thread_Wait_restore_default().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_claim(
+  Thread_Control                *the_thread,
+  Thread_queue_Queue            *queue,
+  const Thread_queue_Operations *operations
+)
+{
+  ISR_lock_Context lock_context;
+
+  _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
+
+  _Assert( the_thread->Wait.queue == NULL );
+  the_thread->Wait.queue = queue;
+  the_thread->Wait.operations = operations;
+
+  _Thread_Wait_release_default_critical( the_thread, &lock_context );
+}
+
+/**
+ * @brief Removes a thread wait lock request.
+ *
+ * On SMP configurations, removes a thread wait lock request.
+ *
+ * On other configurations, this function does nothing.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context used for corresponding
+ *   _Thread_Wait_acquire().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_remove_request(
+  Thread_Control       *the_thread,
+  Thread_queue_Context *queue_context
+)
+{
+#if defined(RTEMS_SMP)
+  ISR_lock_Context lock_context;
+
+  _Thread_Wait_acquire_default( the_thread, &lock_context );
+  _Thread_Wait_remove_request_locked( the_thread, queue_context );
+  _Thread_Wait_release_default( the_thread, &lock_context );
+#else
+  (void) the_thread;
+  (void) queue_context;
+#endif
+}
+
+/**
+ * @brief Restores the default thread wait queue and operations.
+ *
+ * The caller must be the owner of the current thread wait queue lock.
+ *
+ * On SMP configurations, the pending requests are updated to use the stale
+ * thread queue operations.
+ *
+ * @param[in] the_thread The thread.
+ *
+ * @see _Thread_Wait_claim().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_restore_default(
+  Thread_Control *the_thread
+)
+{
+#if defined(RTEMS_SMP)
+  ISR_lock_Context  lock_context;
+  Chain_Node       *node;
+  const Chain_Node *tail;
+
+  _Thread_Wait_acquire_default_critical(
+    the_thread,
+    &lock_context
   );
-#else
-  (void) lock;
-  (void) lock_context;
-#endif
-}
-
-/**
- * @brief Releases the thread lock.
- *
- * @param[in] lock The lock returned by _Thread_Lock_acquire().
- * @param[in] lock_context The lock context used for _Thread_Lock_acquire().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Lock_release(
-  void             *lock,
-  ISR_lock_Context *lock_context
-)
-{
-  _Thread_Lock_release_critical( lock, lock_context );
-  _ISR_lock_ISR_enable( lock_context );
-}
-
-/**
- * @brief Releases the default thread lock inside a critical section
- * (interrupts disabled).
- *
- * The previous interrupt status is not restored.
- *
- * @param[in] the_thread The thread.
- * @param[in] lock_context The lock context used for the corresponding lock
- * acquire.
- */
-RTEMS_INLINE_ROUTINE void _Thread_Lock_release_default_critical(
-  Thread_Control   *the_thread,
-  ISR_lock_Context *lock_context
-)
-{
-  _Thread_Lock_release_critical(
-#if defined(RTEMS_SMP)
-    &the_thread->Lock.Default,
-#else
-    NULL,
-#endif
-    lock_context
+
+  node = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
+  tail = _Chain_Immutable_tail( &the_thread->Wait.Lock.Pending_requests );
+
+  while ( node != tail ) {
+    Thread_queue_Context *queue_context;
+
+    queue_context = THREAD_QUEUE_CONTEXT_OF_REQUEST( node );
+    queue_context->Wait.queue = NULL;
+    queue_context->Wait.operations = &_Thread_queue_Operations_stale_queue;
+
+    node = _Chain_Next( node );
+  }
+#endif
+
+  the_thread->Wait.queue = NULL;
+  the_thread->Wait.operations = &_Thread_queue_Operations_default;
+
+#if defined(RTEMS_SMP)
+  _Thread_Wait_release_default_critical(
+    the_thread,
+    &lock_context
   );
-}
-
-/**
- * @brief Releases the default thread lock.
- *
- * @param[in] the_thread The thread.
- * @param[in] lock_context The lock context used for the corresponding lock
- * acquire.
- */
-RTEMS_INLINE_ROUTINE void _Thread_Lock_release_default(
-  Thread_Control   *the_thread,
-  ISR_lock_Context *lock_context
-)
-{
-  _Thread_Lock_release_default_critical( the_thread, lock_context );
-  _ISR_lock_ISR_enable( lock_context );
-}
-
-/**
- * @brief Acquires the thread lock.
- *
- * @param[in] the_thread The thread.
- * @param[in] lock_context The lock context for _Thread_Lock_release().
- *
- * @return The lock required by _Thread_Lock_release().
- */
-RTEMS_INLINE_ROUTINE void *_Thread_Lock_acquire(
-  Thread_Control   *the_thread,
-  ISR_lock_Context *lock_context
-)
-{
-#if defined(RTEMS_SMP)
-  SMP_ticket_lock_Control *lock_0;
-
-  while ( true ) {
-    SMP_ticket_lock_Control *lock_1;
-
-    _ISR_lock_ISR_disable( lock_context );
-
-    /*
-     * We assume that a normal load of pointer is identical to a relaxed atomic
-     * load.  Here, we may read an out-of-date lock.  However, only the owner
-     * of this out-of-date lock is allowed to set a new one.  Thus, we read at
-     * least this new lock ...
-     */
-    lock_0 = (SMP_ticket_lock_Control *) _Atomic_Load_uintptr(
-      &the_thread->Lock.current.atomic,
-      ATOMIC_ORDER_RELAXED
+#endif
+}
+
+/**
+ * @brief Tranquilizes the thread after a wait a thread queue.
+ *
+ * After the violent blocking procedure this function makes the thread calm and
+ * peaceful again so that it can carry out its normal work.
+ *
+ * On SMP configurations, ensures that all pending thread wait lock requests
+ * completed before the thread is able to begin a new thread wait procedure.
+ *
+ * On other configurations, this function does nothing.
+ *
+ * @param[in] the_thread The thread.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_tranquilize(
+  Thread_Control *the_thread
+)
+{
+#if defined(RTEMS_SMP)
+  Thread_queue_Context queue_context;
+
+  _Thread_queue_Context_initialize( &queue_context );
+  _Thread_Wait_acquire_default( the_thread, &queue_context.Lock_context );
+
+  if ( !_Chain_Is_empty( &the_thread->Wait.Lock.Pending_requests ) ) {
+    _Thread_queue_Gate_add(
+      &the_thread->Wait.Lock.Pending_requests,
+      &queue_context.Wait.Gate
     );
-
-    _SMP_ticket_lock_Acquire(
-      lock_0,
-      &_Thread_Executing->Lock.Stats,
-      &lock_context->Lock_context.Stats_context
-    );
-
-    /*
-     * We must use a load acquire here paired with the store release in
-     * _Thread_Lock_set_unprotected() to observe corresponding thread wait
-     * queue and thread wait operations.  It is important to do this after the
-     * lock acquire, since we may have the following scenario.
-     *
-     * - We read the default lock and try to acquire it.
-     * - The thread lock changes to a thread queue lock.
-     * - The thread lock is restored to the default lock.
-     * - We acquire the default lock and read it here again.
-     * - Now, we must read the restored default thread wait queue and thread
-     *   wait operations and this is not synchronized via the default thread
-     *   lock.
-     */
-    lock_1 = (SMP_ticket_lock_Control *) _Atomic_Load_uintptr(
-      &the_thread->Lock.current.atomic,
-      ATOMIC_ORDER_ACQUIRE
-    );
-
-    /*
-     * ... here, and so on.
-     */
-    if ( lock_0 == lock_1 ) {
-      return lock_0;
-    }
-
-    _Thread_Lock_release( lock_0, lock_context );
+    _Thread_Wait_release_default( the_thread, &queue_context.Lock_context );
+    _Thread_queue_Gate_wait( &queue_context.Wait.Gate );
+    _Thread_Wait_remove_request( the_thread, &queue_context );
+  } else {
+    _Thread_Wait_release_default( the_thread, &queue_context.Lock_context );
   }
 #else
-  _ISR_Local_disable( lock_context->isr_level );
-
-  return NULL;
-#endif
-}
-
-#if defined(RTEMS_SMP)
-/*
- * Internal function, use _Thread_Lock_set() or _Thread_Lock_restore_default()
- * instead.
- */
-RTEMS_INLINE_ROUTINE void _Thread_Lock_set_unprotected(
-  Thread_Control          *the_thread,
-  SMP_ticket_lock_Control *new_lock
-)
-{
-  _Atomic_Store_uintptr(
-    &the_thread->Lock.current.atomic,
-    (uintptr_t) new_lock,
-    ATOMIC_ORDER_RELEASE
-  );
-}
-#endif
-
-/**
- * @brief Sets a new thread lock.
- *
- * The caller must not be the owner of the default thread lock.  The caller
- * must be the owner of the new lock.
- *
- * @param[in] the_thread The thread.
- * @param[in] new_lock The new thread lock.
- */
-#if defined(RTEMS_SMP)
-RTEMS_INLINE_ROUTINE void _Thread_Lock_set(
-  Thread_Control          *the_thread,
-  SMP_ticket_lock_Control *new_lock
-)
-{
-  ISR_lock_Context lock_context;
-
-  _Thread_Lock_acquire_default_critical( the_thread, &lock_context );
-  _Assert( the_thread->Lock.current.normal == &the_thread->Lock.Default );
-  _Thread_Lock_set_unprotected( the_thread, new_lock );
-  _Thread_Lock_release_default_critical( the_thread, &lock_context );
-}
-#else
-#define _Thread_Lock_set( the_thread, new_lock ) \
-  do { } while ( 0 )
-#endif
-
-/**
- * @brief Restores the default thread lock.
- *
- * The caller must be the owner of the current thread lock.
- *
- * @param[in] the_thread The thread.
- */
-#if defined(RTEMS_SMP)
-RTEMS_INLINE_ROUTINE void _Thread_Lock_restore_default(
-  Thread_Control *the_thread
-)
-{
-  _Thread_Lock_set_unprotected( the_thread, &the_thread->Lock.Default );
-}
-#else
-#define _Thread_Lock_restore_default( the_thread ) \
-  do { } while ( 0 )
-#endif
+  (void) the_thread;
+#endif
+}
+
+/**
+ * @brief Cancels a thread wait on a thread queue.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context used for corresponding
+ *   _Thread_Wait_acquire().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_cancel(
+  Thread_Control       *the_thread,
+  Thread_queue_Context *queue_context
+)
+{
+  _Thread_queue_Context_extract( queue_context, the_thread );
+
+#if defined(RTEMS_SMP)
+  if ( queue_context->Wait.queue != NULL ) {
+#endif
+    _Thread_Wait_restore_default( the_thread );
+#if defined(RTEMS_SMP)
+  }
+#endif
+}
 
 /**
@@ -1389,56 +1534,4 @@
 
 /**
- * @brief Sets the thread queue.
- *
- * The caller must be the owner of the thread lock.
- *
- * @param[in] the_thread The thread.
- * @param[in] new_queue The new queue.
- *
- * @see _Thread_Lock_set().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_set_queue(
-  Thread_Control     *the_thread,
-  Thread_queue_Queue *new_queue
-)
-{
-  the_thread->Wait.queue = new_queue;
-}
-
-/**
- * @brief Sets the thread queue operations.
- *
- * The caller must be the owner of the thread lock.
- *
- * @param[in] the_thread The thread.
- * @param[in] new_operations The new queue operations.
- *
- * @see _Thread_Lock_set() and _Thread_Wait_restore_default_operations().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_set_operations(
-  Thread_Control                *the_thread,
-  const Thread_queue_Operations *new_operations
-)
-{
-  the_thread->Wait.operations = new_operations;
-}
-
-/**
- * @brief Restores the default thread queue operations.
- *
- * The caller must be the owner of the thread lock.
- *
- * @param[in] the_thread The thread.
- *
- * @see _Thread_Wait_set_operations().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_restore_default_operations(
-  Thread_Control *the_thread
-)
-{
-  the_thread->Wait.operations = &_Thread_queue_Operations_default;
-}
-
-/**
  * @brief Returns the object identifier of the object containing the current
  * thread wait queue.
@@ -1542,4 +1635,5 @@
 )
 {
+  _Thread_Wait_tranquilize( the_thread );
   _Thread_Timer_remove( the_thread );
 
Index: cpukit/score/include/rtems/score/threadq.h
===================================================================
--- cpukit/score/include/rtems/score/threadq.h	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/score/include/rtems/score/threadq.h	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -44,4 +44,8 @@
 typedef struct _Thread_Control Thread_Control;
 
+typedef struct Thread_queue_Queue Thread_queue_Queue;
+
+typedef struct Thread_queue_Operations Thread_queue_Operations;
+
 typedef struct Thread_queue_Path Thread_queue_Path;
 
@@ -54,4 +58,6 @@
  *   _Objects_Is_local_id( the_proxy->Object.id ) is false.
  * @param mp_id Object identifier of the object containing the thread queue.
+ *
+ * @see _Thread_queue_Context_set_MP_callout().
  */
 typedef void ( *Thread_queue_MP_callout )(
@@ -61,4 +67,22 @@
 #endif
 
+#if defined(RTEMS_SMP)
+/**
+ * @brief The thread queue gate is an SMP synchronization means.
+ *
+ * The gates are added to a list of requests.  A busy wait is performed to make
+ * sure that preceding requests are carried out.  Each predecessor notifies its
+ * successor about on request completion.
+ *
+ * @see _Thread_queue_Gate_add(), _Thread_queue_Gate_wait(), and
+ *   _Thread_queue_Gate_open().
+ */
+typedef struct {
+  Chain_Node Node;
+
+  Atomic_Uint go_ahead;
+} Thread_queue_Gate;
+#endif
+
 /**
  * @brief Thread queue context for the thread queue methods.
@@ -106,5 +130,61 @@
   Thread_queue_MP_callout mp_callout;
 #endif
+
+#if defined(RTEMS_SMP)
+  /**
+   * @brief Data to support thread queue enqueue operations.
+   */
+  struct {
+    /**
+     * @brief Gate to synchronize thread wait lock requests.
+     *
+     * @see _Thread_Wait_acquire_critical() and _Thread_Wait_tranquilize().
+     */
+    Thread_queue_Gate Gate;
+
+    /**
+     * @brief The thread queue lock in case the thread is blocked on a thread
+     * queue at thread wait lock acquire time.
+     */
+    SMP_ticket_lock_Control *queue_lock;
+
+    /**
+     * @brief The thread queue after thread wait lock acquire.
+     *
+     * In case the thread queue is NULL and the thread queue lock is non-NULL
+     * in this context, then we have a stale thread queue.  This happens in
+     * case the thread wait default is restored while we wait on the thread
+     * queue lock, e.g. during a mutex ownership transfer.
+     *
+     * @see _Thread_Wait_restore_default().
+     */
+    Thread_queue_Queue *queue;
+
+    /**
+     * @brief The thread queue operations after thread wait lock acquire.
+     */
+    const Thread_queue_Operations *operations;
+  } Wait;
+#endif
 } Thread_queue_Context;
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief A thread queue link from one thread to another specified by the
+ * thread queue owner and thread wait queue relationships.
+ */
+typedef struct {
+  /**
+   * @brief The owner of this thread queue link.
+   */
+  Thread_Control *owner;
+
+  /**
+   * @brief The queue context used to acquire the thread wait lock of the
+   * owner.
+   */
+  Thread_queue_Context Queue_context;
+} Thread_queue_Link;
+#endif
 
 /**
@@ -192,5 +272,5 @@
 #endif
 
-typedef struct {
+struct Thread_queue_Queue {
   /**
    * @brief Lock to protect this thread queue.
@@ -222,5 +302,5 @@
    */
   Thread_Control *owner;
-} Thread_queue_Queue;
+};
 
 /**
@@ -229,4 +309,6 @@
  * @param[in] the_thread The thread.
  * @param[in] new_priority The new priority value.
+ * @param[in] prepend_it In case this is true, then the thread is prepended to
+ *   its priority group in its scheduler instance, otherwise it is appended.
  * @param[in] queue The actual thread queue.
  *
@@ -236,4 +318,5 @@
   Thread_Control     *the_thread,
   Priority_Control    new_priority,
+  bool                prepend_it,
   Thread_queue_Queue *queue
 );
@@ -248,6 +331,4 @@
  * @param[in] queue The actual thread queue.
  * @param[in] the_thread The thread to enqueue on the queue.
- *
- * @see _Thread_Wait_set_operations().
  */
 typedef void ( *Thread_queue_Enqueue_operation )(
@@ -262,6 +343,4 @@
  * @param[in] queue The actual thread queue.
  * @param[in] the_thread The thread to extract from the thread queue.
- *
- * @see _Thread_Wait_set_operations().
  */
 typedef void ( *Thread_queue_Extract_operation )(
@@ -278,6 +357,4 @@
  * @retval first The first thread of the thread queue according to the insert
  * order.  This thread remains on the thread queue.
- *
- * @see _Thread_Wait_set_operations().
  */
 typedef Thread_Control *( *Thread_queue_First_operation )(
@@ -290,5 +367,5 @@
  * @see _Thread_wait_Set_operations().
  */
-typedef struct {
+struct Thread_queue_Operations {
   /**
    * @brief Thread queue priority change operation.
@@ -321,5 +398,5 @@
    */
   Thread_queue_First_operation first;
-} Thread_queue_Operations;
+};
 
 /**
Index: cpukit/score/include/rtems/score/threadqimpl.h
===================================================================
--- cpukit/score/include/rtems/score/threadqimpl.h	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/score/include/rtems/score/threadqimpl.h	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -27,4 +27,8 @@
 #include <rtems/score/thread.h>
 
+#if defined(RTEMS_DEBUG)
+#include <string.h>
+#endif
+
 #ifdef __cplusplus
 extern "C" {
@@ -47,4 +51,11 @@
  */
 struct Thread_queue_Path {
+#if defined(RTEMS_SMP)
+  /**
+   * @brief The start of a thread queue path.
+   */
+  Thread_queue_Link Start;
+#endif
+
   /**
    * @brief A potential thread to update the priority via
@@ -85,8 +96,6 @@
 {
 #if defined(RTEMS_DEBUG)
+  memset( queue_context, 0, sizeof( *queue_context ) );
   queue_context->expected_thread_dispatch_disable_level = 0xdeadbeef;
-#if defined(RTEMS_MULTIPROCESSING)
-  queue_context->mp_callout = NULL;
-#endif
 #else
   (void) queue_context;
@@ -186,4 +195,133 @@
     (void) queue_context; \
   } while ( 0 )
+#endif
+
+/**
+ * @brief Gets the thread wait queue of the thread queue context.
+ *
+ * On SMP configurations, the value is stored in the thread queue context,
+ * otherwise in the thread itself.
+ *
+ * @param queue_context The thread queue context.
+ * @param the_thread The thread.
+ */
+#if defined(RTEMS_SMP)
+#define _Thread_queue_Context_get_queue( queue_context, the_thread ) \
+  ( queue_context )->Wait.queue
+#else
+#define _Thread_queue_Context_get_queue( queue_context, the_thread ) \
+  ( the_thread )->Wait.queue
+#endif
+
+/**
+ * @brief Gets the thread wait operations of the thread queue context.
+ *
+ * On SMP configurations, the value is stored in the thread queue context,
+ * otherwise in the thread itself.
+ *
+ * @param queue_context The thread queue context.
+ * @param the_thread The thread.
+ */
+#if defined(RTEMS_SMP)
+#define _Thread_queue_Context_get_operations( queue_context, the_thread ) \
+  ( queue_context )->Wait.operations
+#else
+#define _Thread_queue_Context_get_operations( queue_context, the_thread ) \
+  ( the_thread )->Wait.operations
+#endif
+
+/**
+ * @brief Thread priority change by means of the thread queue context.
+ *
+ * On SMP configurations, the used data is stored in the thread queue context,
+ * otherwise in the thread itself.
+ *
+ * @param queue_context The thread queue context.
+ * @param the_thread The thread.
+ * @param new_priority The new thread priority.
+ * @param prepend_it Prepend it to its priority group or not.
+ */
+#if defined(RTEMS_SMP)
+#define _Thread_queue_Context_priority_change( \
+    queue_context, \
+    the_thread, \
+    new_priority, \
+    prepend_it \
+  ) \
+    ( *( queue_context )->Wait.operations->priority_change )( \
+      the_thread, \
+      new_priority, \
+      prepend_it, \
+      ( queue_context )->Wait.queue \
+    )
+#else
+#define _Thread_queue_Context_priority_change( \
+    queue_context, \
+    the_thread, \
+    new_priority, \
+    prepend_it \
+  ) \
+    ( *( the_thread )->Wait.operations->priority_change )( \
+      the_thread, \
+      new_priority, \
+      prepend_it, \
+      ( the_thread )->Wait.queue \
+    )
+#endif
+
+/**
+ * @brief Thread queue extract by means of the thread queue context.
+ *
+ * On SMP configurations, the used data is stored in the thread queue context,
+ * otherwise in the thread itself.
+ *
+ * @param queue_context The thread queue context.
+ * @param the_thread The thread.
+ */
+#if defined(RTEMS_SMP)
+#define _Thread_queue_Context_extract( \
+    queue_context, \
+    the_thread \
+  ) \
+    ( *( queue_context )->Wait.operations->extract )( \
+      ( queue_context )->Wait.queue, \
+      the_thread \
+    )
+#else
+#define _Thread_queue_Context_extract( \
+    queue_context, \
+    the_thread \
+  ) \
+    ( *( the_thread )->Wait.operations->extract )( \
+      ( the_thread )->Wait.queue, \
+      the_thread \
+    )
+#endif
+
+#if defined(RTEMS_SMP)
+RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_add(
+  Chain_Control     *chain,
+  Thread_queue_Gate *gate
+)
+{
+  _Atomic_Store_uint( &gate->go_ahead, 0, ATOMIC_ORDER_RELAXED );
+  _Chain_Append_unprotected( chain, &gate->Node );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_open(
+  Thread_queue_Gate *gate
+)
+{
+  _Atomic_Store_uint( &gate->go_ahead, 1, ATOMIC_ORDER_RELAXED );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_wait(
+  Thread_queue_Gate *gate
+)
+{
+  while ( _Atomic_Load_uint( &gate->go_ahead, ATOMIC_ORDER_RELAXED ) == 0 ) {
+    /* Wait */
+  }
+}
 #endif
 
@@ -912,4 +1050,8 @@
 extern const Thread_queue_Operations _Thread_queue_Operations_priority_inherit;
 
+#if defined(RTEMS_SMP)
+extern const Thread_queue_Operations _Thread_queue_Operations_stale_queue;
+#endif
+
 /**@}*/
 
Index: cpukit/score/src/threadchangepriority.c
===================================================================
--- cpukit/score/src/threadchangepriority.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/score/src/threadchangepriority.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -28,5 +28,6 @@
   void                          *arg,
   Thread_Change_priority_filter  filter,
-  bool                           prepend_it
+  bool                           prepend_it,
+  Thread_queue_Context          *queue_context
 )
 {
@@ -46,15 +47,9 @@
    */
   if ( ( *filter )( the_thread, &new_priority, arg ) ) {
-    Scheduler_Node *own_node;
-
-    own_node = _Scheduler_Thread_get_own_node( the_thread );
-    _Scheduler_Node_set_priority( own_node, new_priority, prepend_it );
-
-    the_thread->current_priority = new_priority;
-
-    ( *the_thread->Wait.operations->priority_change )(
+    _Thread_queue_Context_priority_change(
+      queue_context,
       the_thread,
       new_priority,
-      the_thread->Wait.queue
+      prepend_it
     );
   } else {
@@ -73,17 +68,18 @@
 )
 {
-  ISR_lock_Context  lock_context;
-  ISR_lock_Control *lock;
+  Thread_queue_Context  queue_context;
+  Thread_Control       *the_thread_to_update;
 
-  lock = _Thread_Lock_acquire( the_thread, &lock_context );
-  the_thread = _Thread_Apply_priority_locked(
+  _Thread_Wait_acquire( the_thread, &queue_context );
+  the_thread_to_update = _Thread_Apply_priority_locked(
     the_thread,
     new_priority,
     arg,
     filter,
-    prepend_it
+    prepend_it,
+    &queue_context
   );
-  _Thread_Lock_release( lock, &lock_context );
-  return the_thread;
+  _Thread_Wait_release( the_thread, &queue_context );
+  return the_thread_to_update;
 }
 
Index: cpukit/score/src/threadinitialize.c
===================================================================
--- cpukit/score/src/threadinitialize.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/score/src/threadinitialize.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -183,11 +183,9 @@
   the_thread->Scheduler.own_node = scheduler_node;
   _Resource_Node_initialize( &the_thread->Resource_node );
-  _Atomic_Store_uintptr(
-    &the_thread->Lock.current.atomic,
-    (uintptr_t) &the_thread->Lock.Default,
-    ATOMIC_ORDER_RELAXED
-  );
-  _SMP_ticket_lock_Initialize( &the_thread->Lock.Default );
-  _SMP_lock_Stats_initialize( &the_thread->Lock.Stats, "Thread Lock" );
+  _ISR_lock_Initialize(
+    &the_thread->Wait.Lock.Default,
+    "Thread Wait Default Lock"
+  );
+  _Chain_Initialize_empty( &the_thread->Wait.Lock.Pending_requests );
   _SMP_lock_Stats_initialize( &the_thread->Potpourri_stats, "Thread Potpourri" );
 #endif
Index: cpukit/score/src/threadqenqueue.c
===================================================================
--- cpukit/score/src/threadqenqueue.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/score/src/threadqenqueue.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -35,4 +35,49 @@
   (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_READY_AGAIN)
 
+static void _Thread_queue_Path_release( Thread_queue_Path *path )
+{
+#if defined(RTEMS_SMP)
+  Thread_queue_Link *link;
+
+  link = &path->Start;
+
+  if ( link->owner != NULL ) {
+    _Thread_Wait_release_critical( link->owner, &link->Queue_context );
+  }
+#else
+  (void) path;
+#endif
+}
+
+static void _Thread_queue_Path_acquire(
+  Thread_Control     *the_thread,
+  Thread_queue_Queue *queue,
+  Thread_queue_Path  *path
+)
+{
+#if defined(RTEMS_SMP)
+  Thread_Control     *owner;
+  Thread_queue_Link  *link;
+
+  owner = queue->owner;
+
+  if ( owner == NULL ) {
+    return;
+  }
+
+  link = &path->Start;
+  link->owner = owner;
+
+  _Thread_Wait_acquire_default_critical(
+    owner,
+    &link->Queue_context.Lock_context
+  );
+#else
+  (void) the_thread;
+  (void) queue;
+  (void) path;
+#endif
+}
+
 void _Thread_queue_Enqueue_critical(
   Thread_queue_Queue            *queue,
@@ -53,12 +98,11 @@
 #endif
 
-  _Thread_Lock_set( the_thread, &queue->Lock );
+  _Thread_Wait_claim( the_thread, queue, operations );
+
+  _Thread_queue_Path_acquire( the_thread, queue, &path );
+  ( *operations->enqueue )( queue, the_thread, &path );
+  _Thread_queue_Path_release( &path );
 
   the_thread->Wait.return_code = STATUS_SUCCESSFUL;
-  _Thread_Wait_set_queue( the_thread, queue );
-  _Thread_Wait_set_operations( the_thread, operations );
-
-  ( *operations->enqueue )( queue, the_thread, &path );
-
   _Thread_Wait_flags_set( the_thread, THREAD_QUEUE_INTEND_TO_BLOCK );
   cpu_self = _Thread_Dispatch_disable_critical( &queue_context->Lock_context );
@@ -174,7 +218,5 @@
   }
 
-  _Thread_Wait_set_queue( the_thread, NULL );
-  _Thread_Wait_restore_default_operations( the_thread );
-  _Thread_Lock_restore_default( the_thread );
+  _Thread_Wait_restore_default( the_thread );
 
   return unblock;
@@ -228,28 +270,33 @@
 void _Thread_queue_Extract( Thread_Control *the_thread )
 {
-  Thread_queue_Context  queue_context;
-  void                 *lock;
-  Thread_queue_Queue   *queue;
+  Thread_queue_Context queue_context;
 
   _Thread_queue_Context_initialize( &queue_context );
-  lock = _Thread_Lock_acquire( the_thread, &queue_context.Lock_context );
-
-  queue = the_thread->Wait.queue;
-
-  if ( queue != NULL ) {
-    _SMP_Assert( lock == &queue->Lock );
-
+  _Thread_Wait_acquire( the_thread, &queue_context );
+
+  if (
+    _Thread_queue_Context_get_queue( &queue_context, the_thread ) != NULL
+  ) {
+    bool unblock;
+
+    _Thread_Wait_remove_request( the_thread, &queue_context );
     _Thread_queue_Context_set_MP_callout(
       &queue_context,
       _Thread_queue_MP_callout_do_nothing
     );
-    _Thread_queue_Extract_critical(
-      queue,
-      the_thread->Wait.operations,
+    unblock = _Thread_queue_Extract_locked(
+      _Thread_queue_Context_get_queue( &queue_context, the_thread ),
+      _Thread_queue_Context_get_operations( &queue_context, the_thread ),
       the_thread,
-      &queue_context
+      &queue_context.Lock_context
+    );
+    _Thread_queue_Unblock_critical(
+      unblock,
+      _Thread_queue_Context_get_queue( &queue_context, the_thread ),
+      the_thread,
+      &queue_context.Lock_context
     );
   } else {
-    _Thread_Lock_release( lock, &queue_context.Lock_context );
+    _Thread_Wait_release( the_thread, &queue_context );
   }
 }
@@ -274,6 +321,4 @@
 
   if ( the_thread != NULL ) {
-    _SMP_Assert( the_thread->Lock.current.normal == &the_thread_queue->Queue.Lock );
-
     _Thread_queue_Extract_critical(
       &the_thread_queue->Queue,
Index: cpukit/score/src/threadqops.c
===================================================================
--- cpukit/score/src/threadqops.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/score/src/threadqops.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -23,20 +23,48 @@
 #include <rtems/score/schedulerimpl.h>
 
-static void _Thread_queue_Do_nothing_priority_change(
+static void _Thread_queue_Default_priority_change(
   Thread_Control     *the_thread,
   Priority_Control    new_priority,
+  bool                prepend_it,
   Thread_queue_Queue *queue
 )
 {
+  (void) queue;
+
+  _Scheduler_Thread_set_priority( the_thread, new_priority, prepend_it );
+}
+
+static void _Thread_queue_Do_nothing_extract(
+  Thread_queue_Queue *queue,
+  Thread_Control    *the_thread
+)
+{
   /* Do nothing */
 }
 
-static void _Thread_queue_Do_nothing_extract(
-  Thread_queue_Queue *queue,
-  Thread_Control    *the_thread
-)
-{
-  /* Do nothing */
-}
+#if defined(RTEMS_SMP)
+static void _Thread_queue_Stale_queue_priority_change(
+  Thread_Control     *the_thread,
+  Priority_Control    new_priority,
+  bool                prepend_it,
+  Thread_queue_Queue *queue
+)
+{
+  ISR_lock_Context lock_context;
+
+  (void) queue;
+
+  /*
+   * This operation is used to change the priority in case we have a thread
+   * queue context with a stale thread queue.  We own the thread queue lock of
+   * the former thread queue.  In addition, we need the thread wait default
+   * lock, see _Thread_Wait_restore_default().
+   */
+
+  _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
+  _Scheduler_Thread_set_priority( the_thread, new_priority, prepend_it );
+  _Thread_Wait_release_default_critical( the_thread, &lock_context );
+}
+#endif
 
 static Thread_queue_Heads *_Thread_queue_Queue_enqueue(
@@ -191,4 +219,5 @@
   Thread_Control     *the_thread,
   Priority_Control    new_priority,
+  bool                prepend_it,
   Thread_queue_Queue *queue
 )
@@ -198,4 +227,6 @@
 
   _Assert( heads != NULL );
+
+  _Scheduler_Thread_set_priority( the_thread, new_priority, prepend_it );
 
   priority_queue = _Thread_queue_Priority_queue( heads, the_thread );
@@ -354,6 +385,4 @@
 
   if ( priority < owner->current_priority ) {
-    Scheduler_Node *own_node;
-
     path->update_priority = owner;
 
@@ -361,13 +390,9 @@
     _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
 
-    own_node = _Scheduler_Thread_get_own_node( owner );
-    _Scheduler_Node_set_priority( own_node, priority, false );
-
-    owner->current_priority = priority;
-
-    ( *owner->Wait.operations->priority_change )(
+    _Thread_queue_Context_priority_change(
+      &path->Start.Queue_context,
       owner,
       priority,
-      owner->Wait.queue
+      false
     );
   } else {
@@ -386,5 +411,4 @@
   if ( !_Chain_Has_only_one_node( &heads->Heads.Fifo ) ) {
     const Scheduler_Control *scheduler;
-    Scheduler_Node          *own_node;
     Priority_Control         boost_priority;
 
@@ -393,9 +417,7 @@
 
     scheduler = _Scheduler_Get_own( the_thread );
-    own_node = _Scheduler_Thread_get_own_node( the_thread );
     boost_priority = _Scheduler_Map_priority( scheduler, PRIORITY_PSEUDO_ISR );
-    _Scheduler_Node_set_priority( own_node, boost_priority, false );
-
-    the_thread->current_priority = boost_priority;
+
+    _Scheduler_Thread_set_priority( the_thread, boost_priority, false );
   }
 }
@@ -403,5 +425,5 @@
 
 const Thread_queue_Operations _Thread_queue_Operations_default = {
-  .priority_change = _Thread_queue_Do_nothing_priority_change,
+  .priority_change = _Thread_queue_Default_priority_change,
   .extract = _Thread_queue_Do_nothing_extract
   /*
@@ -413,5 +435,5 @@
 
 const Thread_queue_Operations _Thread_queue_Operations_FIFO = {
-  .priority_change = _Thread_queue_Do_nothing_priority_change,
+  .priority_change = _Thread_queue_Default_priority_change,
   .enqueue = _Thread_queue_FIFO_enqueue,
   .extract = _Thread_queue_FIFO_extract,
@@ -432,2 +454,9 @@
   .first = _Thread_queue_Priority_first
 };
+
+#if defined(RTEMS_SMP)
+const Thread_queue_Operations _Thread_queue_Operations_stale_queue = {
+  .priority_change = _Thread_queue_Stale_queue_priority_change,
+  .extract = _Thread_queue_Do_nothing_extract
+};
+#endif
Index: cpukit/score/src/threadrestart.c
===================================================================
--- cpukit/score/src/threadrestart.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/score/src/threadrestart.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -216,6 +216,5 @@
 
 #if defined(RTEMS_SMP)
-  _SMP_ticket_lock_Destroy( &the_thread->Lock.Default );
-  _SMP_lock_Stats_destroy( &the_thread->Lock.Stats );
+  _ISR_lock_Destroy( &the_thread->Wait.Lock.Default );
   _SMP_lock_Stats_destroy( &the_thread->Potpourri_stats );
 #endif
Index: cpukit/score/src/threadtimeout.c
===================================================================
--- cpukit/score/src/threadtimeout.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ cpukit/score/src/threadtimeout.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -23,26 +23,13 @@
 #include <rtems/score/status.h>
 
-static void _Thread_Do_timeout( Thread_Control *the_thread )
-{
-  the_thread->Wait.return_code = STATUS_TIMEOUT;
-  ( *the_thread->Wait.operations->extract )(
-    the_thread->Wait.queue,
-    the_thread
-  );
-  _Thread_Wait_set_queue( the_thread, NULL );
-  _Thread_Wait_restore_default_operations( the_thread );
-  _Thread_Lock_restore_default( the_thread );
-}
-
 void _Thread_Timeout( Watchdog_Control *watchdog )
 {
-  Thread_Control    *the_thread;
-  void              *thread_lock;
-  ISR_lock_Context   lock_context;
-  Thread_Wait_flags  wait_flags;
-  bool               unblock;
+  Thread_Control       *the_thread;
+  Thread_queue_Context  queue_context;
+  Thread_Wait_flags     wait_flags;
+  bool                  unblock;
 
   the_thread = RTEMS_CONTAINER_OF( watchdog, Thread_Control, Timer.Watchdog );
-  thread_lock = _Thread_Lock_acquire( the_thread, &lock_context );
+  _Thread_Wait_acquire( the_thread, &queue_context );
 
   wait_flags = _Thread_Wait_flags_get( the_thread );
@@ -53,5 +40,7 @@
     bool              success;
 
-    _Thread_Do_timeout( the_thread );
+    _Thread_Wait_cancel( the_thread, &queue_context );
+
+    the_thread->Wait.return_code = STATUS_TIMEOUT;
 
     wait_class = wait_flags & THREAD_WAIT_CLASS_MASK;
@@ -77,7 +66,8 @@
   }
 
-  _Thread_Lock_release( thread_lock, &lock_context );
+  _Thread_Wait_release( the_thread, &queue_context );
 
   if ( unblock ) {
+    _Thread_Wait_tranquilize( the_thread );
     _Thread_Unblock( the_thread );
 
Index: testsuites/sptests/spthreadq01/init.c
===================================================================
--- testsuites/sptests/spthreadq01/init.c	(revision 3a58dc863157bb21054a144c1a21b690544c0d23)
+++ testsuites/sptests/spthreadq01/init.c	(revision 1fcac5adc5ed38fb88ce4c6d24b2ca2e27e3cd10)
@@ -69,11 +69,10 @@
 static rtems_id get_wait_id(test_context *ctx)
 {
-  ISR_lock_Context lock_context;
-  void *lock;
+  Thread_queue_Context queue_context;
   rtems_id id;
 
-  lock = _Thread_Lock_acquire(ctx->master, &lock_context);
+  _Thread_Wait_acquire(ctx->master, &queue_context);
   id = _Thread_Wait_get_id(ctx->master);
-  _Thread_Lock_release(lock, &lock_context);
+  _Thread_Wait_release(ctx->master, &queue_context);
 
   return id;
