[PATCH 5/8] score: Move thread wait node to scheduler node

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Sep 6 12:40:25 UTC 2016


Update #2556.
---
 cpukit/posix/src/killinfo.c                      |   5 +-
 cpukit/score/include/rtems/score/schedulerimpl.h |  17 +-
 cpukit/score/include/rtems/score/schedulernode.h |  40 ++++-
 cpukit/score/include/rtems/score/thread.h        | 217 +++++++++++------------
 cpukit/score/include/rtems/score/threadimpl.h    |   6 -
 cpukit/score/src/thread.c                        |   1 +
 cpukit/score/src/threadmp.c                      |  11 ++
 cpukit/score/src/threadqflush.c                  |  10 +-
 cpukit/score/src/threadqops.c                    |  69 +++++--
 9 files changed, 226 insertions(+), 150 deletions(-)

diff --git a/cpukit/posix/src/killinfo.c b/cpukit/posix/src/killinfo.c
index b7f0354..2e7bacb 100644
--- a/cpukit/posix/src/killinfo.c
+++ b/cpukit/posix/src/killinfo.c
@@ -27,6 +27,7 @@
 #include <rtems/posix/pthreadimpl.h>
 #include <rtems/posix/psignalimpl.h>
 #include <rtems/score/isr.h>
+#include <rtems/score/schedulerimpl.h>
 #include <rtems/score/statesimpl.h>
 #include <rtems/seterr.h>
 
