Changeset aea4a91 in rtems


Ignore:
Timestamp:
Aug 8, 2013, 9:49:15 AM (7 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
48c4a55
Parents:
fc2ad63
git-author:
Sebastian Huber <sebastian.huber@…> (08/08/13 09:49:15)
git-committer:
Sebastian Huber <sebastian.huber@…> (08/20/13 08:14:04)
Message:

smp: Optimize Simple SMP scheduler

Add Thread_Control::is_in_the_air field if configured for SMP. This
helps to simplify the extract operation and avoids superfluous
inter-processor interrupts. Move the processor allocation step into the
enqueue operation.

Add and use _Scheduler_simple_smp_Get_highest_ready(). Add and use
_Scheduler_SMP_Get_lowest_scheduled().

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/include/rtems/score/schedulersimplesmp.h

    rfc2ad63 raea4a91  
    5858    _Scheduler_simple_smp_Schedule, \
    5959    _Scheduler_simple_smp_Yield, \
    60     _Scheduler_simple_smp_Extract, \
     60    _Scheduler_simple_smp_Block, \
    6161    _Scheduler_simple_smp_Enqueue_priority_fifo, \
    6262    _Scheduler_default_Allocate, \
     
    7373
    7474void _Scheduler_simple_smp_Initialize( void );
     75
     76void _Scheduler_simple_smp_Block( Thread_Control *thread );
    7577
    7678void _Scheduler_simple_smp_Enqueue_priority_fifo( Thread_Control *thread );
  • cpukit/score/include/rtems/score/schedulersmpimpl.h

    rfc2ad63 raea4a91  
    8484}
    8585
     86static inline Thread_Control *_Scheduler_SMP_Get_lowest_scheduled(
     87  Scheduler_SMP_Control *self
     88)
     89{
     90  Thread_Control *lowest_ready = NULL;
     91  Chain_Control *scheduled = &self->scheduled;
     92
     93  if ( !_Chain_Is_empty( scheduled ) ) {
     94    lowest_ready = (Thread_Control *) _Chain_Last( scheduled );
     95  }
     96
     97  return lowest_ready;
     98}
     99
    86100/** @} */
    87101
  • cpukit/score/include/rtems/score/thread.h

    rfc2ad63 raea4a91  
    379379
    380380  /**
     381   * @brief This field is true if the thread is in the air.
     382   *
     383   * A thread is in the air if it has an allocated processor (it is an
     384   * executing or heir thread on exactly one processor) and it is not a member
     385   * of the scheduled chain.  The extract operation on a scheduled thread will
     386   * produce threads in the air (see also _Thread_Set_transient()).  The next
     387   * enqueue or schedule operation will decide what to do based on this state
     388   * indication.  It can either place the thread back on the scheduled chain
     389   * and the thread can keep its allocated processor, or it can take the
     390   * processor away from the thread and give the processor to another thread of
     391   * higher priority.
     392   */
     393  bool                                  is_in_the_air;
     394
     395  /**
    381396   * @brief This field is true if the thread is executing.
    382397   *
  • cpukit/score/src/schedulersimplesmp.c

    rfc2ad63 raea4a91  
    3535}
    3636
     37static Thread_Control *_Scheduler_simple_smp_Get_highest_ready(
     38  Scheduler_SMP_Control *self
     39)
     40{
     41  Thread_Control *highest_ready = NULL;
     42  Chain_Control *ready = &self->ready[ 0 ];
     43
     44  if ( !_Chain_Is_empty( ready ) ) {
     45    highest_ready = (Thread_Control *) _Chain_First( ready );
     46  }
     47
     48  return highest_ready;
     49}
     50
    3751static void _Scheduler_simple_smp_Move_from_scheduled_to_ready(
    38   Chain_Control *ready_chain,
     52  Scheduler_SMP_Control *self,
    3953  Thread_Control *scheduled_to_ready
    4054)
    4155{
    4256  _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
    43   _Scheduler_simple_Insert_priority_lifo( ready_chain, scheduled_to_ready );
     57  _Scheduler_simple_Insert_priority_lifo(
     58    &self->ready[ 0 ],
     59    scheduled_to_ready
     60  );
    4461}
    4562
    4663static void _Scheduler_simple_smp_Move_from_ready_to_scheduled(
    47   Chain_Control *scheduled_chain,
     64  Scheduler_SMP_Control *self,
    4865  Thread_Control *ready_to_scheduled
    4966)
    5067{
    5168  _Chain_Extract_unprotected( &ready_to_scheduled->Object.Node );
    52   _Scheduler_simple_Insert_priority_fifo( scheduled_chain, ready_to_scheduled );
     69  _Scheduler_simple_Insert_priority_fifo(
     70    &self->scheduled,
     71    ready_to_scheduled
     72  );
    5373}
    5474
     
    6282}
    6383
     84static void _Scheduler_simple_smp_Schedule_highest_ready(
     85  Scheduler_SMP_Control *self,
     86  Thread_Control *victim
     87)
     88{
     89  Thread_Control *highest_ready =
     90    (Thread_Control *) _Chain_First( &self->ready[ 0 ] );
     91
     92  _Scheduler_SMP_Allocate_processor( highest_ready, victim );
     93
     94  _Scheduler_simple_smp_Move_from_ready_to_scheduled( self, highest_ready );
     95}
     96
    6497static void _Scheduler_simple_smp_Enqueue_ordered(
    6598  Thread_Control *thread,
     
    69102  Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
    70103
    71   /*
    72    * The scheduled chain has exactly processor count nodes after
    73    * initialization, thus the lowest priority scheduled thread exists.
    74    */
    75   Thread_Control *lowest_scheduled =
    76     (Thread_Control *) _Chain_Last( &self->scheduled );
    77 
    78   if ( ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) ) {
    79     _Scheduler_SMP_Allocate_processor( thread, lowest_scheduled );
    80 
    81     _Scheduler_simple_smp_Insert( &self->scheduled, thread, order );
    82 
    83     _Scheduler_simple_smp_Move_from_scheduled_to_ready(
    84       &self->ready[ 0 ],
    85       lowest_scheduled
    86     );
     104  if ( thread->is_in_the_air ) {
     105    Thread_Control *highest_ready =
     106      _Scheduler_simple_smp_Get_highest_ready( self );
     107
     108    thread->is_in_the_air = false;
     109
     110    /*
     111     * The thread has been extracted from the scheduled chain.  We have to
     112     * place it now on the scheduled or ready chain.
     113     *
     114     * NOTE: Do not exchange parameters to do the negation of the order check.
     115     */
     116    if (
     117      highest_ready != NULL
     118        && !( *order )( &thread->Object.Node, &highest_ready->Object.Node )
     119    ) {
     120      _Scheduler_SMP_Allocate_processor( highest_ready, thread );
     121
     122      _Scheduler_simple_smp_Insert( &self->ready[ 0 ], thread, order );
     123
     124      _Scheduler_simple_smp_Move_from_ready_to_scheduled(
     125        self,
     126        highest_ready
     127      );
     128    } else {
     129      thread->is_scheduled = true;
     130
     131      _Scheduler_simple_smp_Insert( &self->scheduled, thread, order );
     132    }
    87133  } else {
    88     _Scheduler_simple_smp_Insert( &self->ready[ 0 ], thread, order );
     134    Thread_Control *lowest_scheduled = _Scheduler_SMP_Get_lowest_scheduled( self );
     135
     136    /*
     137     * The scheduled chain is empty if nested interrupts change the priority of
     138     * all scheduled threads.  These threads are in the air.
     139     */
     140    if (
     141      lowest_scheduled != NULL
     142        && ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node )
     143    ) {
     144      _Scheduler_SMP_Allocate_processor( thread, lowest_scheduled );
     145
     146      _Scheduler_simple_smp_Insert( &self->scheduled, thread, order );
     147
     148      _Scheduler_simple_smp_Move_from_scheduled_to_ready(
     149        self,
     150        lowest_scheduled
     151      );
     152    } else {
     153      _Scheduler_simple_smp_Insert( &self->ready[ 0 ], thread, order );
     154    }
     155  }
     156}
     157
     158void _Scheduler_simple_smp_Block( Thread_Control *thread )
     159{
     160  _Chain_Extract_unprotected( &thread->Object.Node );
     161
     162  if ( thread->is_scheduled ) {
     163    Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
     164
     165    _Scheduler_simple_smp_Schedule_highest_ready( self, thread );
    89166  }
    90167}
     
    108185void _Scheduler_simple_smp_Extract( Thread_Control *thread )
    109186{
    110   Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
     187  thread->is_in_the_air = true;
    111188
    112189  _Chain_Extract_unprotected( &thread->Object.Node );
    113 
    114   if ( thread->is_scheduled ) {
    115     Thread_Control *highest_ready =
    116       (Thread_Control *) _Chain_First( &self->ready[ 0 ] );
    117 
    118     _Scheduler_SMP_Allocate_processor( highest_ready, thread );
    119 
    120     _Scheduler_simple_smp_Move_from_ready_to_scheduled(
    121       &self->scheduled,
    122       highest_ready
    123     );
    124   }
    125190}
    126191
     
    139204void _Scheduler_simple_smp_Schedule( Thread_Control *thread )
    140205{
    141   ( void ) thread;
    142 }
     206  if ( thread->is_in_the_air ) {
     207    Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
     208
     209    thread->is_in_the_air = false;
     210
     211    _Scheduler_simple_smp_Schedule_highest_ready( self, thread );
     212  }
     213}
  • cpukit/score/src/threadinitialize.c

    rfc2ad63 raea4a91  
    181181#if defined(RTEMS_SMP)
    182182  the_thread->is_scheduled            = false;
     183  the_thread->is_in_the_air           = false;
    183184  the_thread->is_executing            = false;
    184185
  • testsuites/smptests/smpmigration01/smpmigration01.scn

    rfc2ad63 raea4a91  
    11*** TEST SMPMIGRATION 1 ***
    22runner 0
    3         cpu 0 tokens 411501
    4         cpu 0 cycles 9464534
    5         cpu 1 tokens 411501
    6         cpu 1 cycles 9464802
     3        cpu 0 tokens 530399
     4        cpu 0 cycles 10077490
     5        cpu 1 tokens 530399
     6        cpu 1 cycles 10071429
    77runner 1
    8         cpu 0 tokens 411500
    9         cpu 0 cycles 41936630
    10         cpu 1 tokens 411501
    11         cpu 1 cycles 42009945
     8        cpu 0 tokens 530399
     9        cpu 0 cycles 5978212
     10        cpu 1 tokens 530399
     11        cpu 1 cycles 7951897
    1212runner 2
    13         cpu 0 tokens 411501
    14         cpu 0 cycles 6583983
    15         cpu 1 tokens 411500
    16         cpu 1 cycles 6583701
     13        cpu 0 tokens 530399
     14        cpu 0 cycles 10070929
     15        cpu 1 tokens 530398
     16        cpu 1 cycles 10106437
    1717*** END OF TEST SMPMIGRATION 1 ***
Note: See TracChangeset for help on using the changeset viewer.