Changeset a816f084 in rtems


Ignore:
Timestamp:
May 7, 2015, 12:02:46 PM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
7a70a09
Parents:
80f376d
git-author:
Sebastian Huber <sebastian.huber@…> (05/07/15 12:02:46)
git-committer:
Sebastian Huber <sebastian.huber@…> (05/19/15 10:00:48)
Message:

score: Fine grained locking for MrsP

Update #2273.

Location:
cpukit
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • cpukit/rtems/src/semobtain.c

    r80f376d ra816f084  
    6060        MRSP_Status mrsp_status;
    6161
    62         _Thread_Disable_dispatch();
    63         _ISR_lock_ISR_enable( &lock_context );
    6462        mrsp_status = _MRSP_Obtain(
    6563          &the_semaphore->Core_control.mrsp,
    6664          executing,
    6765          wait,
    68           timeout
     66          timeout,
     67          &lock_context
    6968        );
    70         _Thread_Enable_dispatch();
    71         _Objects_Put_for_get_isr_disable( &the_semaphore->Object );
    7269        return _Semaphore_Translate_MRSP_status_code( mrsp_status );
    7370      } else
  • cpukit/rtems/src/semrelease.c

    r80f376d ra816f084  
    7676#if defined(RTEMS_SMP)
    7777      if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
    78         _Thread_Disable_dispatch();
    79         _ISR_lock_ISR_enable( &lock_context );
    80         MRSP_Status mrsp_status = _MRSP_Release(
     78        MRSP_Status mrsp_status;
     79
     80        mrsp_status = _MRSP_Release(
    8181          &the_semaphore->Core_control.mrsp,
    82           _Thread_Get_executing()
     82          _Thread_Executing,
     83          &lock_context
    8384        );
    84         _Thread_Enable_dispatch();
    8585        return _Semaphore_Translate_MRSP_status_code( mrsp_status );
    8686      } else
  • cpukit/score/include/rtems/score/mrsp.h

    r80f376d ra816f084  
    2121
    2222#include <rtems/score/chain.h>
     23#include <rtems/score/isrlock.h>
    2324#include <rtems/score/scheduler.h>
    2425#include <rtems/score/thread.h>
     
    7677} MRSP_Status;
    7778
     79typedef struct MRSP_Control MRSP_Control;
     80
    7881/**
    7982 * @brief MrsP rival.
    8083 *
    8184 * The rivals are used by threads waiting for resource ownership.  They are
    82  * registered in the MRSP control block.
     85 * registered in the MrsP control block.
    8386 */
    8487typedef struct {
    8588  /**
    86    * @brief The node for registration in the MRSP rival chain.
     89   * @brief The node for registration in the MrsP rival chain.
    8790   *
    88    * The chain operations are protected by the Giant lock and disabled
    89    * interrupts.
     91   * The chain operations are protected by the MrsP control lock.
    9092   *
    9193   * @see MRSP_Control::Rivals.
    9294   */
    9395  Chain_Node Node;
     96
     97  /**
     98   * @brief The corresponding MrsP control block.
     99   */
     100  MRSP_Control *resource;
    94101
    95102  /**
     
    119126   * Initially the status is set to MRSP_WAIT_FOR_OWNERSHIP.  The rival will
    120127   * busy wait until a status change happens.  This can be MRSP_SUCCESSFUL or
    121    * MRSP_TIMEOUT.  State changes are protected by the Giant lock and disabled
    122    * interrupts.
     128   * MRSP_TIMEOUT.  State changes are protected by the MrsP control lock.
    123129   */
    124130  volatile MRSP_Status status;
     
    128134 * @brief MrsP control block.
    129135 */
    130 typedef struct {
     136struct MRSP_Control {
    131137  /**
    132138   * @brief Basic resource control.
     
    142148
    143149  /**
     150   * @brief Lock to protect the resource dependency tree.
     151   */
     152  ISR_LOCK_MEMBER( Lock )
     153
     154  /**
    144155   * @brief The initial priority of the owner before it was elevated to the
    145156   * ceiling priority.
     
    151162   */
    152163  Priority_Control *ceiling_priorities;
    153 } MRSP_Control;
     164};
    154165
    155166/** @} */
  • cpukit/score/include/rtems/score/mrspimpl.h

    r80f376d ra816f084  
    3737 */
    3838
     39/*
     40 * FIXME: Operations with the resource dependency tree are protected by the
     41 * global scheduler lock.  Since the scheduler lock should be scheduler
     42 * instance specific in the future this will only work temporarily.  A more
     43 * sophisticated locking strategy is necessary.
     44 */
     45
     46RTEMS_INLINE_ROUTINE void _MRSP_Giant_acquire( ISR_lock_Context *lock_context )
     47{
     48  _ISR_lock_Acquire( &_Scheduler_Lock, lock_context );
     49}
     50
     51RTEMS_INLINE_ROUTINE void _MRSP_Giant_release( ISR_lock_Context *lock_context )
     52{
     53  _ISR_lock_Release( &_Scheduler_Lock, lock_context );
     54}
     55
    3956RTEMS_INLINE_ROUTINE bool _MRSP_Restore_priority_filter(
    4057  Thread_Control   *thread,
     
    7592  Thread_Control   *new_owner,
    7693  Priority_Control  initial_priority,
    77   Priority_Control  ceiling_priority
    78 )
    79 {
     94  Priority_Control  ceiling_priority,
     95  ISR_lock_Context *lock_context
     96)
     97{
     98  Per_CPU_Control *cpu_self;
     99
    80100  _Resource_Node_add_resource( &new_owner->Resource_node, &mrsp->Resource );
    81101  _Resource_Set_owner( &mrsp->Resource, &new_owner->Resource_node );
    82102  mrsp->initial_priority_of_owner = initial_priority;
     103  _Scheduler_Thread_change_help_state( new_owner, SCHEDULER_HELP_ACTIVE_OWNER );
     104
     105  cpu_self = _Thread_Dispatch_disable_critical();
     106  _ISR_lock_Release_and_ISR_enable( &mrsp->Lock, lock_context );
     107
    83108  _Thread_Raise_priority( new_owner, ceiling_priority );
    84   _Scheduler_Thread_change_help_state( new_owner, SCHEDULER_HELP_ACTIVE_OWNER );
     109
     110  _Thread_Dispatch_enable( cpu_self );
    85111}
    86112
     
    112138  _Resource_Initialize( &mrsp->Resource );
    113139  _Chain_Initialize_empty( &mrsp->Rivals );
     140  _ISR_lock_Initialize( &mrsp->Lock, "MrsP" );
    114141
    115142  return MRSP_SUCCESSFUL;
     
    139166{
    140167  MRSP_Rival *rival = arg;
     168  MRSP_Control *mrsp = rival->resource;
    141169  Thread_Control *thread = rival->thread;
    142   ISR_Level level;
     170  ISR_lock_Context lock_context;
    143171
    144172  (void) id;
    145173
    146   _ISR_Disable( level );
     174  _ISR_lock_ISR_disable_and_acquire( &mrsp->Lock, &lock_context );
    147175
    148176  if ( rival->status == MRSP_WAIT_FOR_OWNERSHIP ) {
    149     rival->status = MRSP_TIMEOUT;
     177    ISR_lock_Context giant_lock_context;
     178
     179    _MRSP_Giant_acquire( &giant_lock_context );
    150180
    151181    _Chain_Extract_unprotected( &rival->Node );
    152182    _Resource_Node_extract( &thread->Resource_node );
    153183    _Resource_Node_set_dependency( &thread->Resource_node, NULL );
    154 
    155     _ISR_Enable( level );
    156 
    157184    _Scheduler_Thread_change_help_state( thread, rival->initial_help_state );
    158185    _Scheduler_Thread_change_resource_root( thread, thread );
    159     _MRSP_Restore_priority( thread, rival->initial_priority );
     186
     187    _MRSP_Giant_release( &giant_lock_context );
     188
     189    rival->status = MRSP_TIMEOUT;
     190
     191    _ISR_lock_Release_and_ISR_enable( &mrsp->Lock, &lock_context );
    160192  } else {
    161     _ISR_Enable( level );
     193    _ISR_lock_Release_and_ISR_enable( &mrsp->Lock, &lock_context );
    162194  }
    163195}
     
    169201  Priority_Control   initial_priority,
    170202  Priority_Control   ceiling_priority,
    171   Watchdog_Interval  timeout
     203  Watchdog_Interval  timeout,
     204  ISR_lock_Context  *lock_context
    172205)
    173206{
     
    175208  MRSP_Rival rival;
    176209  bool initial_life_protection;
    177   ISR_Level level;
     210  Per_CPU_Control *cpu_self;
     211  ISR_lock_Context giant_lock_context;
    178212
    179213  rival.thread = executing;
     214  rival.resource = mrsp;
    180215  rival.initial_priority = initial_priority;
     216
     217  _MRSP_Giant_acquire( &giant_lock_context );
     218
    181219  rival.initial_help_state =
    182220    _Scheduler_Thread_change_help_state( executing, SCHEDULER_HELP_ACTIVE_RIVAL );
    183221  rival.status = MRSP_WAIT_FOR_OWNERSHIP;
    184222
    185   _Thread_Raise_priority( executing, ceiling_priority );
    186 
    187   _ISR_Disable( level );
    188 
    189223  _Chain_Append_unprotected( &mrsp->Rivals, &rival.Node );
    190224  _Resource_Add_rival( &mrsp->Resource, &executing->Resource_node );
    191225  _Resource_Node_set_dependency( &executing->Resource_node, &mrsp->Resource );
    192 
    193   _ISR_Enable( level );
    194 
    195226  _Scheduler_Thread_change_resource_root(
    196227    executing,
    197228    THREAD_RESOURCE_NODE_TO_THREAD( _Resource_Node_get_root( owner ) )
    198229  );
     230
     231  _MRSP_Giant_release( &giant_lock_context );
     232
     233  cpu_self = _Thread_Dispatch_disable_critical();
     234  _ISR_lock_Release_and_ISR_enable( &mrsp->Lock, lock_context );
     235
     236  _Thread_Raise_priority( executing, ceiling_priority );
    199237
    200238  if ( timeout > 0 ) {
     
    209247
    210248  initial_life_protection = _Thread_Set_life_protection( true );
    211   _Thread_Enable_dispatch();
     249  _Thread_Dispatch_enable( cpu_self );
    212250
    213251  _Assert( _Debug_Is_thread_dispatching_allowed() );
     
    218256  } while ( status == MRSP_WAIT_FOR_OWNERSHIP );
    219257
    220   _Thread_Disable_dispatch();
    221258  _Thread_Set_life_protection( initial_life_protection );
    222259
    223260  if ( timeout > 0 ) {
    224261    _Watchdog_Remove_ticks( &executing->Timer );
     262
     263    if ( status == MRSP_TIMEOUT ) {
     264      _MRSP_Restore_priority( executing, initial_priority );
     265    }
    225266  }
    226267
     
    232273  Thread_Control    *executing,
    233274  bool               wait,
    234   Watchdog_Interval  timeout
     275  Watchdog_Interval  timeout,
     276  ISR_lock_Context  *lock_context
    235277)
    236278{
     
    248290
    249291  if ( !priority_ok) {
     292    _ISR_lock_ISR_enable( lock_context );
    250293    return MRSP_INVALID_PRIORITY;
    251294  }
    252295
     296  _ISR_lock_Acquire( &mrsp->Lock, lock_context );
    253297  owner = _Resource_Get_owner( &mrsp->Resource );
    254298  if ( owner == NULL ) {
     
    257301      executing,
    258302      initial_priority,
    259       ceiling_priority
     303      ceiling_priority,
     304      lock_context
    260305    );
    261306    status = MRSP_SUCCESSFUL;
    262   } else if ( _Resource_Node_get_root( owner ) == &executing->Resource_node ) {
    263     /* Nested access or deadlock */
    264     status = MRSP_UNSATISFIED;
    265   } else if ( wait ) {
     307  } else if (
     308    wait
     309      && _Resource_Node_get_root( owner ) != &executing->Resource_node
     310  ) {
    266311    status = _MRSP_Wait_for_ownership(
    267312      mrsp,
     
    270315      initial_priority,
    271316      ceiling_priority,
    272       timeout
     317      timeout,
     318      lock_context
    273319    );
    274320  } else {
     321    _ISR_lock_Release_and_ISR_enable( &mrsp->Lock, lock_context );
     322    /* Not available, nested access or deadlock */
    275323    status = MRSP_UNSATISFIED;
    276324  }
     
    280328
    281329RTEMS_INLINE_ROUTINE MRSP_Status _MRSP_Release(
    282   MRSP_Control   *mrsp,
    283   Thread_Control *executing
    284 )
    285 {
    286   ISR_Level level;
     330  MRSP_Control     *mrsp,
     331  Thread_Control   *executing,
     332  ISR_lock_Context *lock_context
     333)
     334{
     335  Priority_Control initial_priority;
     336  Per_CPU_Control *cpu_self;
     337  ISR_lock_Context giant_lock_context;
    287338
    288339  if ( _Resource_Get_owner( &mrsp->Resource ) != &executing->Resource_node ) {
     340    _ISR_lock_ISR_enable( lock_context );
    289341    return MRSP_NOT_OWNER_OF_RESOURCE;
    290342  }
     
    296348    )
    297349  ) {
     350    _ISR_lock_ISR_enable( lock_context );
    298351    return MRSP_INCORRECT_STATE;
    299352  }
    300353
    301   _MRSP_Restore_priority( executing, mrsp->initial_priority_of_owner );
    302 
    303   _ISR_Disable( level );
     354  initial_priority = mrsp->initial_priority_of_owner;
     355
     356  _ISR_lock_Acquire( &mrsp->Lock, lock_context );
     357
     358  _MRSP_Giant_acquire( &giant_lock_context );
    304359
    305360  _Resource_Extract( &mrsp->Resource );
    306361
    307362  if ( _Chain_Is_empty( &mrsp->Rivals ) ) {
    308     _ISR_Enable( level );
    309 
    310363    _Resource_Set_owner( &mrsp->Resource, NULL );
    311364  } else {
     
    326379    _Resource_Node_add_resource( &new_owner->Resource_node, &mrsp->Resource );
    327380    _Resource_Set_owner( &mrsp->Resource, &new_owner->Resource_node );
    328 
    329     _ISR_Enable( level );
    330 
    331381    _Scheduler_Thread_change_help_state( new_owner, SCHEDULER_HELP_ACTIVE_OWNER );
    332382    _Scheduler_Thread_change_resource_root( new_owner, new_owner );
     
    337387  }
    338388
     389  _MRSP_Giant_release( &giant_lock_context );
     390
     391  cpu_self = _Thread_Dispatch_disable_critical();
     392  _ISR_lock_Release_and_ISR_enable( &mrsp->Lock, lock_context );
     393
     394  _MRSP_Restore_priority( executing, initial_priority );
     395
     396  _Thread_Dispatch_enable( cpu_self );
     397
    339398  return MRSP_SUCCESSFUL;
    340399}
     
    346405  }
    347406
     407  _ISR_lock_Destroy( &mrsp->Lock );
    348408  _Workspace_Free( mrsp->ceiling_priorities );
    349409
  • cpukit/score/src/schedulerchangeroot.c

    r80f376d ra816f084  
    6262  Scheduler_Node *offers_help_node;
    6363  Thread_Control *offers_help_too;
    64   ISR_Level level;
    65 
    66   _ISR_Disable( level );
    6764
    6865  offers_help_node = _Scheduler_Thread_get_node( offers_help );
     
    8178    _Scheduler_Ask_for_help( ctx.needs_help );
    8279  }
    83 
    84   _ISR_Enable( level );
    8580}
Note: See TracChangeset for help on using the changeset viewer.