@@ -150,8 +151,10 @@ int _POSIX_signals_Send(
     for ( the_node = _Chain_First( the_chain );
           !_Chain_Is_tail( the_chain, the_node ) ;
           the_node = the_node->next ) {
+      Scheduler_Node *scheduler_node;
 
-      the_thread = THREAD_CHAIN_NODE_TO_THREAD( the_node );
+      scheduler_node = SCHEDULER_NODE_OF_WAIT_CHAIN_NODE( the_node );
+      the_thread = _Scheduler_Node_get_owner( scheduler_node );
       api = the_thread->API_Extensions[ THREAD_API_POSIX ];
 
       #if defined(DEBUG_SIGNAL_PROCESSING)
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 1c5a697..0832360 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -785,13 +785,14 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize(
   Priority_Control  priority
 )
 {
+  node->owner = the_thread;
+
   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 );
@@ -800,6 +801,13 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize(
 #endif
 }
 
+RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_owner(
+  const Scheduler_Node *node
+)
+{
+  return node->owner;
+}
+
 RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Node_get_priority(
   Scheduler_Node *node,
   bool           *prepend_it_p
@@ -885,13 +893,6 @@ typedef void ( *Scheduler_Release_idle_thread )(
   Thread_Control    *idle
 );
 
-RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_owner(
-  const Scheduler_Node *node
-)
-{
-  return node->owner;
-}
-
 RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_idle(
   const Scheduler_Node *node
 )
diff --git a/cpukit/score/include/rtems/score/schedulernode.h b/cpukit/score/include/rtems/score/schedulernode.h
index 6153624..63d86e6 100644
--- a/cpukit/score/include/rtems/score/schedulernode.h
+++ b/cpukit/score/include/rtems/score/schedulernode.h
@@ -123,11 +123,6 @@ typedef struct {
   Scheduler_Help_state help_state;
 
   /**
-   * @brief The thread owning this node.
-   */
-  struct _Thread_Control *owner;
-
-  /**
    * @brief The idle thread claimed by this node in case the help state is
    * SCHEDULER_HELP_ACTIVE_OWNER.
    *
@@ -146,6 +141,35 @@ typedef struct {
 #endif
 
   /**
+   * @brief Thread wait support block.
+   */
+  struct {
+    /**
+     * @brief Node for thread queues.
+     *
+     * Each scheduler node can be enqueued on a thread queue on behalf of the
+     * thread owning the scheduler node.  The scheduler node reflects the
+     * priority of the thread within the corresponding scheduler instance.
+     */
+    union {
+      /**
+       * @brief A node for chains.
+       */
+      Chain_Node Chain;
+
+      /**
+       * @brief A node for red-black trees.
+       */
+      RBTree_Node RBTree;
+    } Node;
+  } Wait;
+
+  /**
+   * @brief The thread owning this node.
+   */
+  struct _Thread_Control *owner;
+
+  /**
    * @brief The thread priority information used by the scheduler.
    *
    * The thread priority is manifest in two independent areas.  One area is the
@@ -181,6 +205,12 @@ typedef struct {
   } Priority;
 } Scheduler_Node;
 
+#define SCHEDULER_NODE_OF_WAIT_CHAIN_NODE( node ) \
+  RTEMS_CONTAINER_OF( node, Scheduler_Node, Wait.Node.Chain )
+
+#define SCHEDULER_NODE_OF_WAIT_RBTREE_NODE( node ) \
+  RTEMS_CONTAINER_OF( node, Scheduler_Node, Wait.Node.RBTree )
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 19b52cd..a5faad3 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -210,6 +210,96 @@ typedef struct {
   void                                *tls_area;
 } Thread_Start_information;
 
+#if defined(RTEMS_SMP)
+/**
+ * @brief The thread state with respect to the scheduler.
+ */
+typedef enum {
+  /**
+   * @brief This thread is blocked with respect to the scheduler.
+   *
+   * This thread uses no scheduler nodes.
+   */
+  THREAD_SCHEDULER_BLOCKED,
+
+  /**
+   * @brief This thread is scheduled with respect to the scheduler.
+   *
+   * This thread executes using one of its scheduler nodes.  This could be its
+   * own scheduler node or in case it owns resources taking part in the
+   * scheduler helping protocol a scheduler node of another thread.
+   */
+  THREAD_SCHEDULER_SCHEDULED,
+
+  /**
+   * @brief This thread is ready with respect to the scheduler.
+   *
+   * None of the scheduler nodes of this thread is scheduled.
+   */
+  THREAD_SCHEDULER_READY
+} Thread_Scheduler_state;
+#endif
+
+/**
+ * @brief Thread scheduler control.
+ */
+typedef struct {
+#if defined(RTEMS_SMP)
+  /**
+   * @brief The current scheduler state of this thread.
+   */
+  Thread_Scheduler_state state;
+
+  /**
+   * @brief The own scheduler control of this thread.
+   *
+   * This field is constant after initialization.
+   */
+  const struct Scheduler_Control *own_control;
+
+  /**
+   * @brief The scheduler control of this thread.
+   *
+   * The scheduler helping protocol may change this field.
+   */
+  const struct Scheduler_Control *control;
+
+  /**
+   * @brief The own scheduler node of this thread.
+   *
+   * This field is constant after initialization.  It is used by change
+   * priority and ask for help operations.
+   */
+  Scheduler_Node *own_node;
+#endif
+
+  /**
+   * @brief The scheduler node of this thread.
+   *
+   * On uni-processor configurations this field is constant after
+   * initialization.
+   *
+   * On SMP configurations the scheduler helping protocol may change this
+   * field.
+   */
+  Scheduler_Node *node;
+
+#if defined(RTEMS_SMP)
+  /**
+   * @brief The processor assigned by the current scheduler.
+   */
+  struct Per_CPU_Control *cpu;
+
+#if defined(RTEMS_DEBUG)
+  /**
+   * @brief The processor on which this thread executed the last time or is
+   * executing.
+   */
+  struct Per_CPU_Control *debug_real_cpu;
+#endif
+#endif
+} Thread_Scheduler_control;
+
 /**
  *  @brief Union type to hold a pointer to an immutable or a mutable object.
  *
@@ -248,21 +338,6 @@ typedef unsigned int Thread_Wait_flags;
  *  blocked and to return information to it.
  */
 typedef struct {
-  /**
-   * @brief Node for thread queues.
-   */
-  union {
-    /**
-     * @brief A node for chains.
-     */
-    Chain_Node Chain;
-
-    /**
-     * @brief A node for red-black trees.
-     */
-    RBTree_Node RBTree;
-  } Node;
-
 #if defined(RTEMS_MULTIPROCESSING)
   /*
    * @brief This field is the identifier of the remote object this thread is
@@ -424,6 +499,11 @@ typedef struct {
   /** This field is the number of mutexes currently held by this proxy. */
   uint32_t                 resource_count;
 
+  /**
+   * @brief Scheduler related control.
+   */
+  Thread_Scheduler_control Scheduler;
+
   /** This field is the blocking information for this proxy. */
   Thread_Wait_information  Wait;
   /** This field is the Watchdog used to manage proxy delays and timeouts. */
@@ -444,6 +524,12 @@ typedef struct {
   RBTree_Node              Active;
 
   /**
+   * @brief The scheduler node providing the thread wait nodes used to enqueue
+   * this thread proxy on a thread queue.
+   */
+  Scheduler_Node           Scheduler_node;
+
+  /**
    * @brief Provide thread queue heads for this thread proxy.
    *
    * The actual size of the thread queue heads depends on the application
@@ -592,96 +678,6 @@ typedef struct {
 #endif
 } Thread_Life_control;
 
-#if defined(RTEMS_SMP)
-/**
- * @brief The thread state with respect to the scheduler.
- */
-typedef enum {
-  /**
-   * @brief This thread is blocked with respect to the scheduler.
-   *
-   * This thread uses no scheduler nodes.
-   */
-  THREAD_SCHEDULER_BLOCKED,
-
-  /**
-   * @brief This thread is scheduled with respect to the scheduler.
-   *
-   * This thread executes using one of its scheduler nodes.  This could be its
-   * own scheduler node or in case it owns resources taking part in the
-   * scheduler helping protocol a scheduler node of another thread.
-   */
-  THREAD_SCHEDULER_SCHEDULED,
-
-  /**
-   * @brief This thread is ready with respect to the scheduler.
-   *
-   * None of the scheduler nodes of this thread is scheduled.
-   */
-  THREAD_SCHEDULER_READY
-} Thread_Scheduler_state;
-#endif
-
-/**
- * @brief Thread scheduler control.
- */
-typedef struct {
-#if defined(RTEMS_SMP)
-  /**
-   * @brief The current scheduler state of this thread.
-   */
-  Thread_Scheduler_state state;
-
-  /**
-   * @brief The own scheduler control of this thread.
-   *
-   * This field is constant after initialization.
-   */
-  const struct Scheduler_Control *own_control;
-
-  /**
-   * @brief The scheduler control of this thread.
-   *
-   * The scheduler helping protocol may change this field.
-   */
-  const struct Scheduler_Control *control;
-
-  /**
-   * @brief The own scheduler node of this thread.
-   *
-   * This field is constant after initialization.  It is used by change
-   * priority and ask for help operations.
-   */
-  Scheduler_Node *own_node;
-#endif
-
-  /**
-   * @brief The scheduler node of this thread.
-   *
-   * On uni-processor configurations this field is constant after
-   * initialization.
-   *
-   * On SMP configurations the scheduler helping protocol may change this
-   * field.
-   */
-  Scheduler_Node *node;
-
-#if defined(RTEMS_SMP)
-  /**
-   * @brief The processor assigned by the current scheduler.
-   */
-  struct Per_CPU_Control *cpu;
-
-#if defined(RTEMS_DEBUG)
-  /**
-   * @brief The processor on which this thread executed the last time or is
-   * executing.
-   */
-  struct Per_CPU_Control *debug_real_cpu;
-#endif
-#endif
-} Thread_Scheduler_control;
-
 typedef struct  {
   uint32_t      flags;
   void *        control;
@@ -748,6 +744,12 @@ struct _Thread_Control {
 
   /** This field is the number of mutexes currently held by this thread. */
   uint32_t                 resource_count;
+
+  /**
+   * @brief Scheduler related control.
+   */
+  Thread_Scheduler_control Scheduler;
+
   /** This field is the blocking information for this thread. */
   Thread_Wait_information  Wait;
   /** This field is the Watchdog used to manage thread delays and timeouts. */
@@ -786,11 +788,6 @@ struct _Thread_Control {
   /** This field is true if the thread uses the floating point unit. */
   bool                                  is_fp;
 
-  /**
-   * @brief Scheduler related control.
-   */
-  Thread_Scheduler_control              Scheduler;
-
 #if __RTEMS_ADA__
   /** This field is the GNAT self context pointer. */
   void                                 *rtems_ada_self;
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 1c043c3..2b45a2e 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -77,12 +77,6 @@ extern Thread_Information _Thread_Internal_information;
 extern Thread_Control *_Thread_Allocated_fp;
 #endif
 
-#define THREAD_CHAIN_NODE_TO_THREAD( node ) \
-  RTEMS_CONTAINER_OF( node, Thread_Control, Wait.Node.Chain )
-
-#define THREAD_RBTREE_NODE_TO_THREAD( node ) \
-  RTEMS_CONTAINER_OF( node, Thread_Control, Wait.Node.RBTree )
-
 #if defined(RTEMS_SMP)
 #define THREAD_RESOURCE_NODE_TO_THREAD( node ) \
   RTEMS_CONTAINER_OF( node, Thread_Control, Resource_node )
diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c
index 8028540..c569ae5 100644
--- a/cpukit/score/src/thread.c
+++ b/cpukit/score/src/thread.c
@@ -36,6 +36,7 @@ THREAD_OFFSET_ASSERT( current_priority );
 THREAD_OFFSET_ASSERT( real_priority );
 THREAD_OFFSET_ASSERT( priority_restore_hint );
 THREAD_OFFSET_ASSERT( resource_count );
+THREAD_OFFSET_ASSERT( Scheduler );
 THREAD_OFFSET_ASSERT( Wait );
 THREAD_OFFSET_ASSERT( Timer );
 #if defined(RTEMS_MULTIPROCESSING)
diff --git a/cpukit/score/src/threadmp.c b/cpukit/score/src/threadmp.c
index f525356..cbb6c1c 100644
--- a/cpukit/score/src/threadmp.c
+++ b/cpukit/score/src/threadmp.c
@@ -20,6 +20,7 @@
 
 #include <rtems/score/threadimpl.h>
 #include <rtems/score/isrlock.h>
+#include <rtems/score/schedulerimpl.h>
 #include <rtems/score/wkspace.h>
 
 #include <string.h>
@@ -74,6 +75,16 @@ void _Thread_MP_Handler_initialization (
     _Thread_Timer_initialize( &proxy->Timer, _Per_CPU_Get_by_index( 0 ) );
     _RBTree_Initialize_node( &proxy->Active );
 
+#if defined(RTEMS_SMP)
+    proxy->Scheduler.own_node = &proxy->Scheduler_node;
+#endif
+    proxy->Scheduler.node = &proxy->Scheduler_node;
+    _Scheduler_Node_do_initialize(
+      &proxy->Scheduler_node,
+      (Thread_Control *) proxy,
+      0
+    );
+
     proxy->Wait.spare_heads = &proxy->Thread_queue_heads[ 0 ];
     _Thread_queue_Heads_initialize( proxy->Wait.spare_heads );
   }
diff --git a/cpukit/score/src/threadqflush.c b/cpukit/score/src/threadqflush.c
index 835858d..fb13230 100644
--- a/cpukit/score/src/threadqflush.c
+++ b/cpukit/score/src/threadqflush.c
@@ -19,6 +19,7 @@
 #endif
 
 #include <rtems/score/threadimpl.h>
+#include <rtems/score/schedulerimpl.h>
 #include <rtems/score/status.h>
 
 Thread_Control *_Thread_queue_Flush_default_filter(
@@ -96,7 +97,10 @@ size_t _Thread_queue_Flush_critical(
       queue_context
     );
     if ( do_unblock ) {
-      _Chain_Append_unprotected( &unblock, &first->Wait.Node.Chain );
+      Scheduler_Node *scheduler_node;
+
+      scheduler_node = _Scheduler_Thread_get_own_node( first );
+      _Chain_Append_unprotected( &unblock, &scheduler_node->Wait.Node.Chain );
     }
 
     ++flushed;
@@ -114,11 +118,13 @@ size_t _Thread_queue_Flush_critical(
     _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context );
 
     do {
+      Scheduler_Node *scheduler_node;
       Thread_Control *the_thread;
       Chain_Node     *next;
 
       next = _Chain_Next( node );
-      the_thread = THREAD_CHAIN_NODE_TO_THREAD( node );
+      scheduler_node = SCHEDULER_NODE_OF_WAIT_CHAIN_NODE( node );
+      the_thread = _Scheduler_Node_get_owner( scheduler_node );
       _Thread_Remove_timer_and_unblock( the_thread, queue );
 
       node = next;
diff --git a/cpukit/score/src/threadqops.c b/cpukit/score/src/threadqops.c
index 1545f29..b72421e 100644
--- a/cpukit/score/src/threadqops.c
+++ b/cpukit/score/src/threadqops.c
@@ -99,7 +99,14 @@ static void _Thread_queue_FIFO_do_initialize(
   Thread_Control     *the_thread
 )
 {
-  _Chain_Initialize_one( &heads->Heads.Fifo, &the_thread->Wait.Node.Chain );
+  Scheduler_Node *scheduler_node;
+
+  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
+
+  _Chain_Initialize_one(
+    &heads->Heads.Fifo,
+    &scheduler_node->Wait.Node.Chain
+  );
 }
 
 static void _Thread_queue_FIFO_do_enqueue(
@@ -107,10 +114,14 @@ static void _Thread_queue_FIFO_do_enqueue(
   Thread_Control     *the_thread
 )
 {
-  _Chain_Initialize_node( &the_thread->Wait.Node.Chain );
+  Scheduler_Node *scheduler_node;
+
+  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
+
+  _Chain_Initialize_node( &scheduler_node->Wait.Node.Chain );
   _Chain_Append_unprotected(
     &heads->Heads.Fifo,
-    &the_thread->Wait.Node.Chain
+    &scheduler_node->Wait.Node.Chain
   );
 }
 
@@ -119,7 +130,10 @@ static void _Thread_queue_FIFO_do_extract(
   Thread_Control     *the_thread
 )
 {
-  _Chain_Extract_unprotected( &the_thread->Wait.Node.Chain );
+  Scheduler_Node *scheduler_node;
+
+  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
+  _Chain_Extract_unprotected( &scheduler_node->Wait.Node.Chain );
 }
 
 static void _Thread_queue_FIFO_enqueue(
@@ -155,13 +169,16 @@ static Thread_Control *_Thread_queue_FIFO_first(
   Thread_queue_Heads *heads
 )
 {
-  Chain_Control *fifo = &heads->Heads.Fifo;
-  Chain_Node    *first;
+  Chain_Control  *fifo;
+  Chain_Node     *first;
+  Scheduler_Node *scheduler_node;
 
+  fifo = &heads->Heads.Fifo;
   _Assert( !_Chain_Is_empty( fifo ) );
   first = _Chain_First( fifo );
+  scheduler_node = SCHEDULER_NODE_OF_WAIT_CHAIN_NODE( first );
 
-  return THREAD_CHAIN_NODE_TO_THREAD( first );
+  return _Scheduler_Node_get_owner( scheduler_node );
 }
 
 static Thread_Control *_Thread_queue_FIFO_surrender(
@@ -205,10 +222,12 @@ static bool _Thread_queue_Priority_less(
 )
 {
   const Priority_Control *the_left;
+  const Scheduler_Node   *scheduler_node;
   const Thread_Control   *the_right;
 
   the_left = left;
-  the_right = THREAD_RBTREE_NODE_TO_THREAD( right );
+  scheduler_node = SCHEDULER_NODE_OF_WAIT_RBTREE_NODE( right );
+  the_right = _Scheduler_Node_get_owner( scheduler_node );
 
   return *the_left < the_right->current_priority;
 }
@@ -219,20 +238,23 @@ static void _Thread_queue_Priority_priority_change(
   Priority_Control    new_priority
 )
 {
-  Thread_queue_Heads          *heads = queue->heads;
+  Thread_queue_Heads          *heads;
   Thread_queue_Priority_queue *priority_queue;
+  Scheduler_Node              *scheduler_node;
 
+  heads = queue->heads;
   _Assert( heads != NULL );
 
   priority_queue = _Thread_queue_Priority_queue( heads, the_thread );
+  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
 
   _RBTree_Extract(
     &priority_queue->Queue,
-    &the_thread->Wait.Node.RBTree
+    &scheduler_node->Wait.Node.RBTree
   );
   _RBTree_Insert_inline(
     &priority_queue->Queue,
-    &the_thread->Wait.Node.RBTree,
+    &scheduler_node->Wait.Node.RBTree,
     &new_priority,
     _Thread_queue_Priority_less
   );
@@ -244,6 +266,7 @@ static void _Thread_queue_Priority_do_initialize(
 )
 {
   Thread_queue_Priority_queue *priority_queue;
+  Scheduler_Node              *scheduler_node;
 
   priority_queue = _Thread_queue_Priority_queue( heads, the_thread );
 
@@ -251,9 +274,11 @@ static void _Thread_queue_Priority_do_initialize(
   _Chain_Initialize_one( &heads->Heads.Fifo, &priority_queue->Node );
 #endif
 
+  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
+
   _RBTree_Initialize_one(
     &priority_queue->Queue,
-    &the_thread->Wait.Node.RBTree
+    &scheduler_node->Wait.Node.RBTree
   );
 }
 
@@ -263,6 +288,7 @@ static void _Thread_queue_Priority_do_enqueue(
 )
 {
   Thread_queue_Priority_queue *priority_queue;
+  Scheduler_Node              *scheduler_node;
   Priority_Control             current_priority;
 
   priority_queue = _Thread_queue_Priority_queue( heads, the_thread );
@@ -273,11 +299,13 @@ static void _Thread_queue_Priority_do_enqueue(
   }
 #endif
 
+  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
   current_priority = the_thread->current_priority;
-  _RBTree_Initialize_node( &the_thread->Wait.Node.RBTree );
+
+  _RBTree_Initialize_node( &scheduler_node->Wait.Node.RBTree );
   _RBTree_Insert_inline(
     &priority_queue->Queue,
-    &the_thread->Wait.Node.RBTree,
+    &scheduler_node->Wait.Node.RBTree,
     &current_priority,
     _Thread_queue_Priority_less
   );
@@ -288,12 +316,15 @@ static void _Thread_queue_Priority_do_extract(
   Thread_Control     *the_thread
 )
 {
-  Thread_queue_Priority_queue *priority_queue =
-    _Thread_queue_Priority_queue( heads, the_thread );
+  Thread_queue_Priority_queue *priority_queue;
+  Scheduler_Node              *scheduler_node;
+
+  priority_queue = _Thread_queue_Priority_queue( heads, the_thread );
+  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
 
   _RBTree_Extract(
     &priority_queue->Queue,
-    &the_thread->Wait.Node.RBTree
+    &scheduler_node->Wait.Node.RBTree
   );
 
 #if defined(RTEMS_SMP)
@@ -340,6 +371,7 @@ static Thread_Control *_Thread_queue_Priority_first(
 {
   Thread_queue_Priority_queue *priority_queue;
   RBTree_Node                 *first;
+  Scheduler_Node              *scheduler_node;
 
 #if defined(RTEMS_SMP)
   _Assert( !_Chain_Is_empty( &heads->Heads.Fifo ) );
@@ -351,8 +383,9 @@ static Thread_Control *_Thread_queue_Priority_first(
 
   _Assert( !_RBTree_Is_empty( &priority_queue->Queue ) );
   first = _RBTree_Minimum( &priority_queue->Queue );
+  scheduler_node = SCHEDULER_NODE_OF_WAIT_RBTREE_NODE( first );
 
-  return THREAD_RBTREE_NODE_TO_THREAD( first );
+  return _Scheduler_Node_get_owner( scheduler_node );
 }
 
 static Thread_Control *_Thread_queue_Priority_surrender(
-- 
1.8.4.5




More information about the devel mailing list