Changeset 3a58dc8 in rtems


Ignore:
Timestamp:
Jul 5, 2016, 11:37:10 AM (3 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
1fcac5a
Parents:
ac8402dd
git-author:
Sebastian Huber <sebastian.huber@…> (07/05/16 11:37:10)
git-committer:
Sebastian Huber <sebastian.huber@…> (07/27/16 08:55:30)
Message:

score: Priority inherit thread queue operations

Move the priority change due to priority interitance to the thread queue
enqueue operation to simplify the locking on SMP configurations.

Update #2412.
Update #2556.
Update #2765.

Location:
cpukit/score
Files:
9 edited

Legend:

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

    rac8402dd r3a58dc8  
    3636
    3737#define CORE_MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
     38
     39#define CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS \
     40  &_Thread_queue_Operations_priority_inherit
    3841
    3942RTEMS_INLINE_ROUTINE void _CORE_mutex_Initialize(
  • cpukit/score/include/rtems/score/threadimpl.h

    rac8402dd r3a58dc8  
    511511  Priority_Control  new_priority
    512512);
    513 
    514 /**
    515  * @brief Inherit the priority of a thread.
    516  *
    517  * It changes the current priority of the inheritor thread to the current priority
    518  * of the ancestor thread if it is higher than the current priority of the inheritor
    519  * thread.  In this case the inheritor thread is appended to its new priority group
    520  * in its scheduler instance.
    521  *
    522  * On SMP configurations, the priority is changed to PRIORITY_PSEUDO_ISR in
    523  * case the own schedulers of the inheritor and ancestor thread differ (priority
    524  * boosting).
    525  *
    526  * @param[in] inheritor The thread to inherit the priority.
    527  * @param[in] ancestor The thread to bequeath its priority to the inheritor
    528  *   thread.
    529  */
    530 #if defined(RTEMS_SMP)
    531 void _Thread_Inherit_priority(
    532   Thread_Control *inheritor,
    533   Thread_Control *ancestor
    534 );
    535 #else
    536 RTEMS_INLINE_ROUTINE void _Thread_Inherit_priority(
    537   Thread_Control *inheritor,
    538   Thread_Control *ancestor
    539 )
    540 {
    541   _Thread_Raise_priority( inheritor, ancestor->current_priority );
    542 }
    543 #endif
    544513
    545514/**
  • cpukit/score/include/rtems/score/threadq.h

    rac8402dd r3a58dc8  
    4343
    4444typedef struct _Thread_Control Thread_Control;
     45
     46typedef struct Thread_queue_Path Thread_queue_Path;
    4547
    4648#if defined(RTEMS_MULTIPROCESSING)
     
    240242 * @brief Thread queue enqueue operation.
    241243 *
     244 * A potential thread to update the priority due to priority inheritance is
     245 * returned via the thread queue path.  This thread is handed over to
     246 * _Thread_Update_priority().
     247 *
    242248 * @param[in] queue The actual thread queue.
    243249 * @param[in] the_thread The thread to enqueue on the queue.
     
    247253typedef void ( *Thread_queue_Enqueue_operation )(
    248254  Thread_queue_Queue *queue,
    249   Thread_Control     *the_thread
     255  Thread_Control     *the_thread,
     256  Thread_queue_Path  *path
    250257);
    251258
  • cpukit/score/include/rtems/score/threadqimpl.h

    rac8402dd r3a58dc8  
    3535 */
    3636/**@{*/
     37
     38/**
     39 * @brief Representation of a thread queue path from a start thread queue to
     40 * the terminal thread queue.
     41 *
     42 * The start thread queue is determined by the object on which a thread intends
     43 * to block.  The terminal thread queue is the thread queue reachable via
     44 * thread queue links those owner is not blocked on a thread queue.  The thread
     45 * queue links are determined by the thread queue owner and thread wait queue
     46 * relationships.
     47 */
     48struct Thread_queue_Path {
     49  /**
     50   * @brief A potential thread to update the priority via
     51   * _Thread_Update_priority().
     52   *
     53   * This thread is determined by thread queues which support priority
     54   * inheritance.
     55   */
     56  Thread_Control *update_priority;
     57};
    3758
    3859/**
     
    889910extern const Thread_queue_Operations _Thread_queue_Operations_priority;
    890911
     912extern const Thread_queue_Operations _Thread_queue_Operations_priority_inherit;
     913
    891914/**@}*/
    892915
  • cpukit/score/src/coremutexseize.c

    rac8402dd r3a58dc8  
    5555#endif
    5656
    57   _Thread_Inherit_priority( owner, executing );
    58 
    5957#if defined(RTEMS_SMP)
    6058  _Thread_queue_Context_set_expected_level( queue_context, 1 );
     
    6765  _Thread_queue_Enqueue_critical(
    6866    &the_mutex->Wait_queue.Queue,
    69     CORE_MUTEX_TQ_OPERATIONS,
     67    CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS,
    7068    executing,
    7169    STATES_WAITING_FOR_MUTEX,
  • cpukit/score/src/mutex.c

    rac8402dd r3a58dc8  
    2727#include <rtems/score/todimpl.h>
    2828
    29 #define MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
     29#define MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority_inherit
    3030
    3131typedef struct {
     
    108108)
    109109{
    110   _Thread_Inherit_priority( owner, executing );
    111110  _Thread_queue_Context_set_expected_level( queue_context, 1 );
    112111  _Thread_queue_Enqueue_critical(
  • cpukit/score/src/threadchangepriority.c

    rac8402dd r3a58dc8  
    143143}
    144144
    145 #if defined(RTEMS_SMP)
    146 static bool _Thread_Inherit_priority_filter(
    147   Thread_Control   *inheritor,
    148   Priority_Control *new_priority,
    149   void             *arg
    150 )
    151 {
    152   Thread_Control *ancestor = arg;
    153 
    154   if ( _Scheduler_Get_own( inheritor ) == _Scheduler_Get_own( ancestor ) ) {
    155     *new_priority = ancestor->current_priority;
    156   }
    157 
    158   return _Thread_Priority_less_than(
    159     inheritor->current_priority,
    160     *new_priority
    161   );
    162 }
    163 
    164 void _Thread_Inherit_priority(
    165   Thread_Control *inheritor,
    166   Thread_Control *ancestor
    167 )
    168 {
    169   _Thread_Change_priority(
    170     inheritor,
    171     PRIORITY_PSEUDO_ISR,
    172     ancestor,
    173     _Thread_Inherit_priority_filter,
    174     false
    175   );
    176 }
    177 #endif
    178 
    179145static bool _Thread_Restore_priority_filter(
    180146  Thread_Control   *the_thread,
  • cpukit/score/src/threadqenqueue.c

    rac8402dd r3a58dc8  
    4343)
    4444{
    45   Per_CPU_Control *cpu_self;
    46   bool             success;
     45  Thread_queue_Path  path;
     46  Per_CPU_Control   *cpu_self;
     47  bool               success;
    4748
    4849#if defined(RTEMS_MULTIPROCESSING)
     
    5859  _Thread_Wait_set_operations( the_thread, operations );
    5960
    60   ( *operations->enqueue )( queue, the_thread );
     61  ( *operations->enqueue )( queue, the_thread, &path );
    6162
    6263  _Thread_Wait_flags_set( the_thread, THREAD_QUEUE_INTEND_TO_BLOCK );
     
    125126  }
    126127
     128  _Thread_Update_priority( path.update_priority );
    127129  _Thread_Dispatch_enable( cpu_self );
    128130}
  • cpukit/score/src/threadqops.c

    rac8402dd r3a58dc8  
    4040}
    4141
    42 static void _Thread_queue_Queue_enqueue(
     42static Thread_queue_Heads *_Thread_queue_Queue_enqueue(
    4343  Thread_queue_Queue *queue,
    4444  Thread_Control     *the_thread,
     
    6363
    6464  ( *enqueue )( heads, the_thread );
     65
     66  return heads;
    6567}
    6668
     
    117119static void _Thread_queue_FIFO_enqueue(
    118120  Thread_queue_Queue *queue,
    119   Thread_Control     *the_thread
    120 )
    121 {
     121  Thread_Control     *the_thread,
     122  Thread_queue_Path  *path
     123)
     124{
     125  path->update_priority = NULL;
     126
    122127  _Thread_queue_Queue_enqueue(
    123128    queue,
     
    267272static void _Thread_queue_Priority_enqueue(
    268273  Thread_queue_Queue *queue,
    269   Thread_Control     *the_thread
    270 )
    271 {
     274  Thread_Control     *the_thread,
     275  Thread_queue_Path  *path
     276)
     277{
     278  path->update_priority = NULL;
     279
    272280  _Thread_queue_Queue_enqueue(
    273281    queue,
     
    309317
    310318  return THREAD_RBTREE_NODE_TO_THREAD( first );
     319}
     320
     321static void _Thread_queue_Priority_inherit_enqueue(
     322  Thread_queue_Queue *queue,
     323  Thread_Control     *the_thread,
     324  Thread_queue_Path  *path
     325)
     326{
     327  Thread_queue_Heads *heads;
     328  Thread_Control     *owner;
     329  Priority_Control    priority;
     330
     331  heads = _Thread_queue_Queue_enqueue(
     332    queue,
     333    the_thread,
     334    _Thread_queue_Priority_do_initialize,
     335    _Thread_queue_Priority_do_enqueue
     336  );
     337
     338  owner = queue->owner;
     339
     340#if defined(RTEMS_SMP)
     341  if ( _Chain_Has_only_one_node( &heads->Heads.Fifo ) ) {
     342    priority = the_thread->current_priority;
     343  } else {
     344    priority = _Scheduler_Map_priority(
     345      _Scheduler_Get_own( the_thread ),
     346      PRIORITY_PSEUDO_ISR
     347    );
     348  }
     349#else
     350  (void) heads;
     351
     352  priority = the_thread->current_priority;
     353#endif
     354
     355  if ( priority < owner->current_priority ) {
     356    Scheduler_Node *own_node;
     357
     358    path->update_priority = owner;
     359
     360    owner->priority_restore_hint = true;
     361    _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
     362
     363    own_node = _Scheduler_Thread_get_own_node( owner );
     364    _Scheduler_Node_set_priority( own_node, priority, false );
     365
     366    owner->current_priority = priority;
     367
     368    ( *owner->Wait.operations->priority_change )(
     369      owner,
     370      priority,
     371      owner->Wait.queue
     372    );
     373  } else {
     374    path->update_priority = NULL;
     375  }
    311376}
    312377
     
    360425  .first = _Thread_queue_Priority_first
    361426};
     427
     428const Thread_queue_Operations _Thread_queue_Operations_priority_inherit = {
     429  .priority_change = _Thread_queue_Priority_priority_change,
     430  .enqueue = _Thread_queue_Priority_inherit_enqueue,
     431  .extract = _Thread_queue_Priority_extract,
     432  .first = _Thread_queue_Priority_first
     433};
Note: See TracChangeset for help on using the changeset viewer.