Changeset 15b5678d in rtems


Ignore:
Timestamp:
Aug 1, 2016, 9:03:16 AM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
52a661e8
Parents:
e27421f
git-author:
Sebastian Huber <sebastian.huber@…> (08/01/16 09:03:16)
git-committer:
Sebastian Huber <sebastian.huber@…> (09/08/16 07:55:27)
Message:

score: Move thread wait node to scheduler node

Update #2556.

Location:
cpukit
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • cpukit/posix/src/killinfo.c

    re27421f r15b5678d  
    2828#include <rtems/posix/psignalimpl.h>
    2929#include <rtems/score/isr.h>
     30#include <rtems/score/schedulerimpl.h>
    3031#include <rtems/score/statesimpl.h>
    3132#include <rtems/seterr.h>
     
    151152          !_Chain_Is_tail( the_chain, the_node ) ;
    152153          the_node = the_node->next ) {
    153 
    154       the_thread = THREAD_CHAIN_NODE_TO_THREAD( the_node );
     154      Scheduler_Node *scheduler_node;
     155
     156      scheduler_node = SCHEDULER_NODE_OF_WAIT_CHAIN_NODE( the_node );
     157      the_thread = _Scheduler_Node_get_owner( scheduler_node );
    155158      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
    156159
  • cpukit/score/include/rtems/score/schedulerimpl.h

    re27421f r15b5678d  
    786786)
    787787{
     788  node->owner = the_thread;
     789
    788790  node->Priority.value = priority;
    789791  node->Priority.prepend_it = false;
     
    792794  node->user = the_thread;
    793795  node->help_state = SCHEDULER_HELP_YOURSELF;
    794   node->owner = the_thread;
    795796  node->idle = NULL;
    796797  node->accepts_help = the_thread;
     
    801802}
    802803
     804RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_owner(
     805  const Scheduler_Node *node
     806)
     807{
     808  return node->owner;
     809}
     810
    803811RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Node_get_priority(
    804812  Scheduler_Node *node,
     
    885893  Thread_Control    *idle
    886894);
    887 
    888 RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_owner(
    889   const Scheduler_Node *node
    890 )
    891 {
    892   return node->owner;
    893 }
    894895
    895896RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_idle(
  • cpukit/score/include/rtems/score/schedulernode.h

    re27421f r15b5678d  
    124124
    125125  /**
    126    * @brief The thread owning this node.
    127    */
    128   struct _Thread_Control *owner;
    129 
    130   /**
    131126   * @brief The idle thread claimed by this node in case the help state is
    132127   * SCHEDULER_HELP_ACTIVE_OWNER.
     
    145140  struct _Thread_Control *accepts_help;
    146141#endif
     142
     143  /**
     144   * @brief Thread wait support block.
     145   */
     146  struct {
     147    /**
     148     * @brief Node for thread queues.
     149     *
     150     * Each scheduler node can be enqueued on a thread queue on behalf of the
     151     * thread owning the scheduler node.  The scheduler node reflects the
     152     * priority of the thread within the corresponding scheduler instance.
     153     */
     154    union {
     155      /**
     156       * @brief A node for chains.
     157       */
     158      Chain_Node Chain;
     159
     160      /**
     161       * @brief A node for red-black trees.
     162       */
     163      RBTree_Node RBTree;
     164    } Node;
     165  } Wait;
     166
     167  /**
     168   * @brief The thread owning this node.
     169   */
     170  struct _Thread_Control *owner;
    147171
    148172  /**
     
    182206} Scheduler_Node;
    183207
     208#define SCHEDULER_NODE_OF_WAIT_CHAIN_NODE( node ) \
     209  RTEMS_CONTAINER_OF( node, Scheduler_Node, Wait.Node.Chain )
     210
     211#define SCHEDULER_NODE_OF_WAIT_RBTREE_NODE( node ) \
     212  RTEMS_CONTAINER_OF( node, Scheduler_Node, Wait.Node.RBTree )
     213
    184214#ifdef __cplusplus
    185215}
  • cpukit/score/include/rtems/score/thread.h

    re27421f r15b5678d  
    211211} Thread_Start_information;
    212212
     213#if defined(RTEMS_SMP)
     214/**
     215 * @brief The thread state with respect to the scheduler.
     216 */
     217typedef enum {
     218  /**
     219   * @brief This thread is blocked with respect to the scheduler.
     220   *
     221   * This thread uses no scheduler nodes.
     222   */
     223  THREAD_SCHEDULER_BLOCKED,
     224
     225  /**
     226   * @brief This thread is scheduled with respect to the scheduler.
     227   *
     228   * This thread executes using one of its scheduler nodes.  This could be its
     229   * own scheduler node or in case it owns resources taking part in the
     230   * scheduler helping protocol a scheduler node of another thread.
     231   */
     232  THREAD_SCHEDULER_SCHEDULED,
     233
     234  /**
     235   * @brief This thread is ready with respect to the scheduler.
     236   *
     237   * None of the scheduler nodes of this thread is scheduled.
     238   */
     239  THREAD_SCHEDULER_READY
     240} Thread_Scheduler_state;
     241#endif
     242
     243/**
     244 * @brief Thread scheduler control.
     245 */
     246typedef struct {
     247#if defined(RTEMS_SMP)
     248  /**
     249   * @brief The current scheduler state of this thread.
     250   */
     251  Thread_Scheduler_state state;
     252
     253  /**
     254   * @brief The own scheduler control of this thread.
     255   *
     256   * This field is constant after initialization.
     257   */
     258  const struct Scheduler_Control *own_control;
     259
     260  /**
     261   * @brief The scheduler control of this thread.
     262   *
     263   * The scheduler helping protocol may change this field.
     264   */
     265  const struct Scheduler_Control *control;
     266
     267  /**
     268   * @brief The own scheduler node of this thread.
     269   *
     270   * This field is constant after initialization.  It is used by change
     271   * priority and ask for help operations.
     272   */
     273  Scheduler_Node *own_node;
     274#endif
     275
     276  /**
     277   * @brief The scheduler node of this thread.
     278   *
     279   * On uni-processor configurations this field is constant after
     280   * initialization.
     281   *
     282   * On SMP configurations the scheduler helping protocol may change this
     283   * field.
     284   */
     285  Scheduler_Node *node;
     286
     287#if defined(RTEMS_SMP)
     288  /**
     289   * @brief The processor assigned by the current scheduler.
     290   */
     291  struct Per_CPU_Control *cpu;
     292#endif
     293} Thread_Scheduler_control;
     294
    213295/**
    214296 *  @brief Union type to hold a pointer to an immutable or a mutable object.
     
    249331 */
    250332typedef struct {
    251   /**
    252    * @brief Node for thread queues.
    253    */
    254   union {
    255     /**
    256      * @brief A node for chains.
    257      */
    258     Chain_Node Chain;
    259 
    260     /**
    261      * @brief A node for red-black trees.
    262      */
    263     RBTree_Node RBTree;
    264   } Node;
    265 
    266333#if defined(RTEMS_MULTIPROCESSING)
    267334  /*
     
    425492  uint32_t                 resource_count;
    426493
     494  /**
     495   * @brief Scheduler related control.
     496   */
     497  Thread_Scheduler_control Scheduler;
     498
    427499  /** This field is the blocking information for this proxy. */
    428500  Thread_Wait_information  Wait;
     
    445517
    446518  /**
     519   * @brief The scheduler node providing the thread wait nodes used to enqueue
     520   * this thread proxy on a thread queue.
     521   */
     522  Scheduler_Node           Scheduler_node;
     523
     524  /**
    447525   * @brief Provide thread queue heads for this thread proxy.
    448526   *
     
    592670#endif
    593671} Thread_Life_control;
    594 
    595 #if defined(RTEMS_SMP)
    596 /**
    597  * @brief The thread state with respect to the scheduler.
    598  */
    599 typedef enum {
    600   /**
    601    * @brief This thread is blocked with respect to the scheduler.
    602    *
    603    * This thread uses no scheduler nodes.
    604    */
    605   THREAD_SCHEDULER_BLOCKED,
    606 
    607   /**
    608    * @brief This thread is scheduled with respect to the scheduler.
    609    *
    610    * This thread executes using one of its scheduler nodes.  This could be its
    611    * own scheduler node or in case it owns resources taking part in the
    612    * scheduler helping protocol a scheduler node of another thread.
    613    */
    614   THREAD_SCHEDULER_SCHEDULED,
    615 
    616   /**
    617    * @brief This thread is ready with respect to the scheduler.
    618    *
    619    * None of the scheduler nodes of this thread is scheduled.
    620    */
    621   THREAD_SCHEDULER_READY
    622 } Thread_Scheduler_state;
    623 #endif
    624 
    625 /**
    626  * @brief Thread scheduler control.
    627  */
    628 typedef struct {
    629 #if defined(RTEMS_SMP)
    630   /**
    631    * @brief The current scheduler state of this thread.
    632    */
    633   Thread_Scheduler_state state;
    634 
    635   /**
    636    * @brief The own scheduler control of this thread.
    637    *
    638    * This field is constant after initialization.
    639    */
    640   const struct Scheduler_Control *own_control;
    641 
    642   /**
    643    * @brief The scheduler control of this thread.
    644    *
    645    * The scheduler helping protocol may change this field.
    646    */
    647   const struct Scheduler_Control *control;
    648 
    649   /**
    650    * @brief The own scheduler node of this thread.
    651    *
    652    * This field is constant after initialization.  It is used by change
    653    * priority and ask for help operations.
    654    */
    655   Scheduler_Node *own_node;
    656 #endif
    657 
    658   /**
    659    * @brief The scheduler node of this thread.
    660    *
    661    * On uni-processor configurations this field is constant after
    662    * initialization.
    663    *
    664    * On SMP configurations the scheduler helping protocol may change this
    665    * field.
    666    */
    667   Scheduler_Node *node;
    668 
    669 #if defined(RTEMS_SMP)
    670   /**
    671    * @brief The processor assigned by the current scheduler.
    672    */
    673   struct Per_CPU_Control *cpu;
    674 #endif
    675 } Thread_Scheduler_control;
    676672
    677673typedef struct  {
     
    741737  /** This field is the number of mutexes currently held by this thread. */
    742738  uint32_t                 resource_count;
     739
     740  /**
     741   * @brief Scheduler related control.
     742   */
     743  Thread_Scheduler_control Scheduler;
     744
    743745  /** This field is the blocking information for this thread. */
    744746  Thread_Wait_information  Wait;
     
    779781  bool                                  is_fp;
    780782
    781   /**
    782    * @brief Scheduler related control.
    783    */
    784   Thread_Scheduler_control              Scheduler;
    785 
    786783#if __RTEMS_ADA__
    787784  /** This field is the GNAT self context pointer. */
  • cpukit/score/include/rtems/score/threadimpl.h

    re27421f r15b5678d  
    7777extern Thread_Control *_Thread_Allocated_fp;
    7878#endif
    79 
    80 #define THREAD_CHAIN_NODE_TO_THREAD( node ) \
    81   RTEMS_CONTAINER_OF( node, Thread_Control, Wait.Node.Chain )
    82 
    83 #define THREAD_RBTREE_NODE_TO_THREAD( node ) \
    84   RTEMS_CONTAINER_OF( node, Thread_Control, Wait.Node.RBTree )
    8579
    8680#if defined(RTEMS_SMP)
  • cpukit/score/src/thread.c

    re27421f r15b5678d  
    3737THREAD_OFFSET_ASSERT( priority_restore_hint );
    3838THREAD_OFFSET_ASSERT( resource_count );
     39THREAD_OFFSET_ASSERT( Scheduler );
    3940THREAD_OFFSET_ASSERT( Wait );
    4041THREAD_OFFSET_ASSERT( Timer );
  • cpukit/score/src/threadmp.c

    re27421f r15b5678d  
    2121#include <rtems/score/threadimpl.h>
    2222#include <rtems/score/isrlock.h>
     23#include <rtems/score/schedulerimpl.h>
    2324#include <rtems/score/wkspace.h>
    2425
     
    7475    _Thread_Timer_initialize( &proxy->Timer, _Per_CPU_Get_by_index( 0 ) );
    7576    _RBTree_Initialize_node( &proxy->Active );
     77
     78#if defined(RTEMS_SMP)
     79    proxy->Scheduler.own_node = &proxy->Scheduler_node;
     80#endif
     81    proxy->Scheduler.node = &proxy->Scheduler_node;
     82    _Scheduler_Node_do_initialize(
     83      &proxy->Scheduler_node,
     84      (Thread_Control *) proxy,
     85      0
     86    );
    7687
    7788    proxy->Wait.spare_heads = &proxy->Thread_queue_heads[ 0 ];
  • cpukit/score/src/threadqflush.c

    re27421f r15b5678d  
    2020
    2121#include <rtems/score/threadimpl.h>
     22#include <rtems/score/schedulerimpl.h>
    2223#include <rtems/score/status.h>
    2324
     
    9798    );
    9899    if ( do_unblock ) {
    99       _Chain_Append_unprotected( &unblock, &first->Wait.Node.Chain );
     100      Scheduler_Node *scheduler_node;
     101
     102      scheduler_node = _Scheduler_Thread_get_own_node( first );
     103      _Chain_Append_unprotected( &unblock, &scheduler_node->Wait.Node.Chain );
    100104    }
    101105
     
    115119
    116120    do {
     121      Scheduler_Node *scheduler_node;
    117122      Thread_Control *the_thread;
    118123      Chain_Node     *next;
    119124
    120125      next = _Chain_Next( node );
    121       the_thread = THREAD_CHAIN_NODE_TO_THREAD( node );
     126      scheduler_node = SCHEDULER_NODE_OF_WAIT_CHAIN_NODE( node );
     127      the_thread = _Scheduler_Node_get_owner( scheduler_node );
    122128      _Thread_Remove_timer_and_unblock( the_thread, queue );
    123129
  • cpukit/score/src/threadqops.c

    re27421f r15b5678d  
    100100)
    101101{
    102   _Chain_Initialize_node( &the_thread->Wait.Node.Chain );
    103   _Chain_Initialize_one( &heads->Heads.Fifo, &the_thread->Wait.Node.Chain );
     102  Scheduler_Node *scheduler_node;
     103
     104  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
     105
     106  _Chain_Initialize_node( &scheduler_node->Wait.Node.Chain );
     107  _Chain_Initialize_one(
     108    &heads->Heads.Fifo,
     109    &scheduler_node->Wait.Node.Chain
     110  );
    104111}
    105112
     
    109116)
    110117{
    111   _Chain_Initialize_node( &the_thread->Wait.Node.Chain );
     118  Scheduler_Node *scheduler_node;
     119
     120  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
     121
     122  _Chain_Initialize_node( &scheduler_node->Wait.Node.Chain );
    112123  _Chain_Append_unprotected(
    113124    &heads->Heads.Fifo,
    114     &the_thread->Wait.Node.Chain
     125    &scheduler_node->Wait.Node.Chain
    115126  );
    116127}
     
    121132)
    122133{
    123   _Chain_Extract_unprotected( &the_thread->Wait.Node.Chain );
     134  Scheduler_Node *scheduler_node;
     135
     136  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
     137  _Chain_Extract_unprotected( &scheduler_node->Wait.Node.Chain );
    124138}
    125139
     
    157171)
    158172{
    159   Chain_Control *fifo = &heads->Heads.Fifo;
    160   Chain_Node    *first;
    161 
     173  Chain_Control  *fifo;
     174  Chain_Node     *first;
     175  Scheduler_Node *scheduler_node;
     176
     177  fifo = &heads->Heads.Fifo;
    162178  _Assert( !_Chain_Is_empty( fifo ) );
    163179  first = _Chain_First( fifo );
    164 
    165   return THREAD_CHAIN_NODE_TO_THREAD( first );
     180  scheduler_node = SCHEDULER_NODE_OF_WAIT_CHAIN_NODE( first );
     181
     182  return _Scheduler_Node_get_owner( scheduler_node );
    166183}
    167184
     
    207224{
    208225  const Priority_Control *the_left;
     226  const Scheduler_Node   *scheduler_node;
    209227  const Thread_Control   *the_right;
    210228
    211229  the_left = left;
    212   the_right = THREAD_RBTREE_NODE_TO_THREAD( right );
     230  scheduler_node = SCHEDULER_NODE_OF_WAIT_RBTREE_NODE( right );
     231  the_right = _Scheduler_Node_get_owner( scheduler_node );
    213232
    214233  return *the_left < the_right->current_priority;
     
    221240)
    222241{
    223   Thread_queue_Heads          *heads = queue->heads;
     242  Thread_queue_Heads          *heads;
    224243  Thread_queue_Priority_queue *priority_queue;
    225 
     244  Scheduler_Node              *scheduler_node;
     245
     246  heads = queue->heads;
    226247  _Assert( heads != NULL );
    227248
    228249  priority_queue = _Thread_queue_Priority_queue( heads, the_thread );
     250  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
    229251
    230252  _RBTree_Extract(
    231253    &priority_queue->Queue,
    232     &the_thread->Wait.Node.RBTree
     254    &scheduler_node->Wait.Node.RBTree
    233255  );
    234256  _RBTree_Insert_inline(
    235257    &priority_queue->Queue,
    236     &the_thread->Wait.Node.RBTree,
     258    &scheduler_node->Wait.Node.RBTree,
    237259    &new_priority,
    238260    _Thread_queue_Priority_less
     
    246268{
    247269  Thread_queue_Priority_queue *priority_queue;
     270  Scheduler_Node              *scheduler_node;
    248271
    249272  priority_queue = _Thread_queue_Priority_queue( heads, the_thread );
     
    253276#endif
    254277
    255   _RBTree_Initialize_node( &the_thread->Wait.Node.RBTree );
     278  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
     279
     280  _RBTree_Initialize_node( &scheduler_node->Wait.Node.RBTree );
    256281  _RBTree_Initialize_one(
    257282    &priority_queue->Queue,
    258     &the_thread->Wait.Node.RBTree
     283    &scheduler_node->Wait.Node.RBTree
    259284  );
    260285}
     
    266291{
    267292  Thread_queue_Priority_queue *priority_queue;
     293  Scheduler_Node              *scheduler_node;
    268294  Priority_Control             current_priority;
    269295
     
    276302#endif
    277303
     304  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
    278305  current_priority = the_thread->current_priority;
    279   _RBTree_Initialize_node( &the_thread->Wait.Node.RBTree );
     306
     307  _RBTree_Initialize_node( &scheduler_node->Wait.Node.RBTree );
    280308  _RBTree_Insert_inline(
    281309    &priority_queue->Queue,
    282     &the_thread->Wait.Node.RBTree,
     310    &scheduler_node->Wait.Node.RBTree,
    283311    &current_priority,
    284312    _Thread_queue_Priority_less
     
    291319)
    292320{
    293   Thread_queue_Priority_queue *priority_queue =
    294     _Thread_queue_Priority_queue( heads, the_thread );
     321  Thread_queue_Priority_queue *priority_queue;
     322  Scheduler_Node              *scheduler_node;
     323
     324  priority_queue = _Thread_queue_Priority_queue( heads, the_thread );
     325  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
    295326
    296327  _RBTree_Extract(
    297328    &priority_queue->Queue,
    298     &the_thread->Wait.Node.RBTree
     329    &scheduler_node->Wait.Node.RBTree
    299330  );
    300331
     
    343374  Thread_queue_Priority_queue *priority_queue;
    344375  RBTree_Node                 *first;
     376  Scheduler_Node              *scheduler_node;
    345377
    346378#if defined(RTEMS_SMP)
     
    354386  _Assert( !_RBTree_Is_empty( &priority_queue->Queue ) );
    355387  first = _RBTree_Minimum( &priority_queue->Queue );
    356 
    357   return THREAD_RBTREE_NODE_TO_THREAD( first );
     388  scheduler_node = SCHEDULER_NODE_OF_WAIT_RBTREE_NODE( first );
     389
     390  return _Scheduler_Node_get_owner( scheduler_node );
    358391}
    359392
Note: See TracChangeset for help on using the changeset viewer.