Changeset 33e250c9 in rtems


Ignore:
Timestamp:
May 27, 2016, 1:41:41 PM (3 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
0b713f89
Parents:
5a598ac
git-author:
Sebastian Huber <sebastian.huber@…> (05/27/16 13:41:41)
git-committer:
Sebastian Huber <sebastian.huber@…> (05/30/16 14:16:23)
Message:

score: Rework CORE priority ceiling mutex

Rework seize and surrender methods to use CORE_ceiling_mutex_Control.
This eliminates CORE_mutex_Disciplines.

Location:
cpukit
Files:
18 edited

Legend:

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

    r5a598ac r33e250c9  
    4747
    4848  *prioceiling = _POSIX_Priority_From_core(
    49     the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling
     49    the_mutex->Mutex.priority_ceiling
    5050  );
    5151
  • cpukit/posix/src/mutexinit.c

    r5a598ac r33e250c9  
    120120  the_mutex->is_recursive = ( the_attr->type == PTHREAD_MUTEX_RECURSIVE );
    121121
    122   if ( protocol == POSIX_MUTEX_NO_PROTOCOL ) {
     122  if ( protocol == POSIX_MUTEX_PRIORITY_CEILING ) {
     123    _CORE_ceiling_mutex_Initialize(
     124      &the_mutex->Mutex,
     125      _POSIX_Priority_To_core( the_attr->prio_ceiling )
     126    );
     127  } else if ( protocol == POSIX_MUTEX_NO_PROTOCOL ) {
    123128    _CORE_recursive_mutex_Initialize(
    124129      &the_mutex->Mutex.Recursive
     
    131136    } else {
    132137      the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
    133     }
    134 
    135     the_mutex_attr.priority_ceiling =
    136       _POSIX_Priority_To_core( the_attr->prio_ceiling );
    137 
    138     if ( protocol == POSIX_MUTEX_PRIORITY_CEILING ) {
    139       the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
    140     } else {
    141       the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
    142138    }
    143139
  • cpukit/posix/src/mutexlocksupp.c

    r5a598ac r33e250c9  
    6666
    6767  switch ( the_mutex->protocol ) {
     68    case POSIX_MUTEX_PRIORITY_CEILING:
     69      status = _CORE_ceiling_mutex_Seize(
     70        &the_mutex->Mutex,
     71        executing,
     72        wait,
     73        timeout,
     74        _POSIX_Mutex_Lock_nested,
     75        &queue_context
     76      );
     77      break;
    6878    case POSIX_MUTEX_NO_PROTOCOL:
    6979      status = _CORE_recursive_mutex_Seize_no_protocol(
     
    7888      break;
    7989    default:
     90      _Assert( the_mutex->protocol == POSIX_MUTEX_PRIORITY_INHERIT );
    8091      status = _CORE_mutex_Seize(
    8192        &the_mutex->Mutex.Recursive.Mutex,
  • cpukit/posix/src/mutexsetprioceiling.c

    r5a598ac r33e250c9  
    5858
    5959  *old_ceiling = _POSIX_Priority_From_core(
    60     the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling
     60    the_mutex->Mutex.priority_ceiling
    6161  );
    62   the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling =
    63     the_priority;
     62  the_mutex->Mutex.priority_ceiling = the_priority;
    6463
    6564  error = pthread_mutex_unlock( mutex );
  • cpukit/posix/src/mutexunlock.c

    r5a598ac r33e250c9  
    4646
    4747  switch ( the_mutex->protocol ) {
     48    case POSIX_MUTEX_PRIORITY_CEILING:
     49      status = _CORE_ceiling_mutex_Surrender(
     50        &the_mutex->Mutex,
     51        executing,
     52        &queue_context
     53      );
     54      break;
    4855    case POSIX_MUTEX_NO_PROTOCOL:
    4956      status = _CORE_recursive_mutex_Surrender_no_protocol(
     
    5562      break;
    5663    default:
     64      _Assert( the_mutex->protocol == POSIX_MUTEX_PRIORITY_INHERIT );
    5765      status = _CORE_mutex_Surrender(
    5866        &the_mutex->Mutex.Recursive.Mutex,
  • cpukit/rtems/include/rtems/rtems/semimpl.h

    r5a598ac r33e250c9  
    3434typedef enum {
    3535  SEMAPHORE_VARIANT_MUTEX,
     36  SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING,
    3637  SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL,
    3738  SEMAPHORE_VARIANT_SIMPLE_BINARY,
  • cpukit/rtems/src/semcreate.c

    r5a598ac r33e250c9  
    137137#endif
    138138
     139  priority_ceiling = _RTEMS_tasks_Priority_to_Core( priority_ceiling );
    139140  the_semaphore->attribute_set = attribute_set;
    140141  executing = _Thread_Get_executing();
     
    170171    );
    171172#endif
    172   } else if (
    173     !_Attributes_Is_inherit_priority( attribute_set )
    174       && !_Attributes_Is_priority_ceiling( attribute_set )
    175   ) {
     173  } else if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
     174    _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
     175    the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING;
     176    _CORE_ceiling_mutex_Initialize(
     177      &the_semaphore->Core_control.Mutex,
     178      priority_ceiling
     179    );
     180
     181    if ( count == 0 ) {
     182      Thread_queue_Context queue_context;
     183
     184      _Thread_queue_Context_initialize( &queue_context );
     185      _ISR_lock_ISR_disable( &queue_context.Lock_context );
     186      _CORE_mutex_Acquire_critical(
     187        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
     188        &queue_context
     189      );
     190      status = _CORE_ceiling_mutex_Set_owner(
     191        &the_semaphore->Core_control.Mutex,
     192        executing,
     193        &queue_context
     194      );
     195    } else {
     196      status = STATUS_SUCCESSFUL;
     197    }
     198  } else if ( !_Attributes_Is_inherit_priority( attribute_set ) ) {
    176199    _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
    177200    the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL;
     
    190213  } else {
    191214    _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
     215    _Assert( _Attributes_Is_inherit_priority( attribute_set ) );
    192216    the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX;
    193217
    194     the_mutex_attr.priority_ceiling =
    195       _RTEMS_tasks_Priority_to_Core( priority_ceiling );
    196218    the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
    197 
    198     if ( _Attributes_Is_inherit_priority( attribute_set ) ) {
    199       the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
    200     } else {
    201       _Assert( _Attributes_Is_priority_ceiling( attribute_set ) );
    202       the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
    203     }
    204219
    205220    status = _CORE_mutex_Initialize(
  • cpukit/rtems/src/semdelete.c

    r5a598ac r33e250c9  
    5252  switch ( the_semaphore->variant ) {
    5353    case SEMAPHORE_VARIANT_MUTEX:
     54    case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
    5455    case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
    5556      if (
     
    9899      _Assert(
    99100        the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
     101          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING
    100102          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
    101103          || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
  • cpukit/rtems/src/semflush.c

    r5a598ac r33e250c9  
    5959      _Assert(
    6060        the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
     61          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING
    6162          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
    6263          || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
  • cpukit/rtems/src/semobtain.c

    r5a598ac r33e250c9  
    9191      );
    9292      break;
     93    case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
     94      status = _CORE_ceiling_mutex_Seize(
     95        &the_semaphore->Core_control.Mutex,
     96        executing,
     97        wait,
     98        timeout,
     99        _CORE_recursive_mutex_Seize_nested,
     100        &queue_context
     101      );
     102      break;
    93103    case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
    94104      status = _CORE_recursive_mutex_Seize_no_protocol(
  • cpukit/rtems/src/semrelease.c

    r5a598ac r33e250c9  
    2929  Semaphore_Control    *the_semaphore;
    3030  Thread_queue_Context  queue_context;
     31  Thread_Control       *executing;
    3132  Status_Control        status;
    3233
     
    4142  }
    4243
     44  executing = _Thread_Executing;
     45
    4346  _Thread_queue_Context_set_MP_callout(
    4447    &queue_context,
     
    5154      status = _MRSP_Surrender(
    5255        &the_semaphore->Core_control.mrsp,
    53         _Thread_Executing,
     56        executing,
    5457        &queue_context
    5558      );
     
    5962      status = _CORE_mutex_Surrender(
    6063        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
     64        &queue_context
     65      );
     66      break;
     67    case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
     68      status = _CORE_ceiling_mutex_Surrender(
     69        &the_semaphore->Core_control.Mutex,
     70        executing,
    6171        &queue_context
    6272      );
  • cpukit/rtems/src/semsetpriority.c

    r5a598ac r33e250c9  
    1818
    1919#include <rtems/rtems/semimpl.h>
    20 #include <rtems/rtems/attrimpl.h>
    2120#include <rtems/rtems/tasksimpl.h>
    2221#include <rtems/score/schedulerimpl.h>
     
    3029)
    3130{
    32   rtems_status_code   sc;
    33   rtems_attribute     attribute_set = the_semaphore->attribute_set;
    34   rtems_task_priority old_priority;
     31  rtems_status_code    sc;
     32  rtems_task_priority  old_priority;
     33#if defined(RTEMS_SMP)
     34  MRSP_Control        *mrsp;
     35  uint32_t             scheduler_index;
     36#endif
    3537
    3638  new_priority = _RTEMS_tasks_Priority_to_Core( new_priority );
    3739
     40  switch ( the_semaphore->variant ) {
     41    case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
     42      _CORE_mutex_Acquire_critical(
     43        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
     44        queue_context
     45      );
     46
     47      old_priority = the_semaphore->Core_control.Mutex.priority_ceiling;
     48
     49      if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
     50        the_semaphore->Core_control.Mutex.priority_ceiling = new_priority;
     51      }
     52
     53      _CORE_mutex_Release(
     54        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
     55        queue_context
     56      );
     57      sc = RTEMS_SUCCESSFUL;
     58      break;
    3859#if defined(RTEMS_SMP)
    39   if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
    40     MRSP_Control *mrsp = &the_semaphore->Core_control.mrsp;
    41     uint32_t scheduler_index = _Scheduler_Get_index_by_id( scheduler_id );
     60    case SEMAPHORE_VARIANT_MRSP:
     61      mrsp = &the_semaphore->Core_control.mrsp;
     62      scheduler_index = _Scheduler_Get_index_by_id( scheduler_id );
    4263
    43     _MRSP_Acquire_critical( mrsp, queue_context );
     64      _MRSP_Acquire_critical( mrsp, queue_context );
    4465
    45     old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index );
     66      old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index );
    4667
    47     if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
    48       _MRSP_Set_ceiling_priority( mrsp, scheduler_index, new_priority );
    49     }
     68      if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
     69        _MRSP_Set_ceiling_priority( mrsp, scheduler_index, new_priority );
     70      }
    5071
    51     _MRSP_Release( mrsp, queue_context );
    52 
    53     sc = RTEMS_SUCCESSFUL;
    54   } else
     72      _MRSP_Release( mrsp, queue_context );
     73      sc = RTEMS_SUCCESSFUL;
     74      break;
    5575#endif
    56   if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
    57     CORE_mutex_Control *mutex;
    58 
    59     mutex = &the_semaphore->Core_control.Mutex.Recursive.Mutex;
    60     _CORE_mutex_Acquire_critical( mutex, queue_context );
    61 
    62     old_priority = mutex->Attributes.priority_ceiling;
    63 
    64     if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
    65       mutex->Attributes.priority_ceiling = new_priority;
    66     }
    67 
    68     _CORE_mutex_Release( mutex, queue_context );
    69 
    70     sc = RTEMS_SUCCESSFUL;
    71   } else {
    72     _ISR_lock_ISR_enable( &queue_context->Lock_context );
    73 
    74     old_priority = 0;
    75 
    76     sc = RTEMS_NOT_DEFINED;
     76    default:
     77      _Assert(
     78        the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
     79          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
     80          || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
     81          || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
     82      );
     83      _ISR_lock_ISR_enable( &queue_context->Lock_context );
     84      old_priority = 0;
     85      sc = RTEMS_NOT_DEFINED;
     86      break;
    7787  }
    7888
  • cpukit/score/include/rtems/score/coremutex.h

    r5a598ac r33e250c9  
    4343
    4444/**
    45  *  @brief The blocking disciplines for a mutex.
    46  *
    47  *  This enumerated type defines the blocking disciplines for a mutex.
    48  */
    49 typedef enum {
    50   /** This specifies that threads will wait for the mutex in priority order.
    51    *  Additionally, the Priority Inheritance Protocol will be in effect.
    52    */
    53   CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT,
    54   /** This specifies that threads will wait for the mutex in priority order.
    55    *  Additionally, the Priority Ceiling Protocol will be in effect.
    56    */
    57   CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
    58 }   CORE_mutex_Disciplines;
    59 
    60 /**
    6145 *  @brief The possible behaviors for lock nesting.
    6246 *
     
    9781   */
    9882  CORE_mutex_Nesting_behaviors lock_nesting_behavior;
    99   /** This field indicates whether threads waiting on the mutex block in
    100    *  FIFO or priority order.
    101    */
    102   CORE_mutex_Disciplines       discipline;
    103   /** This field contains the ceiling priority to be used if that protocol
    104    *  is selected.
    105    */
    106   Priority_Control             priority_ceiling;
    10783}   CORE_mutex_Attributes;
    10884
  • cpukit/score/include/rtems/score/coremuteximpl.h

    r5a598ac r33e250c9  
    129129
    130130/**
    131  * @brief Does mutex use priority inheritance.
    132  *
    133  * This routine returns true if the mutex's wait discipline is
    134  * INHERIT_PRIORITY and false otherwise.
    135  *
    136  * @param[in] the_attribute is the attribute set of the mutex.
    137  *
    138  * @retval true The mutex is using priority inheritance.
    139  * @retval false The mutex is not using priority inheritance.
    140  */
    141 RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority(
    142   const CORE_mutex_Attributes *the_attribute
    143 )
    144 {
    145   return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
    146 }
    147 
    148 /**
    149  * @brief Does mutex use priority ceiling.
    150  *
    151  * This routine returns true if the mutex's wait discipline is
    152  * PRIORITY_CEILING and false otherwise.
    153  *
    154  * @param[in] the_attribute is the attribute set of the mutex.
    155  *
    156  * @retval true The mutex is using priority ceiling.
    157  * @retval false The mutex is not using priority ceiling.
    158  */
    159 RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling(
    160   const CORE_mutex_Attributes *the_attribute
    161 )
    162 {
    163   return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
    164 }
    165 
    166 /**
    167131 *  @brief Attempt to receive a unit from the_mutex.
    168132 *
     
    192156    ++executing->resource_count;
    193157
    194     if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
    195       _CORE_mutex_Release( the_mutex, queue_context );
    196     } else {
    197       /*
    198        * must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
    199        *
    200        * we possibly bump the priority of the current holder -- which
    201        * happens to be _Thread_Executing.
    202        */
    203       Priority_Control  ceiling;
    204       Priority_Control  current;
    205 
    206       ceiling = the_mutex->Attributes.priority_ceiling;
    207       current = executing->current_priority;
    208       if ( current == ceiling ) {
    209         _CORE_mutex_Release( the_mutex, queue_context );
    210       } else if ( current > ceiling ) {
    211         Per_CPU_Control *cpu_self;
    212 
    213         cpu_self = _Thread_Dispatch_disable_critical(
    214           &queue_context->Lock_context
    215         );
    216         _CORE_mutex_Release( the_mutex, queue_context );
    217         _Thread_Raise_priority( executing, ceiling );
    218         _Thread_Dispatch_enable( cpu_self );
    219       } else /* if ( current < ceiling ) */ {
    220         the_mutex->holder = NULL;
    221         the_mutex->nest_count = 0;     /* undo locking above */
    222         executing->resource_count--;   /* undo locking above */
    223         _CORE_mutex_Release( the_mutex, queue_context );
    224         return STATUS_MUTEX_CEILING_VIOLATED;
    225       }
    226     }
    227 
     158    _CORE_mutex_Release( the_mutex, queue_context );
    228159    return STATUS_SUCCESSFUL;
    229160  }
     
    346277}
    347278
     279RTEMS_INLINE_ROUTINE void _CORE_mutex_Restore_priority(
     280  Thread_Control *executing
     281)
     282{
     283  /*
     284   *  Whether or not someone is waiting for the mutex, an
     285   *  inherited priority must be lowered if this is the last
     286   *  mutex (i.e. resource) this task has.
     287   */
     288  if ( !_Thread_Owns_resources( executing ) ) {
     289    /*
     290     * Ensure that the executing resource count is visible to all other
     291     * processors and that we read the latest priority restore hint.
     292     */
     293    _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
     294
     295    if ( executing->priority_restore_hint ) {
     296      Per_CPU_Control *cpu_self;
     297
     298      cpu_self = _Thread_Dispatch_disable();
     299      _Thread_Restore_priority( executing );
     300      _Thread_Dispatch_enable( cpu_self );
     301    }
     302  }
     303}
     304
    348305RTEMS_INLINE_ROUTINE void _CORE_recursive_mutex_Initialize(
    349306  CORE_recursive_mutex_Control *the_mutex
     
    480437}
    481438
     439RTEMS_INLINE_ROUTINE void _CORE_ceiling_mutex_Initialize(
     440  CORE_ceiling_mutex_Control *the_mutex,
     441  Priority_Control            priority_ceiling
     442)
     443{
     444  _CORE_recursive_mutex_Initialize( &the_mutex->Recursive );
     445  the_mutex->priority_ceiling = priority_ceiling;
     446}
     447
     448RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Set_owner(
     449  CORE_ceiling_mutex_Control *the_mutex,
     450  Thread_Control             *owner,
     451  Thread_queue_Context       *queue_context
     452)
     453{
     454  Priority_Control  priority_ceiling;
     455  Priority_Control  current_priority;
     456  Per_CPU_Control  *cpu_self;
     457
     458  priority_ceiling = the_mutex->priority_ceiling;
     459  current_priority = owner->current_priority;
     460
     461  if ( current_priority < priority_ceiling ) {
     462    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
     463    return STATUS_MUTEX_CEILING_VIOLATED;
     464  }
     465
     466  _CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, owner );
     467  ++owner->resource_count;
     468
     469  if ( current_priority == priority_ceiling ) {
     470    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
     471    return STATUS_SUCCESSFUL;
     472  }
     473
     474  cpu_self = _Thread_Dispatch_disable_critical( &queue_context->Lock_context );
     475  _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
     476  _Thread_Raise_priority( owner, priority_ceiling );
     477  _Thread_Dispatch_enable( cpu_self );
     478  return STATUS_SUCCESSFUL;
     479}
     480
     481RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Seize(
     482  CORE_ceiling_mutex_Control    *the_mutex,
     483  Thread_Control                *executing,
     484  bool                           wait,
     485  Watchdog_Interval              timeout,
     486  Status_Control              ( *nested )( CORE_recursive_mutex_Control * ),
     487  Thread_queue_Context          *queue_context
     488)
     489{
     490  Thread_Control *owner;
     491
     492  _CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
     493
     494  owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex );
     495
     496  if ( owner == NULL ) {
     497    return _CORE_ceiling_mutex_Set_owner(
     498      the_mutex,
     499      executing,
     500      queue_context
     501    );
     502  }
     503
     504  if ( owner == executing ) {
     505    Status_Control status;
     506
     507    status = ( *nested )( &the_mutex->Recursive );
     508    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
     509    return status;
     510  }
     511
     512  return _CORE_mutex_Seize_no_protocol_slow(
     513    &the_mutex->Recursive.Mutex,
     514    CORE_MUTEX_TQ_OPERATIONS,
     515    executing,
     516    wait,
     517    timeout,
     518    queue_context
     519  );
     520}
     521
     522RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Surrender(
     523  CORE_ceiling_mutex_Control *the_mutex,
     524  Thread_Control             *executing,
     525  Thread_queue_Context       *queue_context
     526)
     527{
     528  unsigned int    nest_level;
     529  Thread_Control *new_owner;
     530
     531  _CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
     532
     533  if ( !_CORE_mutex_Is_owner( &the_mutex->Recursive.Mutex, executing ) ) {
     534    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
     535    return STATUS_NOT_OWNER;
     536  }
     537
     538  nest_level = the_mutex->Recursive.nest_level;
     539
     540  if ( nest_level > 0 ) {
     541    the_mutex->Recursive.nest_level = nest_level - 1;
     542    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
     543    return STATUS_SUCCESSFUL;
     544  }
     545
     546  --executing->resource_count;
     547
     548  new_owner = _Thread_queue_First_locked(
     549    &the_mutex->Recursive.Mutex.Wait_queue,
     550    CORE_MUTEX_TQ_OPERATIONS
     551  );
     552  _CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, new_owner );
     553
     554  if ( new_owner != NULL ) {
     555    bool unblock;
     556
     557    /*
     558     * We must extract the thread now since this will restore its default
     559     * thread lock.  This is necessary to avoid a deadlock in the
     560     * _Thread_Change_priority() below due to a recursive thread queue lock
     561     * acquire.
     562     */
     563    unblock = _Thread_queue_Extract_locked(
     564      &the_mutex->Recursive.Mutex.Wait_queue.Queue,
     565      CORE_MUTEX_TQ_OPERATIONS,
     566      new_owner,
     567      queue_context
     568    );
     569
     570#if defined(RTEMS_MULTIPROCESSING)
     571    if ( _Objects_Is_local_id( new_owner->Object.id ) )
     572#endif
     573    {
     574      ++new_owner->resource_count;
     575      _Thread_Raise_priority( new_owner, the_mutex->priority_ceiling );
     576    }
     577
     578    _Thread_queue_Unblock_critical(
     579      unblock,
     580      &the_mutex->Recursive.Mutex.Wait_queue.Queue,
     581      new_owner,
     582      &queue_context->Lock_context
     583    );
     584  } else {
     585    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
     586  }
     587
     588  _CORE_mutex_Restore_priority( executing );
     589  return STATUS_SUCCESSFUL;
     590}
     591
    482592/** @} */
    483593
  • cpukit/score/src/apimutex.c

    r5a598ac r33e250c9  
    4949
    5050  CORE_mutex_Attributes attr =  {
    51     CORE_MUTEX_NESTING_ACQUIRES,
    52     CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT,
    53     0
     51    CORE_MUTEX_NESTING_ACQUIRES
    5452  };
    5553
  • cpukit/score/src/coremutex.c

    r5a598ac r33e250c9  
    4040
    4141  if ( initially_locked ) {
    42     bool              is_priority_ceiling;
    43     Priority_Control  ceiling;
    44     Per_CPU_Control  *cpu_self;
    45 
    4642    the_mutex->nest_count = 1;
    4743    the_mutex->holder     = executing;
    48 
    49     /* The mutex initialization is only protected by the allocator lock */
    50     cpu_self = _Thread_Dispatch_disable();
    51 
    52     is_priority_ceiling =
    53       _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes );
    54     ceiling = the_mutex->Attributes.priority_ceiling;
    55 
    56     /*
    57      * The test to check for a ceiling violation is a bit arbitrary.  In case
    58      * this thread is the owner of a priority inheritance mutex, then it may
    59      * get a higher priority later or anytime on SMP configurations.
    60      */
    61     if ( is_priority_ceiling && executing->current_priority < ceiling ) {
    62       /*
    63        * There is no need to undo the previous work since this error aborts
    64        * the object creation.
    65        */
    66       _Thread_Dispatch_enable( cpu_self );
    67       return STATUS_MUTEX_CEILING_VIOLATED;
    68     }
    69 
    7044    executing->resource_count++;
    71 
    72     if ( is_priority_ceiling ) {
    73       _Thread_Raise_priority( executing, ceiling );
    74     }
    75 
    76     _Thread_Dispatch_enable( cpu_self );
    7745  } else {
    7846    the_mutex->nest_count = 0;
  • cpukit/score/src/coremutexseize.c

    r5a598ac r33e250c9  
    3030)
    3131{
     32  Thread_Control *holder;
     33
    3234#if !defined(RTEMS_SMP)
    3335  /*
     
    3840#endif
    3941
    40   if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
    41     Thread_Control *holder = the_mutex->holder;
     42  holder = the_mutex->holder;
    4243
    4344#if !defined(RTEMS_SMP)
    44     /*
    45      * To enable interrupts here works only since exactly one executing thread
    46      * exists and only threads are allowed to seize and surrender mutexes with
    47      * the priority inheritance protocol.  On SMP configurations more than one
    48      * executing thread may exist, so here we must not release the lock, since
    49      * otherwise the current holder may be no longer the holder of the mutex
    50      * once we released the lock.
    51      */
    52     _CORE_mutex_Release( the_mutex, queue_context );
     45  /*
     46   * To enable interrupts here works only since exactly one executing thread
     47   * exists and only threads are allowed to seize and surrender mutexes with
     48   * the priority inheritance protocol.  On SMP configurations more than one
     49   * executing thread may exist, so here we must not release the lock, since
     50   * otherwise the current holder may be no longer the holder of the mutex
     51   * once we released the lock.
     52   */
     53  _CORE_mutex_Release( the_mutex, queue_context );
    5354#endif
    5455
    55     _Thread_Inherit_priority( holder, executing );
    56 
    57 #if !defined(RTEMS_SMP)
    58     _ISR_lock_ISR_disable( &queue_context->Lock_context );
    59     _CORE_mutex_Acquire_critical( the_mutex, queue_context );
    60 #endif
    61   }
     56  _Thread_Inherit_priority( holder, executing );
    6257
    6358#if defined(RTEMS_SMP)
    6459  _Thread_queue_Context_set_expected_level( queue_context, 1 );
    6560#else
     61  _ISR_lock_ISR_disable( &queue_context->Lock_context );
     62  _CORE_mutex_Acquire_critical( the_mutex, queue_context );
    6663  _Thread_queue_Context_set_expected_level( queue_context, 2 );
    6764#endif
  • cpukit/score/src/coremutexsurrender.c

    r5a598ac r33e250c9  
    119119#endif
    120120    {
    121       switch ( the_mutex->Attributes.discipline ) {
    122         case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
    123           the_thread->resource_count++;
    124           _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, the_thread );
    125           break;
    126         case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
    127           the_thread->resource_count++;
    128           _Thread_Raise_priority(
    129             the_thread,
    130             the_mutex->Attributes.priority_ceiling
    131           );
    132           break;
    133       }
     121      the_thread->resource_count++;
     122      _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, the_thread );
    134123    }
    135124
     
    165154  }
    166155
     156  _CORE_mutex_Restore_priority( holder );
    167157  return STATUS_SUCCESSFUL;
    168158}
Note: See TracChangeset for help on using the changeset viewer.