Changeset 5a598ac in rtems


Ignore:
Timestamp:
May 27, 2016, 6:02:03 AM (3 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
33e250c9
Parents:
bbb3c5f
git-author:
Sebastian Huber <sebastian.huber@…> (05/27/16 06:02:03)
git-committer:
Sebastian Huber <sebastian.huber@…> (05/30/16 14:16:23)
Message:

score: Add CORE mutex variants

Add CORE_recursive_mutex_Control and CORE_ceiling_mutex_Control to avoid
the run-time evaluation of attributes to figure out how a particular
mutex methods should behave. Start with the no protocol variants. This
eliminates the CORE_MUTEX_DISCIPLINES_FIFO and
CORE_MUTEX_DISCIPLINES_PRIORITY disciplines.

Location:
cpukit
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libmisc/monitor/mon-sema.c

    rbbb3c5f r5a598ac  
    2323    canonical_sema->attribute = rtems_sema->attribute_set;
    2424    canonical_sema->priority_ceiling =
    25       rtems_sema->Core_control.mutex.Attributes.priority_ceiling;
     25      rtems_sema->Core_control.Mutex.priority_ceiling;
    2626
    2727    canonical_sema->holder_id = 0;
     
    3434    else {
    3535      /* we have a binary semaphore (mutex) */
    36       Thread_Control *holder = rtems_sema->Core_control.mutex.holder;
     36      Thread_Control *holder;
    3737
     38      holder = rtems_sema->Core_control.Mutex.Recursive.Mutex.holder;
    3839      if (holder != NULL) {
    3940        canonical_sema->holder_id = holder->Object.id;
  • cpukit/libnetworking/rtems/rtems_glue.c

    rbbb3c5f r5a598ac  
    119119        nest_count =
    120120                the_networkSemaphore ?
    121                 the_networkSemaphore->Core_control.mutex.nest_count : 0;
     121                the_networkSemaphore->Core_control.Mutex.Recursive.Mutex.nest_count : 0;
    122122        for (i = 0; i < nest_count; ++i) {
    123123                rtems_bsdnet_semaphore_release();
     
    379379        _ISR_lock_ISR_disable(&queue_context.Lock_context);
    380380        status = _CORE_mutex_Seize (
    381                 &the_networkSemaphore->Core_control.mutex,
     381                &the_networkSemaphore->Core_control.Mutex.Recursive.Mutex,
    382382                _Thread_Executing,
    383383                1,              /* wait */
     
    412412        _ISR_lock_ISR_disable(&queue_context.Lock_context);
    413413        status = _CORE_mutex_Surrender (
    414                 &the_networkSemaphore->Core_control.mutex,
     414                &the_networkSemaphore->Core_control.Mutex.Recursive.Mutex,
    415415                &queue_context
    416416                );
  • cpukit/posix/include/rtems/posix/mutex.h

    rbbb3c5f r5a598ac  
    3636/**@{**/
    3737
    38 /*
    39  *  Data Structure used to manage a POSIX mutex
     38/**
     39 * @brief The POSIX mutex control.
    4040 */
     41typedef struct {
     42  /**
     43   * @brief The object control.
     44   */
     45  Objects_Control Object;
    4146
    42 typedef struct {
    43    Objects_Control     Object;
    44    CORE_mutex_Control  Mutex;
    45 }  POSIX_Mutex_Control;
     47  /**
     48   * The most general mutex variant supported by a POSIX mutex.
     49   *
     50   * The priority inheritance or no protocol variants will use only parts of
     51   * this structure.
     52   */
     53  CORE_ceiling_mutex_Control Mutex;
     54
     55  /**
     56   * @brief The protocol variant.
     57   *
     58   * @see POSIX_Mutex_Protocol.
     59   */
     60  unsigned int protocol : 2;
     61
     62  /**
     63   * @brief Indicates if this is a non-recursive or recursive mutex.
     64   */
     65  unsigned int is_recursive : 1;
     66} POSIX_Mutex_Control;
    4667
    4768/** @} */
  • cpukit/posix/include/rtems/posix/muteximpl.h

    rbbb3c5f r5a598ac  
    2929#endif
    3030
     31#define POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
     32
     33/**
     34 * @brief Supported POSIX mutex protocols.
     35 *
     36 * Must be in synchronization with POSIX_Mutex_Control::protocol.
     37 */
     38typedef enum {
     39  POSIX_MUTEX_NO_PROTOCOL,
     40  POSIX_MUTEX_PRIORITY_INHERIT,
     41  POSIX_MUTEX_PRIORITY_CEILING
     42} POSIX_Mutex_Protocol;
     43
    3144/**
    3245 *  The following defines the information control block used to manage
     
    3952 */
    4053extern pthread_mutexattr_t _POSIX_Mutex_Default_attributes;
     54
     55RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Acquire_critical(
     56  POSIX_Mutex_Control  *the_mutex,
     57  Thread_queue_Context *queue_context
     58)
     59{
     60  _CORE_mutex_Acquire_critical(
     61    &the_mutex->Mutex.Recursive.Mutex,
     62    queue_context
     63  );
     64}
     65
     66RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Release(
     67  POSIX_Mutex_Control  *the_mutex,
     68  Thread_queue_Context *queue_context
     69)
     70{
     71  _CORE_mutex_Release(
     72    &the_mutex->Mutex.Recursive.Mutex,
     73    queue_context
     74  );
     75}
    4176
    4277/**
  • cpukit/posix/src/mutexdestroy.c

    rbbb3c5f r5a598ac  
    3838
    3939  if ( the_mutex != NULL ) {
    40     _CORE_mutex_Acquire_critical( &the_mutex->Mutex, &queue_context );
     40    _POSIX_Mutex_Acquire_critical( the_mutex, &queue_context );
    4141
    4242    /*
     
    4545     */
    4646
    47     if ( !_CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
     47    if (
     48      !_CORE_mutex_Is_locked( &the_mutex->Mutex.Recursive.Mutex )
     49    ) {
    4850      _Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );
    49       _CORE_mutex_Release( &the_mutex->Mutex, &queue_context );
    50       _CORE_mutex_Destroy( &the_mutex->Mutex );
     51      _POSIX_Mutex_Release( the_mutex, &queue_context );
     52      _CORE_mutex_Destroy( &the_mutex->Mutex.Recursive.Mutex );
    5153      _POSIX_Mutex_Free( the_mutex );
    5254      eno = 0;
    5355    } else {
    54       _CORE_mutex_Release( &the_mutex->Mutex, &queue_context );
     56      _POSIX_Mutex_Release( the_mutex, &queue_context );
    5557      eno = EBUSY;
    5658    }
  • cpukit/posix/src/mutexgetprioceiling.c

    rbbb3c5f r5a598ac  
    4444  }
    4545
    46   _CORE_mutex_Acquire_critical( &the_mutex->Mutex, &queue_context );
     46  _POSIX_Mutex_Acquire_critical( the_mutex, &queue_context );
    4747
    4848  *prioceiling = _POSIX_Priority_From_core(
    49     the_mutex->Mutex.Attributes.priority_ceiling
     49    the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling
    5050  );
    5151
    52   _CORE_mutex_Release( &the_mutex->Mutex, &queue_context );
     52  _POSIX_Mutex_Release( the_mutex, &queue_context );
    5353
    5454  return 0;
  • cpukit/posix/src/mutexinit.c

    rbbb3c5f r5a598ac  
    3434)
    3535{
    36   POSIX_Mutex_Control          *the_mutex;
    37   CORE_mutex_Attributes        *the_mutex_attr;
    38   const pthread_mutexattr_t    *the_attr;
    39   CORE_mutex_Disciplines        the_discipline;
     36  POSIX_Mutex_Control       *the_mutex;
     37  const pthread_mutexattr_t *the_attr;
     38  POSIX_Mutex_Protocol       protocol;
    4039
    4140  if ( attr ) the_attr = attr;
     
    7675  switch ( the_attr->protocol ) {
    7776    case PTHREAD_PRIO_NONE:
    78       the_discipline = CORE_MUTEX_DISCIPLINES_FIFO;
     77      protocol = POSIX_MUTEX_NO_PROTOCOL;
    7978      break;
    8079    case PTHREAD_PRIO_INHERIT:
    81       the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
     80      protocol = POSIX_MUTEX_PRIORITY_INHERIT;
    8281      break;
    8382    case PTHREAD_PRIO_PROTECT:
    84       the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
     83      protocol = POSIX_MUTEX_PRIORITY_CEILING;
    8584      break;
    8685    default:
     
    118117  }
    119118
    120   the_mutex_attr = &the_mutex->Mutex.Attributes;
     119  the_mutex->protocol = protocol;
     120  the_mutex->is_recursive = ( the_attr->type == PTHREAD_MUTEX_RECURSIVE );
    121121
    122   if ( the_attr->type == PTHREAD_MUTEX_RECURSIVE )
    123     the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
    124   else
    125     the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
    126   the_mutex_attr->only_owner_release = true;
    127   the_mutex_attr->priority_ceiling =
    128     _POSIX_Priority_To_core( the_attr->prio_ceiling );
    129   the_mutex_attr->discipline = the_discipline;
     122  if ( protocol == POSIX_MUTEX_NO_PROTOCOL ) {
     123    _CORE_recursive_mutex_Initialize(
     124      &the_mutex->Mutex.Recursive
     125    );
     126  } else {
     127    CORE_mutex_Attributes the_mutex_attr;
    130128
    131   /*
    132    *  Must be initialized to unlocked.
    133    */
    134   _CORE_mutex_Initialize( &the_mutex->Mutex, NULL, the_mutex_attr, false );
     129    if ( the_attr->type == PTHREAD_MUTEX_RECURSIVE ) {
     130      the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
     131    } else {
     132      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;
     142    }
     143
     144    /*
     145     *  Must be initialized to unlocked.
     146     */
     147    _CORE_mutex_Initialize(
     148      &the_mutex->Mutex.Recursive.Mutex,
     149      NULL,
     150      &the_mutex_attr,
     151      false
     152    );
     153  }
    135154
    136155  _Objects_Open_u32( &_POSIX_Mutex_Information, &the_mutex->Object, 0 );
  • cpukit/posix/src/mutexlocksupp.c

    rbbb3c5f r5a598ac  
    2222#include <rtems/posix/posixapi.h>
    2323
    24 THREAD_QUEUE_OBJECT_ASSERT( POSIX_Mutex_Control, Mutex.Wait_queue );
     24THREAD_QUEUE_OBJECT_ASSERT(
     25  POSIX_Mutex_Control,
     26  Mutex.Recursive.Mutex.Wait_queue
     27);
     28
     29static Status_Control _POSIX_Mutex_Lock_nested(
     30  CORE_recursive_mutex_Control *the_recursive_mutex
     31)
     32{
     33  POSIX_Mutex_Control *the_mutex;
     34
     35  the_mutex = RTEMS_CONTAINER_OF(
     36    the_recursive_mutex,
     37    POSIX_Mutex_Control,
     38    Mutex.Recursive
     39  );
     40
     41  if ( the_mutex->is_recursive ) {
     42    return _CORE_recursive_mutex_Seize_nested( the_recursive_mutex );
     43  } else {
     44    return STATUS_NESTING_NOT_ALLOWED;
     45  }
     46}
    2547
    2648int _POSIX_Mutex_Lock_support(
    2749  pthread_mutex_t   *mutex,
    28   bool               blocking,
     50  bool               wait,
    2951  Watchdog_Interval  timeout
    3052)
     
    3254  POSIX_Mutex_Control  *the_mutex;
    3355  Thread_queue_Context  queue_context;
     56  Thread_Control       *executing;
    3457  Status_Control        status;
    3558
     
    4063  }
    4164
    42   status = _CORE_mutex_Seize(
    43     &the_mutex->Mutex,
    44     _Thread_Executing,
    45     blocking,
    46     timeout,
    47     &queue_context
    48   );
     65  executing = _Thread_Executing;
     66
     67  switch ( the_mutex->protocol ) {
     68    case POSIX_MUTEX_NO_PROTOCOL:
     69      status = _CORE_recursive_mutex_Seize_no_protocol(
     70        &the_mutex->Mutex.Recursive,
     71        POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS,
     72        executing,
     73        wait,
     74        timeout,
     75        _POSIX_Mutex_Lock_nested,
     76        &queue_context
     77      );
     78      break;
     79    default:
     80      status = _CORE_mutex_Seize(
     81        &the_mutex->Mutex.Recursive.Mutex,
     82        executing,
     83        wait,
     84        timeout,
     85        &queue_context
     86      );
     87      break;
     88  }
     89
    4990  return _POSIX_Get_error( status );
    5091}
  • cpukit/posix/src/mutexsetprioceiling.c

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

    rbbb3c5f r5a598ac  
    3434  POSIX_Mutex_Control  *the_mutex;
    3535  Thread_queue_Context  queue_context;
     36  Thread_Control       *executing;
    3637  Status_Control        status;
    3738
     
    4243  }
    4344
    44   status = _CORE_mutex_Surrender( &the_mutex->Mutex, &queue_context );
     45  executing = _Thread_Executing;
     46
     47  switch ( the_mutex->protocol ) {
     48    case POSIX_MUTEX_NO_PROTOCOL:
     49      status = _CORE_recursive_mutex_Surrender_no_protocol(
     50        &the_mutex->Mutex.Recursive,
     51        POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS,
     52        executing,
     53        &queue_context
     54      );
     55      break;
     56    default:
     57      status = _CORE_mutex_Surrender(
     58        &the_mutex->Mutex.Recursive.Mutex,
     59        &queue_context
     60      );
     61      break;
     62  }
     63
    4564  return _POSIX_Get_error( status );
    4665}
  • cpukit/rtems/include/rtems/rtems/sem.h

    rbbb3c5f r5a598ac  
    8484     *  API Semaphore instance.
    8585     */
    86     CORE_mutex_Control     mutex;
     86    CORE_ceiling_mutex_Control Mutex;
    8787
    8888    /**
  • cpukit/rtems/include/rtems/rtems/semimpl.h

    rbbb3c5f r5a598ac  
    2727#endif
    2828
     29/**
     30 * @brief Classic semaphore variants.
     31 *
     32 * Must be in synchronization with Semaphore_Control::variant.
     33 */
    2934typedef enum {
    3035  SEMAPHORE_VARIANT_MUTEX,
     36  SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL,
    3137  SEMAPHORE_VARIANT_SIMPLE_BINARY,
    3238  SEMAPHORE_VARIANT_COUNTING
  • cpukit/rtems/src/semcreate.c

    rbbb3c5f r5a598ac  
    6464  Semaphore_Control     *the_semaphore;
    6565  CORE_mutex_Attributes  the_mutex_attr;
     66  Thread_Control        *executing;
    6667  Status_Control         status;
    6768
     
    137138
    138139  the_semaphore->attribute_set = attribute_set;
     140  executing = _Thread_Get_executing();
    139141
    140142  if ( _Attributes_Is_priority( attribute_set ) ) {
     
    164166      &the_semaphore->Core_control.mrsp,
    165167      priority_ceiling,
    166       _Thread_Get_executing(),
     168      executing,
    167169      count != 1
    168170    );
    169171#endif
     172  } else if (
     173    !_Attributes_Is_inherit_priority( attribute_set )
     174      && !_Attributes_Is_priority_ceiling( attribute_set )
     175  ) {
     176    _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
     177    the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL;
     178    _CORE_recursive_mutex_Initialize(
     179      &the_semaphore->Core_control.Mutex.Recursive
     180    );
     181
     182    if ( count == 0 ) {
     183      _CORE_mutex_Set_owner(
     184        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
     185        executing
     186      );
     187    }
     188
     189    status = STATUS_SUCCESSFUL;
    170190  } else {
     191    _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
    171192    the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX;
    172193
    173     _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
    174 
    175     /*
    176      *  It is either simple binary semaphore or a more powerful mutex
    177      *  style binary semaphore.  This is the mutex style.
    178      */
    179     if ( _Attributes_Is_priority( attribute_set ) )
    180       the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY;
    181     else
    182       the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_FIFO;
    183 
    184     the_mutex_attr.priority_ceiling      = _RTEMS_tasks_Priority_to_Core(
    185                                              priority_ceiling
    186                                            );
     194    the_mutex_attr.priority_ceiling =
     195      _RTEMS_tasks_Priority_to_Core( priority_ceiling );
    187196    the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
    188     the_mutex_attr.only_owner_release    = false;
    189 
    190     if ( the_mutex_attr.discipline == CORE_MUTEX_DISCIPLINES_PRIORITY ) {
    191       if ( _Attributes_Is_inherit_priority( attribute_set ) ) {
    192         the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
    193         the_mutex_attr.only_owner_release = true;
    194       } else if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
    195         the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
    196         the_mutex_attr.only_owner_release = true;
    197       }
     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;
    198203    }
    199204
    200205    status = _CORE_mutex_Initialize(
    201       &the_semaphore->Core_control.mutex,
    202       _Thread_Get_executing(),
     206      &the_semaphore->Core_control.Mutex.Recursive.Mutex,
     207      executing,
    203208      &the_mutex_attr,
    204209      count != 1
  • cpukit/rtems/src/semdelete.c

    rbbb3c5f r5a598ac  
    5252  switch ( the_semaphore->variant ) {
    5353    case SEMAPHORE_VARIANT_MUTEX:
    54       if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) ) {
     54    case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
     55      if (
     56        _CORE_mutex_Is_locked(
     57          &the_semaphore->Core_control.Mutex.Recursive.Mutex
     58        )
     59      ) {
    5560        status = STATUS_RESOURCE_IN_USE;
    5661      } else {
     
    9398      _Assert(
    9499        the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
     100          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
    95101          || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
    96102          || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
  • cpukit/rtems/src/semflush.c

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

    rbbb3c5f r5a598ac  
    3030THREAD_QUEUE_OBJECT_ASSERT(
    3131  Semaphore_Control,
    32   Core_control.mutex.Wait_queue
     32  Core_control.Mutex.Recursive.Mutex.Wait_queue
    3333);
    3434
     
    8484    case SEMAPHORE_VARIANT_MUTEX:
    8585      status = _CORE_mutex_Seize(
    86         &the_semaphore->Core_control.mutex,
     86        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
    8787        executing,
    8888        wait,
    8989        timeout,
     90        &queue_context
     91      );
     92      break;
     93    case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
     94      status = _CORE_recursive_mutex_Seize_no_protocol(
     95        &the_semaphore->Core_control.Mutex.Recursive,
     96        _Semaphore_Get_operations( the_semaphore ),
     97        executing,
     98        wait,
     99        timeout,
     100        _CORE_recursive_mutex_Seize_nested,
    90101        &queue_context
    91102      );
  • cpukit/rtems/src/semrelease.c

    rbbb3c5f r5a598ac  
    5858    case SEMAPHORE_VARIANT_MUTEX:
    5959      status = _CORE_mutex_Surrender(
    60         &the_semaphore->Core_control.mutex,
     60        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
    6161        &queue_context
    6262      );
     63      break;
     64    case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
     65      _CORE_recursive_mutex_Surrender_no_protocol_classic(
     66        &the_semaphore->Core_control.Mutex.Recursive,
     67        _Semaphore_Get_operations( the_semaphore ),
     68        &queue_context
     69      );
     70      status = STATUS_SUCCESSFUL;
    6371      break;
    6472    case SEMAPHORE_VARIANT_SIMPLE_BINARY:
  • cpukit/rtems/src/semsetpriority.c

    rbbb3c5f r5a598ac  
    5555#endif
    5656  if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
    57     CORE_mutex_Control *mutex = &the_semaphore->Core_control.mutex;
     57    CORE_mutex_Control *mutex;
    5858
     59    mutex = &the_semaphore->Core_control.Mutex.Recursive.Mutex;
    5960    _CORE_mutex_Acquire_critical( mutex, queue_context );
    6061
  • cpukit/score/include/rtems/score/coremutex.h

    rbbb3c5f r5a598ac  
    4848 */
    4949typedef enum {
    50   /** This specifies that threads will wait for the mutex in FIFO order. */
    51   CORE_MUTEX_DISCIPLINES_FIFO,
    52   /** This specifies that threads will wait for the mutex in priority order.  */
    53   CORE_MUTEX_DISCIPLINES_PRIORITY,
    5450  /** This specifies that threads will wait for the mutex in priority order.
    5551   *  Additionally, the Priority Inheritance Protocol will be in effect.
     
    10197   */
    10298  CORE_mutex_Nesting_behaviors lock_nesting_behavior;
    103   /** When this field is true, then only the thread that locked the mutex
    104    *  is allowed to unlock it.
    105    */
    106   bool                         only_owner_release;
    10799  /** This field indicates whether threads waiting on the mutex block in
    108100   *  FIFO or priority order.
     
    126118  Thread_queue_Control    Wait_queue;
    127119
    128   /**
    129    * @brief The thread queue operations according to the blocking discipline.
    130    */
    131   const Thread_queue_Operations *operations;
    132 
    133120  /** This element is the set of attributes which define this instance's
    134121   *  behavior.
     
    146133}   CORE_mutex_Control;
    147134
     135/**
     136 * @brief The recursive mutex control.
     137 */
     138typedef struct {
     139  /**
     140   * @brief The plain non-recursive mutex.
     141   */
     142  CORE_mutex_Control Mutex;
     143
     144  /**
     145   * @brief The nest level in case of a recursive seize.
     146   */
     147  unsigned int nest_level;
     148} CORE_recursive_mutex_Control;
     149
     150/**
     151 * @brief The recursive mutex control with priority ceiling protocol support.
     152 */
     153typedef struct {
     154  /**
     155   * @brief The plain recursive mutex.
     156   */
     157  CORE_recursive_mutex_Control Recursive;
     158
     159  /**
     160   * @brief The priority ceiling value for the mutex owner.
     161   */
     162  Priority_Control priority_ceiling;
     163} CORE_ceiling_mutex_Control;
     164
    148165/**@}*/
    149166
  • cpukit/score/include/rtems/score/coremuteximpl.h

    rbbb3c5f r5a598ac  
    3333 */
    3434/**@{**/
     35
     36#define CORE_MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
    3537
    3638/**
     
    101103);
    102104
     105RTEMS_INLINE_ROUTINE Thread_Control *_CORE_mutex_Get_owner(
     106  const CORE_mutex_Control *the_mutex
     107)
     108{
     109  return the_mutex->holder;
     110}
     111
    103112/**
    104113 * @brief Is mutex locked.
     
    116125)
    117126{
    118   return the_mutex->holder != NULL;
     127  return _CORE_mutex_Get_owner( the_mutex ) != NULL;
    119128}
    120129
     
    181190    the_mutex->holder     = executing;
    182191    the_mutex->nest_count = 1;
    183     if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
    184          _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ){
    185       executing->resource_count++;
    186     }
     192    ++executing->resource_count;
    187193
    188194    if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
     
    310316}
    311317
     318Status_Control _CORE_mutex_Seize_no_protocol_slow(
     319  CORE_mutex_Control            *the_mutex,
     320  const Thread_queue_Operations *operations,
     321  Thread_Control                *executing,
     322  bool                           wait,
     323  Watchdog_Interval              timeout,
     324  Thread_queue_Context          *queue_context
     325);
     326
    312327Status_Control _CORE_mutex_Surrender(
    313328  CORE_mutex_Control   *the_mutex,
    314329  Thread_queue_Context *queue_context
    315330);
     331
     332RTEMS_INLINE_ROUTINE void _CORE_mutex_Set_owner(
     333  CORE_mutex_Control *the_mutex,
     334  Thread_Control     *owner
     335)
     336{
     337  the_mutex->holder = owner;
     338}
    316339
    317340RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_owner(
     
    320343)
    321344{
    322   return the_mutex->holder == the_thread;
    323 }
    324 
    325 /**
    326  * @brief Does core mutex use FIFO blocking.
    327  *
    328  * This routine returns true if the mutex's wait discipline is FIFO and false
    329  * otherwise.
    330  *
    331  * @param[in] the_attribute is the attribute set of the mutex.
    332  *
    333  * @retval true The mutex is using FIFO blocking order.
    334  * @retval false The mutex is not using FIFO blocking order.
    335  */
    336 RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_fifo(
    337   const CORE_mutex_Attributes *the_attribute
    338 )
    339 {
    340   return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_FIFO;
     345  return _CORE_mutex_Get_owner( the_mutex ) == the_thread;
     346}
     347
     348RTEMS_INLINE_ROUTINE void _CORE_recursive_mutex_Initialize(
     349  CORE_recursive_mutex_Control *the_mutex
     350)
     351{
     352  _Thread_queue_Initialize( &the_mutex->Mutex.Wait_queue );
     353  the_mutex->Mutex.holder = NULL;
     354  the_mutex->nest_level = 0;
     355}
     356
     357RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Seize_nested(
     358  CORE_recursive_mutex_Control *the_mutex
     359)
     360{
     361  ++the_mutex->nest_level;
     362  return STATUS_SUCCESSFUL;
     363}
     364
     365RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Seize_no_protocol(
     366  CORE_recursive_mutex_Control  *the_mutex,
     367  const Thread_queue_Operations *operations,
     368  Thread_Control                *executing,
     369  bool                           wait,
     370  Watchdog_Interval              timeout,
     371  Status_Control              ( *nested )( CORE_recursive_mutex_Control * ),
     372  Thread_queue_Context          *queue_context
     373)
     374{
     375  Thread_Control *owner;
     376
     377  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
     378
     379  owner = _CORE_mutex_Get_owner( &the_mutex->Mutex );
     380
     381  if ( owner == NULL ) {
     382    _CORE_mutex_Set_owner( &the_mutex->Mutex, executing );
     383    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
     384    return STATUS_SUCCESSFUL;
     385  }
     386
     387  if ( owner == executing ) {
     388    Status_Control status;
     389
     390    status = ( *nested )( the_mutex );
     391    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
     392    return status;
     393  }
     394
     395  return _CORE_mutex_Seize_no_protocol_slow(
     396    &the_mutex->Mutex,
     397    operations,
     398    executing,
     399    wait,
     400    timeout,
     401    queue_context
     402  );
     403}
     404
     405RTEMS_INLINE_ROUTINE void
     406_CORE_recursive_mutex_Surrender_no_protocol_finalize(
     407  CORE_recursive_mutex_Control  *the_mutex,
     408  const Thread_queue_Operations *operations,
     409  Thread_queue_Context          *queue_context
     410)
     411{
     412  unsigned int    nest_level;
     413  Thread_Control *new_owner;
     414
     415  nest_level = the_mutex->nest_level;
     416
     417  if ( nest_level > 0 ) {
     418    the_mutex->nest_level = nest_level - 1;
     419    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
     420    return;
     421  }
     422
     423  new_owner = _Thread_queue_First_locked(
     424    &the_mutex->Mutex.Wait_queue,
     425    operations
     426  );
     427  _CORE_mutex_Set_owner( &the_mutex->Mutex, new_owner );
     428
     429  if ( new_owner == NULL ) {
     430    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
     431    return;
     432  }
     433
     434  _Thread_queue_Extract_critical(
     435    &the_mutex->Mutex.Wait_queue.Queue,
     436    operations,
     437    new_owner,
     438    queue_context
     439  );
     440}
     441
     442RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Surrender_no_protocol(
     443  CORE_recursive_mutex_Control  *the_mutex,
     444  const Thread_queue_Operations *operations,
     445  Thread_Control                *executing,
     446  Thread_queue_Context          *queue_context
     447)
     448{
     449  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
     450
     451  if ( !_CORE_mutex_Is_owner( &the_mutex->Mutex, executing ) ) {
     452    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
     453    return STATUS_NOT_OWNER;
     454  }
     455
     456  _CORE_recursive_mutex_Surrender_no_protocol_finalize(
     457    the_mutex,
     458    operations,
     459    queue_context
     460  );
     461  return STATUS_SUCCESSFUL;
     462}
     463
     464/*
     465 * The Classic no protocol recursive mutex has the nice property that everyone
     466 * can release it.
     467 */
     468RTEMS_INLINE_ROUTINE void _CORE_recursive_mutex_Surrender_no_protocol_classic(
     469  CORE_recursive_mutex_Control  *the_mutex,
     470  const Thread_queue_Operations *operations,
     471  Thread_queue_Context          *queue_context
     472)
     473{
     474  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
     475  _CORE_recursive_mutex_Surrender_no_protocol_finalize(
     476    the_mutex,
     477    operations,
     478    queue_context
     479  );
    341480}
    342481
  • cpukit/score/src/apimutex.c

    rbbb3c5f r5a598ac  
    5050  CORE_mutex_Attributes attr =  {
    5151    CORE_MUTEX_NESTING_ACQUIRES,
    52     true,
    5352    CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT,
    5453    0
  • cpukit/score/src/coremutex.c

    rbbb3c5f r5a598ac  
    4040
    4141  if ( initially_locked ) {
    42     bool is_priority_ceiling =
    43       _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes );
     42    bool              is_priority_ceiling;
     43    Priority_Control  ceiling;
     44    Per_CPU_Control  *cpu_self;
    4445
    4546    the_mutex->nest_count = 1;
    4647    the_mutex->holder     = executing;
    4748
    48     if (  is_priority_ceiling ||
    49          _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
    50       Priority_Control ceiling = the_mutex->Attributes.priority_ceiling;
    51       Per_CPU_Control *cpu_self;
     49    /* The mutex initialization is only protected by the allocator lock */
     50    cpu_self = _Thread_Dispatch_disable();
    5251
    53       /* The mutex initialization is only protected by the allocator lock */
    54       cpu_self = _Thread_Dispatch_disable();
     52    is_priority_ceiling =
     53      _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes );
     54    ceiling = the_mutex->Attributes.priority_ceiling;
    5555
     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 ) {
    5662      /*
    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.
     63       * There is no need to undo the previous work since this error aborts
     64       * the object creation.
    6065       */
    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       }
     66      _Thread_Dispatch_enable( cpu_self );
     67      return STATUS_MUTEX_CEILING_VIOLATED;
     68    }
    6969
    70       executing->resource_count++;
     70    executing->resource_count++;
    7171
    72       if ( is_priority_ceiling ) {
    73         _Thread_Raise_priority( executing, ceiling );
    74       }
     72    if ( is_priority_ceiling ) {
     73      _Thread_Raise_priority( executing, ceiling );
     74    }
    7575
    76       _Thread_Dispatch_enable( cpu_self );
    77     }
     76    _Thread_Dispatch_enable( cpu_self );
    7877  } else {
    7978    the_mutex->nest_count = 0;
     
    8382  _Thread_queue_Initialize( &the_mutex->Wait_queue );
    8483
    85   if ( _CORE_mutex_Is_fifo( the_mutex_attributes ) ) {
    86     the_mutex->operations = &_Thread_queue_Operations_FIFO;
    87   } else {
    88     the_mutex->operations = &_Thread_queue_Operations_priority;
    89   }
    90 
    9184  return STATUS_SUCCESSFUL;
    9285}
  • cpukit/score/src/coremutexseize.c

    rbbb3c5f r5a598ac  
    6969  _Thread_queue_Enqueue_critical(
    7070    &the_mutex->Wait_queue.Queue,
    71     the_mutex->operations,
     71    CORE_MUTEX_TQ_OPERATIONS,
    7272    executing,
    7373    STATES_WAITING_FOR_MUTEX,
     
    8383}
    8484
     85Status_Control _CORE_mutex_Seize_no_protocol_slow(
     86  CORE_mutex_Control            *the_mutex,
     87  const Thread_queue_Operations *operations,
     88  Thread_Control                *executing,
     89  bool                           wait,
     90  Watchdog_Interval              timeout,
     91  Thread_queue_Context          *queue_context
     92)
     93{
     94  if ( wait ) {
     95    _Thread_queue_Context_set_expected_level( queue_context, 1 );
     96    _Thread_queue_Enqueue_critical(
     97      &the_mutex->Wait_queue.Queue,
     98      operations,
     99      executing,
     100      STATES_WAITING_FOR_MUTEX,
     101      timeout,
     102      queue_context
     103    );
     104    return _Thread_Wait_get_status( executing );
     105  } else {
     106    _CORE_mutex_Release( the_mutex, queue_context );
     107    return STATUS_UNAVAILABLE;
     108  }
     109}
  • cpukit/score/src/coremutexsurrender.c

    rbbb3c5f r5a598ac  
    3535
    3636  /*
    37    *  The following code allows a thread (or ISR) other than the thread
    38    *  which acquired the mutex to release that mutex.  This is only
    39    *  allowed when the mutex in quetion is FIFO or simple Priority
    40    *  discipline.  But Priority Ceiling or Priority Inheritance mutexes
    41    *  must be released by the thread which acquired them.
     37   *  Priority Ceiling or Priority Inheritance mutexes must be released by the
     38   *  thread which acquired them.
    4239   */
    43 
    44   if ( the_mutex->Attributes.only_owner_release ) {
    45     if ( !_Thread_Is_executing( holder ) ) {
    46       _ISR_lock_ISR_enable( &queue_context->Lock_context );
    47       return STATUS_NOT_OWNER;
    48     }
     40  if ( !_Thread_Is_executing( holder ) ) {
     41    _ISR_lock_ISR_enable( &queue_context->Lock_context );
     42    return STATUS_NOT_OWNER;
    4943  }
    5044
     
    8983   *  blocked thread.
    9084   */
    91   if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
    92        _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
    93     holder->resource_count--;
    94   }
     85   holder->resource_count--;
    9586  the_mutex->holder = NULL;
    9687
     
    10293    ( the_thread = _Thread_queue_First_locked(
    10394        &the_mutex->Wait_queue,
    104         the_mutex->operations
     95        CORE_MUTEX_TQ_OPERATIONS
    10596      )
    10697    )
     
    119110    unblock = _Thread_queue_Extract_locked(
    120111      &the_mutex->Wait_queue.Queue,
    121       the_mutex->operations,
     112      CORE_MUTEX_TQ_OPERATIONS,
    122113      the_thread,
    123114      queue_context
     
    129120    {
    130121      switch ( the_mutex->Attributes.discipline ) {
    131         case CORE_MUTEX_DISCIPLINES_FIFO:
    132         case CORE_MUTEX_DISCIPLINES_PRIORITY:
    133           break;
    134122        case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
    135123          the_thread->resource_count++;
Note: See TracChangeset for help on using the changeset viewer.