Changeset ff2e6c64 in rtems


Ignore:
Timestamp:
Aug 2, 2016, 9:26:56 AM (3 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
21bdca4
Parents:
3b3552bf
git-author:
Sebastian Huber <sebastian.huber@…> (08/02/16 09:26:56)
git-committer:
Sebastian Huber <sebastian.huber@…> (08/03/16 11:57:30)
Message:

score: Fix and simplify thread wait locks

There was a subtile race condition in _Thread_queue_Do_extract_locked().
It must first update the thread wait flags and then restore the default
thread wait state. In the previous implementation this could lead under
rare timing conditions to an ineffective _Thread_Wait_tranquilize()
resulting to a corrupt system state.

Update #2556.

Location:
cpukit/score
Files:
8 edited

Legend:

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

    r3b3552bf rff2e6c64  
    327327     */
    328328    Chain_Control Pending_requests;
     329
     330    /**
     331     * @brief Tranquilizer gate used by _Thread_Wait_tranquilize().
     332     *
     333     * This gate is closed by _Thread_Wait_claim().  In case there are no
     334     * pending requests during a _Thread_Wait_restore_default(), then this gate
     335     * is opened immediately, otherwise it is placed on the pending request
     336     * chain and opened by _Thread_Wait_remove_request_locked() as the last
     337     * gate on the chain to signal overall request completion.
     338     */
     339    Thread_queue_Gate Tranquilizer;
    329340  } Lock;
    330341
  • cpukit/score/include/rtems/score/threadimpl.h

    r3b3552bf rff2e6c64  
    10371037)
    10381038{
     1039  Chain_Node *first;
     1040
    10391041  _Chain_Extract_unprotected( &queue_context->Wait.Gate.Node );
    1040 
    1041   if ( !_Chain_Is_empty( &the_thread->Wait.Lock.Pending_requests ) ) {
    1042     Thread_queue_Context *first;
    1043 
    1044     first = THREAD_QUEUE_CONTEXT_OF_REQUEST(
    1045       _Chain_First( &the_thread->Wait.Lock.Pending_requests )
    1046     );
    1047 
    1048     _Thread_queue_Gate_open( &first->Wait.Gate );
     1042  first = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
     1043
     1044  if ( first != _Chain_Tail( &the_thread->Wait.Lock.Pending_requests ) ) {
     1045    _Thread_queue_Gate_open( (Thread_queue_Gate *) first );
    10491046  }
    10501047}
    10511048
    10521049RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_queue_critical(
    1053   SMP_ticket_lock_Control *queue_lock,
    1054   Thread_queue_Context    *queue_context
    1055 )
    1056 {
    1057   _SMP_ticket_lock_Acquire(
    1058     queue_lock,
     1050  Thread_queue_Queue   *queue,
     1051  Thread_queue_Context *queue_context
     1052)
     1053{
     1054  _Thread_queue_Queue_acquire_critical(
     1055    queue,
    10591056    &_Thread_Executing->Potpourri_stats,
    1060     &queue_context->Lock_context.Lock_context.Stats_context
     1057    &queue_context->Lock_context
    10611058  );
    10621059}
    10631060
    10641061RTEMS_INLINE_ROUTINE void _Thread_Wait_release_queue_critical(
    1065   SMP_ticket_lock_Control *queue_lock,
    1066   Thread_queue_Context    *queue_context
    1067 )
    1068 {
    1069   _SMP_ticket_lock_Release(
    1070     queue_lock,
    1071     &queue_context->Lock_context.Lock_context.Stats_context
     1062  Thread_queue_Queue   *queue,
     1063  Thread_queue_Context *queue_context
     1064)
     1065{
     1066  _Thread_queue_Queue_release_critical(
     1067    queue,
     1068    &queue_context->Lock_context
    10721069  );
    10731070}
     
    10991096  queue = the_thread->Wait.queue;
    11001097  queue_context->Wait.queue = queue;
    1101   queue_context->Wait.operations = the_thread->Wait.operations;
    11021098
    11031099  if ( queue != NULL ) {
    1104     queue_context->Wait.queue_lock = &queue->Lock;
    1105     _Chain_Initialize_node( &queue_context->Wait.Gate.Node );
    1106     _Chain_Append_unprotected(
     1100    _Thread_queue_Gate_add(
    11071101      &the_thread->Wait.Lock.Pending_requests,
    1108       &queue_context->Wait.Gate.Node
     1102      &queue_context->Wait.Gate
    11091103    );
    11101104    _Thread_Wait_release_default_critical(
     
    11121106      &queue_context->Lock_context
    11131107    );
    1114     _Thread_Wait_acquire_queue_critical( &queue->Lock, queue_context );
    1115   } else {
    1116     queue_context->Wait.queue_lock = NULL;
     1108    _Thread_Wait_acquire_queue_critical( queue, queue_context );
     1109
     1110    if ( queue_context->Wait.queue == NULL ) {
     1111      _Thread_Wait_release_queue_critical( queue, queue_context );
     1112      _Thread_Wait_acquire_default_critical(
     1113        the_thread,
     1114        &queue_context->Lock_context
     1115      );
     1116      _Thread_Wait_remove_request_locked( the_thread, queue_context );
     1117      _Assert( the_thread->Wait.queue == NULL );
     1118    }
    11171119  }
    11181120#else
     
    11551157{
    11561158#if defined(RTEMS_SMP)
    1157   SMP_ticket_lock_Control *queue_lock;
    1158 
    1159   queue_lock = queue_context->Wait.queue_lock;
    1160 
    1161   if ( queue_lock != NULL ) {
    1162     _Thread_Wait_release_queue_critical( queue_lock, queue_context );
     1159  Thread_queue_Queue *queue;
     1160
     1161  queue = queue_context->Wait.queue;
     1162
     1163  if ( queue != NULL ) {
     1164    _Thread_Wait_release_queue_critical( queue, queue_context );
    11631165    _Thread_Wait_acquire_default_critical(
    11641166      the_thread,
     
    12191221
    12201222  _Assert( the_thread->Wait.queue == NULL );
     1223
     1224#if defined(RTEMS_SMP)
     1225  _Chain_Initialize_empty( &the_thread->Wait.Lock.Pending_requests );
     1226  _Chain_Initialize_node( &the_thread->Wait.Lock.Tranquilizer.Node );
     1227  _Thread_queue_Gate_close( &the_thread->Wait.Lock.Tranquilizer );
     1228#endif
     1229
    12211230  the_thread->Wait.queue = queue;
    12221231  the_thread->Wait.operations = operations;
     
    12741283  const Chain_Node *tail;
    12751284
    1276   _Thread_Wait_acquire_default_critical(
    1277     the_thread,
    1278     &lock_context
    1279   );
     1285  _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
    12801286
    12811287  node = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
    12821288  tail = _Chain_Immutable_tail( &the_thread->Wait.Lock.Pending_requests );
    12831289
    1284   while ( node != tail ) {
    1285     Thread_queue_Context *queue_context;
    1286 
    1287     queue_context = THREAD_QUEUE_CONTEXT_OF_REQUEST( node );
    1288     queue_context->Wait.queue = NULL;
    1289     queue_context->Wait.operations = &_Thread_queue_Operations_stale_queue;
    1290 
    1291     node = _Chain_Next( node );
     1290  if ( node != tail ) {
     1291    do {
     1292      Thread_queue_Context *queue_context;
     1293
     1294      queue_context = THREAD_QUEUE_CONTEXT_OF_REQUEST( node );
     1295      queue_context->Wait.queue = NULL;
     1296
     1297      node = _Chain_Next( node );
     1298    } while ( node != tail );
     1299
     1300    _Thread_queue_Gate_add(
     1301      &the_thread->Wait.Lock.Pending_requests,
     1302      &the_thread->Wait.Lock.Tranquilizer
     1303    );
     1304  } else {
     1305    _Thread_queue_Gate_open( &the_thread->Wait.Lock.Tranquilizer );
    12921306  }
    12931307#endif
     
    12971311
    12981312#if defined(RTEMS_SMP)
    1299   _Thread_Wait_release_default_critical(
    1300     the_thread,
    1301     &lock_context
    1302   );
    1303 #endif
    1304 }
    1305 
    1306 /**
    1307  * @brief Tranquilizes the thread after a wait a thread queue.
     1313  _Thread_Wait_release_default_critical( the_thread, &lock_context );
     1314#endif
     1315}
     1316
     1317/**
     1318 * @brief Tranquilizes the thread after a wait on a thread queue.
    13081319 *
    13091320 * After the violent blocking procedure this function makes the thread calm and
     
    13151326 * On other configurations, this function does nothing.
    13161327 *
     1328 * It must be called after a _Thread_Wait_claim() exactly once
     1329 *  - after the corresponding thread queue lock was released, and
     1330 *  - the default wait state is restored or some other processor is about to do
     1331 *    this.
     1332 *
    13171333 * @param[in] the_thread The thread.
    13181334 */
     
    13221338{
    13231339#if defined(RTEMS_SMP)
    1324   Thread_queue_Context queue_context;
    1325 
    1326   _Thread_queue_Context_initialize( &queue_context );
    1327   _Thread_Wait_acquire_default( the_thread, &queue_context.Lock_context );
    1328 
    1329   if ( !_Chain_Is_empty( &the_thread->Wait.Lock.Pending_requests ) ) {
    1330     _Thread_queue_Gate_add(
    1331       &the_thread->Wait.Lock.Pending_requests,
    1332       &queue_context.Wait.Gate
    1333     );
    1334     _Thread_Wait_release_default( the_thread, &queue_context.Lock_context );
    1335     _Thread_queue_Gate_wait( &queue_context.Wait.Gate );
    1336     _Thread_Wait_remove_request( the_thread, &queue_context );
    1337   } else {
    1338     _Thread_Wait_release_default( the_thread, &queue_context.Lock_context );
    1339   }
     1340  _Thread_queue_Gate_wait( &the_thread->Wait.Lock.Tranquilizer );
    13401341#else
    13411342  (void) the_thread;
     
    13551356)
    13561357{
    1357   _Thread_queue_Context_extract( queue_context, the_thread );
    1358 
    1359 #if defined(RTEMS_SMP)
    1360   if ( queue_context->Wait.queue != NULL ) {
    1361 #endif
     1358  Thread_queue_Queue *queue;
     1359
     1360  queue = the_thread->Wait.queue;
     1361
     1362#if defined(RTEMS_SMP)
     1363  if ( queue != NULL ) {
     1364    _Assert( queue_context->Wait.queue == queue );
     1365#endif
     1366
     1367    ( *the_thread->Wait.operations->extract )( queue, the_thread );
    13621368    _Thread_Wait_restore_default( the_thread );
    1363 #if defined(RTEMS_SMP)
     1369
     1370#if defined(RTEMS_SMP)
     1371    _Assert( queue_context->Wait.queue == NULL );
     1372    queue_context->Wait.queue = queue;
    13641373  }
    13651374#endif
  • cpukit/score/include/rtems/score/threadq.h

    r3b3552bf rff2e6c64  
    165165
    166166    /**
    167      * @brief The thread queue lock in case the thread is blocked on a thread
    168      * queue at thread wait lock acquire time.
    169      */
    170     SMP_ticket_lock_Control *queue_lock;
    171 
    172     /**
    173      * @brief The thread queue after thread wait lock acquire.
    174      *
    175      * In case the thread queue is NULL and the thread queue lock is non-NULL
    176      * in this context, then we have a stale thread queue.  This happens in
    177      * case the thread wait default is restored while we wait on the thread
    178      * queue lock, e.g. during a mutex ownership transfer.
    179      *
    180      * @see _Thread_Wait_restore_default().
     167     * @brief The thread queue in case the thread is blocked on a thread queue.
    181168     */
    182169    Thread_queue_Queue *queue;
    183 
    184     /**
    185      * @brief The thread queue operations after thread wait lock acquire.
    186      */
    187     const Thread_queue_Operations *operations;
    188170  } Wait;
    189171#endif
     
    350332 * @brief Thread queue priority change operation.
    351333 *
     334 * @param[in] queue The actual thread queue.
    352335 * @param[in] the_thread The thread.
    353336 * @param[in] new_priority The new priority value.
    354  * @param[in] prepend_it In case this is true, then the thread is prepended to
    355  *   its priority group in its scheduler instance, otherwise it is appended.
    356  * @param[in] queue The actual thread queue.
    357337 *
    358338 * @see Thread_queue_Operations.
    359339 */
    360340typedef void ( *Thread_queue_Priority_change_operation )(
     341  Thread_queue_Queue *queue,
    361342  Thread_Control     *the_thread,
    362   Priority_Control    new_priority,
    363   bool                prepend_it,
    364   Thread_queue_Queue *queue
     343  Priority_Control    new_priority
    365344);
    366345
  • cpukit/score/include/rtems/score/threadqimpl.h

    r3b3552bf rff2e6c64  
    235235#endif
    236236
    237 /**
    238  * @brief Gets the thread wait queue of the thread queue context.
    239  *
    240  * On SMP configurations, the value is stored in the thread queue context,
    241  * otherwise in the thread itself.
    242  *
    243  * @param queue_context The thread queue context.
    244  * @param the_thread The thread.
    245  */
    246237#if defined(RTEMS_SMP)
    247 #define _Thread_queue_Context_get_queue( queue_context, the_thread ) \
    248   ( queue_context )->Wait.queue
    249 #else
    250 #define _Thread_queue_Context_get_queue( queue_context, the_thread ) \
    251   ( the_thread )->Wait.queue
    252 #endif
    253 
    254 /**
    255  * @brief Gets the thread wait operations of the thread queue context.
    256  *
    257  * On SMP configurations, the value is stored in the thread queue context,
    258  * otherwise in the thread itself.
    259  *
    260  * @param queue_context The thread queue context.
    261  * @param the_thread The thread.
    262  */
    263 #if defined(RTEMS_SMP)
    264 #define _Thread_queue_Context_get_operations( queue_context, the_thread ) \
    265   ( queue_context )->Wait.operations
    266 #else
    267 #define _Thread_queue_Context_get_operations( queue_context, the_thread ) \
    268   ( the_thread )->Wait.operations
    269 #endif
    270 
    271 /**
    272  * @brief Thread priority change by means of the thread queue context.
    273  *
    274  * On SMP configurations, the used data is stored in the thread queue context,
    275  * otherwise in the thread itself.
    276  *
    277  * @param queue_context The thread queue context.
    278  * @param the_thread The thread.
    279  * @param new_priority The new thread priority.
    280  * @param prepend_it Prepend it to its priority group or not.
    281  */
    282 #if defined(RTEMS_SMP)
    283 #define _Thread_queue_Context_priority_change( \
    284     queue_context, \
    285     the_thread, \
    286     new_priority, \
    287     prepend_it \
    288   ) \
    289     ( *( queue_context )->Wait.operations->priority_change )( \
    290       the_thread, \
    291       new_priority, \
    292       prepend_it, \
    293       ( queue_context )->Wait.queue \
    294     )
    295 #else
    296 #define _Thread_queue_Context_priority_change( \
    297     queue_context, \
    298     the_thread, \
    299     new_priority, \
    300     prepend_it \
    301   ) \
    302     ( *( the_thread )->Wait.operations->priority_change )( \
    303       the_thread, \
    304       new_priority, \
    305       prepend_it, \
    306       ( the_thread )->Wait.queue \
    307     )
    308 #endif
    309 
    310 /**
    311  * @brief Thread queue extract by means of the thread queue context.
    312  *
    313  * On SMP configurations, the used data is stored in the thread queue context,
    314  * otherwise in the thread itself.
    315  *
    316  * @param queue_context The thread queue context.
    317  * @param the_thread The thread.
    318  */
    319 #if defined(RTEMS_SMP)
    320 #define _Thread_queue_Context_extract( \
    321     queue_context, \
    322     the_thread \
    323   ) \
    324     ( *( queue_context )->Wait.operations->extract )( \
    325       ( queue_context )->Wait.queue, \
    326       the_thread \
    327     )
    328 #else
    329 #define _Thread_queue_Context_extract( \
    330     queue_context, \
    331     the_thread \
    332   ) \
    333     ( *( the_thread )->Wait.operations->extract )( \
    334       ( the_thread )->Wait.queue, \
    335       the_thread \
    336     )
    337 #endif
    338 
    339 #if defined(RTEMS_SMP)
     238RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_close(
     239  Thread_queue_Gate *gate
     240)
     241{
     242  _Atomic_Store_uint( &gate->go_ahead, 0, ATOMIC_ORDER_RELAXED );
     243}
     244
    340245RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_add(
    341246  Chain_Control     *chain,
     
    343248)
    344249{
    345   _Atomic_Store_uint( &gate->go_ahead, 0, ATOMIC_ORDER_RELAXED );
    346250  _Chain_Append_unprotected( chain, &gate->Node );
    347251}
     
    1088992extern const Thread_queue_Operations _Thread_queue_Operations_priority_inherit;
    1089993
    1090 #if defined(RTEMS_SMP)
    1091 extern const Thread_queue_Operations _Thread_queue_Operations_stale_queue;
    1092 #endif
    1093 
    1094994/**@}*/
    1095995
  • cpukit/score/src/threadchangepriority.c

    r3b3552bf rff2e6c64  
    4747   */
    4848  if ( ( *filter )( the_thread, &new_priority, arg ) ) {
    49     _Thread_queue_Context_priority_change(
    50       queue_context,
     49    _Scheduler_Thread_set_priority( the_thread, new_priority, prepend_it );
     50
     51    ( *the_thread->Wait.operations->priority_change )(
     52      the_thread->Wait.queue,
    5153      the_thread,
    52       new_priority,
    53       prepend_it
     54      new_priority
    5455    );
    5556  } else {
  • cpukit/score/src/threadinitialize.c

    r3b3552bf rff2e6c64  
    187187    "Thread Wait Default Lock"
    188188  );
    189   _Chain_Initialize_empty( &the_thread->Wait.Lock.Pending_requests );
     189  _Thread_queue_Gate_open( &the_thread->Wait.Lock.Tranquilizer );
    190190  _SMP_lock_Stats_initialize( &the_thread->Potpourri_stats, "Thread Potpourri" );
    191191#endif
  • cpukit/score/src/threadqenqueue.c

    r3b3552bf rff2e6c64  
    177177    link = RTEMS_CONTAINER_OF( node, Thread_queue_Link, Path_node );
    178178
    179     if ( link->Queue_context.Wait.queue_lock != NULL ) {
     179    if ( link->Queue_context.Wait.queue != NULL ) {
    180180      _Thread_queue_Link_remove( link );
    181181    }
     
    214214
    215215  _Chain_Initialize_empty( &path->Links );
     216
     217  owner = queue->owner;
     218
     219  if ( owner == NULL ) {
     220    return true;
     221  }
     222
     223  if ( owner == the_thread ) {
     224    return false;
     225  }
     226
    216227  _Chain_Initialize_node( &path->Start.Path_node );
    217228  _Thread_queue_Context_initialize( &path->Start.Queue_context );
    218 
    219   owner = queue->owner;
    220 
    221   if ( owner == NULL ) {
    222     return true;
    223   }
    224 
    225   if ( owner == the_thread ) {
    226     return false;
    227   }
    228 
    229229  link = &path->Start;
    230230
     
    240240    target = owner->Wait.queue;
    241241    link->Queue_context.Wait.queue = target;
    242     link->Queue_context.Wait.operations = owner->Wait.operations;
    243242
    244243    if ( target != NULL ) {
    245244      if ( _Thread_queue_Link_add( link, queue, target ) ) {
    246         link->Queue_context.Wait.queue_lock = &target->Lock;
    247         _Chain_Append_unprotected(
     245        _Thread_queue_Gate_add(
    248246          &owner->Wait.Lock.Pending_requests,
    249           &link->Queue_context.Wait.Gate.Node
     247          &link->Queue_context.Wait.Gate
    250248        );
    251249        _Thread_Wait_release_default_critical(
     
    253251          &link->Queue_context.Lock_context
    254252        );
    255         _Thread_Wait_acquire_queue_critical(
    256           &target->Lock,
    257           &link->Queue_context
    258         );
     253        _Thread_Wait_acquire_queue_critical( target, &link->Queue_context );
    259254
    260255        if ( link->Queue_context.Wait.queue == NULL ) {
     256          _Thread_queue_Link_remove( link );
     257          _Thread_Wait_release_queue_critical( target, &link->Queue_context );
     258          _Thread_Wait_acquire_default_critical(
     259            owner,
     260            &link->Queue_context.Lock_context
     261          );
     262          _Thread_Wait_remove_request_locked( owner, &link->Queue_context );
     263          _Assert( owner->Wait.queue == NULL );
    261264          return true;
    262265        }
    263266      } else {
    264         link->Queue_context.Wait.queue_lock = NULL;
     267        link->Queue_context.Wait.queue = NULL;
    265268        _Thread_queue_Path_release( path );
    266269        return false;
    267270      }
    268271    } else {
    269       link->Queue_context.Wait.queue_lock = NULL;
    270272      return true;
    271273    }
     
    331333    _Thread_Wait_restore_default( the_thread );
    332334    _Thread_queue_Queue_release( queue, &queue_context->Lock_context );
     335    _Thread_Wait_tranquilize( the_thread );
    333336    ( *queue_context->deadlock_callout )( the_thread );
    334337    return;
     
    505508void _Thread_queue_Extract( Thread_Control *the_thread )
    506509{
    507   Thread_queue_Context queue_context;
     510  Thread_queue_Context  queue_context;
     511  Thread_queue_Queue   *queue;
    508512
    509513  _Thread_queue_Context_initialize( &queue_context );
    510514  _Thread_Wait_acquire( the_thread, &queue_context );
    511515
    512   if (
    513     _Thread_queue_Context_get_queue( &queue_context, the_thread ) != NULL
    514   ) {
     516  queue = the_thread->Wait.queue;
     517
     518  if ( queue != NULL ) {
    515519    bool unblock;
    516520
     
    521525    );
    522526    unblock = _Thread_queue_Extract_locked(
    523       _Thread_queue_Context_get_queue( &queue_context, the_thread ),
    524       _Thread_queue_Context_get_operations( &queue_context, the_thread ),
     527      queue,
     528      the_thread->Wait.operations,
    525529      the_thread,
    526530      &queue_context.Lock_context
     
    528532    _Thread_queue_Unblock_critical(
    529533      unblock,
    530       _Thread_queue_Context_get_queue( &queue_context, the_thread ),
     534      queue,
    531535      the_thread,
    532536      &queue_context.Lock_context
  • cpukit/score/src/threadqops.c

    r3b3552bf rff2e6c64  
    2323#include <rtems/score/schedulerimpl.h>
    2424
    25 static void _Thread_queue_Default_priority_change(
    26   Thread_Control     *the_thread,
    27   Priority_Control    new_priority,
    28   bool                prepend_it,
    29   Thread_queue_Queue *queue
     25static void _Thread_queue_Do_nothing_priority_change(
     26  Thread_queue_Queue *queue,
     27  Thread_Control     *the_thread,
     28  Priority_Control    new_priority
    3029)
    3130{
    3231  (void) queue;
    33 
    34   _Scheduler_Thread_set_priority( the_thread, new_priority, prepend_it );
     32  (void) the_thread;
     33  (void) new_priority;
    3534}
    3635
    3736static void _Thread_queue_Do_nothing_extract(
    3837  Thread_queue_Queue *queue,
    39   Thread_Control    *the_thread
    40 )
    41 {
    42   /* Do nothing */
    43 }
    44 
    45 #if defined(RTEMS_SMP)
    46 static void _Thread_queue_Stale_queue_priority_change(
    47   Thread_Control     *the_thread,
    48   Priority_Control    new_priority,
    49   bool                prepend_it,
    50   Thread_queue_Queue *queue
    51 )
    52 {
    53   ISR_lock_Context lock_context;
    54 
     38  Thread_Control     *the_thread
     39)
     40{
    5541  (void) queue;
    56 
    57   /*
    58    * This operation is used to change the priority in case we have a thread
    59    * queue context with a stale thread queue.  We own the thread queue lock of
    60    * the former thread queue.  In addition, we need the thread wait default
    61    * lock, see _Thread_Wait_restore_default().
    62    */
    63 
    64   _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
    65   _Scheduler_Thread_set_priority( the_thread, new_priority, prepend_it );
    66   _Thread_Wait_release_default_critical( the_thread, &lock_context );
    67 }
    68 #endif
     42  (void) the_thread;
     43}
    6944
    7045static Thread_queue_Heads *_Thread_queue_Queue_enqueue(
     
    217192
    218193static void _Thread_queue_Priority_priority_change(
    219   Thread_Control     *the_thread,
    220   Priority_Control    new_priority,
    221   bool                prepend_it,
    222   Thread_queue_Queue *queue
     194  Thread_queue_Queue *queue,
     195  Thread_Control     *the_thread,
     196  Priority_Control    new_priority
    223197)
    224198{
     
    227201
    228202  _Assert( heads != NULL );
    229 
    230   _Scheduler_Thread_set_priority( the_thread, new_priority, prepend_it );
    231203
    232204  priority_queue = _Thread_queue_Priority_queue( heads, the_thread );
     
    390362    _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
    391363
    392     _Thread_queue_Context_priority_change(
    393       &path->Start.Queue_context,
     364    _Scheduler_Thread_set_priority( owner, priority, false );
     365
     366    ( *owner->Wait.operations->priority_change )(
     367      owner->Wait.queue,
    394368      owner,
    395       priority,
    396       false
     369      priority
    397370    );
    398371  } else {
     
    425398
    426399const Thread_queue_Operations _Thread_queue_Operations_default = {
    427   .priority_change = _Thread_queue_Default_priority_change,
     400  .priority_change = _Thread_queue_Do_nothing_priority_change,
    428401  .extract = _Thread_queue_Do_nothing_extract
    429402  /*
     
    435408
    436409const Thread_queue_Operations _Thread_queue_Operations_FIFO = {
    437   .priority_change = _Thread_queue_Default_priority_change,
     410  .priority_change = _Thread_queue_Do_nothing_priority_change,
    438411  .enqueue = _Thread_queue_FIFO_enqueue,
    439412  .extract = _Thread_queue_FIFO_extract,
     
    454427  .first = _Thread_queue_Priority_first
    455428};
    456 
    457 #if defined(RTEMS_SMP)
    458 const Thread_queue_Operations _Thread_queue_Operations_stale_queue = {
    459   .priority_change = _Thread_queue_Stale_queue_priority_change,
    460   .extract = _Thread_queue_Do_nothing_extract
    461 };
    462 #endif
Note: See TracChangeset for help on using the changeset viewer.