Changeset 5870ac55 in rtems


Ignore:
Timestamp:
Jan 5, 2000, 10:19:21 PM (21 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
ef03d0e
Parents:
5283cc82
Message:

Added support for simple binary semaphores in addition to the high
power binary/mutex style semaphores already supported by RTEMS. This
was done at the request of Eric Norum <eric@…> in support
of his effort to port EPICS to RTEMS. This change consisted of
changing the nesting_allowed boolean into a lock_nesting_behavior
enumerated value as well as allowing the core mutex object to optionally
support ensuring that the holder of a binary semaphore released it.
Finally, a more subtle enhancement was to allow the non-holder to release
a priority inheritance/ceiling mutex and still allow the holding task
to return to its original priority.

Files:
32 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/posix/src/mutexinit.c

    r5283cc82 r5870ac55  
    145145  the_mutex_attr = &the_mutex->Mutex.Attributes;
    146146
    147   the_mutex_attr->allow_nesting = the_attr->recursive;
     147  if ( the_attr->recursive )
     148    the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
     149  else
     150    the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
     151  the_mutex_attr->only_owner_release = TRUE;
    148152  the_mutex_attr->priority_ceiling =
    149153    _POSIX_Priority_To_core( the_attr->prio_ceiling );
  • c/src/exec/rtems/include/rtems/rtems/attr.h

    r5283cc82 r5870ac55  
    3838#define RTEMS_PRIORITY            0x00000004 /* process by priority */
    3939
    40 #define RTEMS_COUNTING_SEMAPHORE  0x00000000
    41 #define RTEMS_BINARY_SEMAPHORE    0x00000010
     40#define RTEMS_SEMAPHORE_CLASS         0x00000030 /* mask */
     41#define RTEMS_COUNTING_SEMAPHORE      0x00000000
     42#define RTEMS_BINARY_SEMAPHORE        0x00000010
     43#define RTEMS_SIMPLE_BINARY_SEMAPHORE 0x00000020
    4244
    4345#define RTEMS_NO_INHERIT_PRIORITY 0x00000000
    44 #define RTEMS_INHERIT_PRIORITY    0x00000020
     46#define RTEMS_INHERIT_PRIORITY    0x00000040
    4547
    4648#define RTEMS_NO_PRIORITY_CEILING 0x00000000
    47 #define RTEMS_PRIORITY_CEILING    0x00000040
    48 
    49 #define RTEMS_NESTING_ALLOWED     0x00000000
    50 #define RTEMS_NO_NESTING_ALLOWED  0x00000080
     49#define RTEMS_PRIORITY_CEILING    0x00000080
    5150
    5251#define RTEMS_APPLICATION_TASK    0x00000000
  • c/src/exec/rtems/inline/rtems/rtems/attr.inl

    r5283cc82 r5870ac55  
    120120)
    121121{
    122   return ( attribute_set & RTEMS_BINARY_SEMAPHORE );
     122  return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_BINARY_SEMAPHORE);
     123}
     124
     125/*PAGE
     126 *
     127 *  _Attributes_Is_simple_binary_semaphore
     128 *
     129 *  DESCRIPTION:
     130 *
     131 *  This function returns TRUE if the simple binary semaphore attribute is
     132 *  enabled in the attribute_set and FALSE otherwise.
     133 */
     134
     135RTEMS_INLINE_ROUTINE boolean _Attributes_Is_simple_binary_semaphore(
     136  rtems_attribute attribute_set
     137)
     138{
     139  return
     140    ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_SIMPLE_BINARY_SEMAPHORE);
     141
     142
     143/*PAGE
     144 *
     145 *  _Attributes_Is_counting_semaphore
     146 *
     147 *  DESCRIPTION:
     148 *
     149 *  This function returns TRUE if the counting semaphore attribute is
     150 *  enabled in the attribute_set and FALSE otherwise.
     151 */
     152
     153RTEMS_INLINE_ROUTINE boolean _Attributes_Is_counting_semaphore(
     154  rtems_attribute attribute_set
     155)
     156{
     157  return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_COUNTING_SEMAPHORE);
    123158}
    124159
     
    159194/*PAGE
    160195 *
    161  *  _Attributes_Is_nesting_allowed
    162  *
    163  *  DESCRIPTION:
    164  *
    165  *  This function returns TRUE if the nesting allowed attribute
    166  *  is enabled in the attribute_set and FALSE otherwise.
    167  */
    168  
    169 RTEMS_INLINE_ROUTINE boolean _Attributes_Is_nesting_allowed(
    170   rtems_attribute attribute_set
    171 )
    172 {
    173    return ( !(attribute_set & RTEMS_NO_NESTING_ALLOWED) );
    174 }
    175 
    176 /*PAGE
    177  *
    178196 *  _Attributes_Is_system_task
    179197 *
  • c/src/exec/rtems/macros/rtems/rtems/attr.inl

    r5283cc82 r5870ac55  
    6969
    7070#define _Attributes_Is_binary_semaphore( _attribute_set ) \
    71   ( (_attribute_set) & RTEMS_BINARY_SEMAPHORE )
     71  (((_attribute_set) & RTEMS_SEMAPHORE_CLASS) == RTEMS_BINARY_SEMAPHORE)
     72
     73/*PAGE
     74 *
     75 *  _Attributes_Is_simple_binary_semaphore
     76 *
     77 */
     78
     79#define _Attributes_Is_simple_binary_semaphore( _attribute_set ) \
     80  (((_attribute_set) & RTEMS_SEMAPHORE_CLASS) == RTEMS_SIMPLE_BINARY_SEMAPHORE)
     81
     82/*PAGE
     83 *
     84 *  _Attributes_Is_counting_semaphore
     85 *
     86 */
     87
     88#define _Attributes_Is_counting_semaphore( _attribute_set ) \
     89  (((_attribute_set) & RTEMS_SEMAPHORE_CLASS) == RTEMS_COUNTING_SEMAPHORE)
    7290
    7391/*PAGE
     
    91109/*PAGE
    92110 *
    93  *  _Attributes_Is_nesting_allowed
    94  *
    95  */
    96 
    97 #define _Attributes_Is_nesting_allowed( _attribute_set ) \
    98    ( !((_attribute_set) & RTEMS_NO_NESTING_ALLOWED) )
    99 
    100 /*PAGE
    101  *
    102111 *  _Attributes_Is_system_task
    103112 *
  • c/src/exec/rtems/src/semcreate.c

    r5283cc82 r5870ac55  
    9797              _Attributes_Is_priority_ceiling( attribute_set ) ) {
    9898
    99     if ( ! ( _Attributes_Is_binary_semaphore( attribute_set ) &&
     99    if ( ! ( (_Attributes_Is_binary_semaphore( attribute_set ) ||
     100              _Attributes_Is_simple_binary_semaphore( attribute_set )) &&
     101             
    100102             _Attributes_Is_priority( attribute_set ) ) )
    101103      return RTEMS_NOT_DEFINED;
     
    103105  }
    104106
    105   if ( _Attributes_Is_binary_semaphore( attribute_set ) && ( count > 1 ) )
     107  if ( !_Attributes_Is_counting_semaphore( attribute_set ) && ( count > 1 ) )
    106108    return RTEMS_INVALID_NUMBER;
    107109
     
    127129  the_semaphore->attribute_set = attribute_set;
    128130
    129   if ( _Attributes_Is_binary_semaphore( attribute_set ) ) {
     131  /*
     132   *  If it is not a counting, semaphore, then it is either a
     133   *  simple binary semaphore or a more powerful lmutex style binary
     134   *  semaphore.
     135   */
     136
     137  if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) {
    130138    if ( _Attributes_Is_inherit_priority( attribute_set ) )
    131139      the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
     
    137145      the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_FIFO;
    138146
    139     if ( _Attributes_Is_nesting_allowed( attribute_set ) )
    140       the_mutex_attributes.allow_nesting = TRUE;
    141     else
    142       the_mutex_attributes.allow_nesting = FALSE;
    143 
    144     /* Add priority ceiling code here ????? */
     147
     148    if ( _Attributes_Is_binary_semaphore( attribute_set ) ) {
     149      the_mutex_attributes.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
     150
     151      switch ( the_mutex_attributes.discipline ) {
     152        case CORE_MUTEX_DISCIPLINES_FIFO:
     153        case CORE_MUTEX_DISCIPLINES_PRIORITY:
     154          the_mutex_attributes.only_owner_release = FALSE;
     155          break;
     156        case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
     157        case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
     158          the_mutex_attributes.only_owner_release = TRUE;
     159          break;
     160      }
     161    } else {
     162      the_mutex_attributes.lock_nesting_behavior = CORE_MUTEX_NESTING_BLOCKS;
     163      the_mutex_attributes.only_owner_release = FALSE;
     164    }
    145165
    146166    the_mutex_attributes.priority_ceiling = priority_ceiling;
     
    162182#endif
    163183    );
    164   }
    165   else {
     184  } else {
    166185    if ( _Attributes_Is_priority( attribute_set ) )
    167186      the_semaphore_attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY;
     
    179198     */
    180199
    181     the_mutex_attributes.allow_nesting = TRUE;
     200    the_mutex_attributes.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
    182201    the_mutex_attributes.priority_ceiling = PRIORITY_MINIMUM;
    183202
  • c/src/exec/rtems/src/semdelete.c

    r5283cc82 r5870ac55  
    8282
    8383    case OBJECTS_LOCAL:
    84       if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set) ) {
     84      if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
    8585        if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) ) {
    8686          _Thread_Enable_dispatch();
  • c/src/exec/rtems/src/semflush.c

    r5283cc82 r5870ac55  
    7878
    7979    case OBJECTS_LOCAL:
    80       if ( _Attributes_Is_binary_semaphore(the_semaphore->attribute_set) ) {
     80      if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
    8181        _CORE_mutex_Flush(
    8282          &the_semaphore->Core_control.mutex,
  • c/src/exec/rtems/src/semobtain.c

    r5283cc82 r5870ac55  
    9393        wait = TRUE;
    9494
    95       if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) {
     95      if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
    9696        _CORE_mutex_Seize(
    9797          &the_semaphore->Core_control.mutex,
  • c/src/exec/rtems/src/semrelease.c

    r5283cc82 r5870ac55  
    8686
    8787    case OBJECTS_LOCAL:
    88       if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) {
     88      if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
    8989        mutex_status = _CORE_mutex_Surrender(
    9090                         &the_semaphore->Core_control.mutex,
  • c/src/exec/score/include/rtems/score/coremutex.h

    r5283cc82 r5870ac55  
    6464
    6565/*
     66 *  Mutex lock nesting behavior
     67 *
     68 *  CORE_MUTEX_NESTING_ACQUIRES:
     69 *    This sequence has no blocking or errors:
     70 *         lock(m)
     71 *         lock(m)
     72 *         unlock(m)
     73 *         unlock(m)
     74 *
     75 *  CORE_MUTEX_NESTING_IS_ERROR
     76 *    This sequence returns an error at the indicated point:
     77 *        lock(m)
     78 *        lock(m)   - already locked error
     79 *        unlock(m)
     80 *
     81 *  CORE_MUTEX_NESTING_BLOCKS
     82 *    This sequence performs as indicated:
     83 *        lock(m)
     84 *        lock(m)   - deadlocks or timeouts
     85 *        unlock(m) - releases
     86 */
     87
     88typedef enum {
     89  CORE_MUTEX_NESTING_ACQUIRES,
     90  CORE_MUTEX_NESTING_IS_ERROR,
     91  CORE_MUTEX_NESTING_BLOCKS
     92}  CORE_mutex_Nesting_behaviors;
     93 
     94/*
    6695 *  Locked and unlocked values
    6796 */
     
    76105
    77106typedef struct {
    78   boolean                 allow_nesting;
    79   CORE_mutex_Disciplines  discipline;
    80   Priority_Control        priority_ceiling;
     107  CORE_mutex_Nesting_behaviors lock_nesting_behavior;
     108  boolean                      only_owner_release;
     109  CORE_mutex_Disciplines       discipline;
     110  Priority_Control             priority_ceiling;
    81111}   CORE_mutex_Attributes;
    82112 
  • c/src/exec/score/include/rtems/score/interr.h

    r5283cc82 r5870ac55  
    5454  INTERNAL_ERROR_OUT_OF_PROXIES,
    5555  INTERNAL_ERROR_INVALID_GLOBAL_ID,
    56   INTERNAL_ERROR_BAD_STACK_HOOK
     56  INTERNAL_ERROR_BAD_STACK_HOOK,
     57  INTERNAL_ERROR_BAD_ATTRIBUTES
    5758} Internal_errors_Core_list;
    5859
  • c/src/exec/score/inline/rtems/score/coremutex.inl

    r5283cc82 r5870ac55  
    102102}
    103103 
    104 /*PAGE
    105  *
    106  *  _CORE_mutex_Is_nesting_allowed
    107  *
    108  *  DESCRIPTION:
    109  *
    110  *  This routine returns TRUE if the mutex allows a task to obtain a
    111  *  semaphore more than once and nest.
    112  */
    113  
    114 RTEMS_INLINE_ROUTINE boolean _CORE_mutex_Is_nesting_allowed(
    115   CORE_mutex_Attributes *the_attribute
    116 )
    117 {
    118   return the_attribute->allow_nesting == TRUE;
    119  
    120 }
    121  
    122104#endif
    123105/* end of include file */
  • c/src/exec/score/macros/rtems/score/coremutex.inl

    r5283cc82 r5870ac55  
    6464  ( (_the_attribute)->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING )
    6565 
    66 /*PAGE
    67  *
    68  *  _CORE_mutex_Is_nesting_allowed
    69  *
    70  */
    71  
    72 #define _CORE_mutex_Is_nesting_allowed( _the_attribute ) \
    73   ( (_the_attribute)->allow_nesting == TRUE )
    74 
    7566#endif
    7667/* end of include file */
  • c/src/exec/score/src/coremutex.c

    r5283cc82 r5870ac55  
    5656
    5757  the_mutex->Attributes = *the_mutex_attributes;
    58   the_mutex->lock          = initial_lock;
     58  the_mutex->lock       = initial_lock;
     59
     60#if 0
     61  if ( !the_mutex_attributes->only_owner_release &&
     62       the_mutex_attributes->nesting_allowed ) {
     63    _Internal_error_Occurred(
     64      INTERNAL_ERROR_CORE,
     65      TRUE,
     66      INTERNAL_ERROR_BAD_ATTRIBUTES
     67    );
     68  }
     69#endif
    5970
    6071  if ( initial_lock == CORE_MUTEX_LOCKED ) {
  • c/src/exec/score/src/coremutexseize.c

    r5283cc82 r5870ac55  
    9595  }
    9696
    97   if ( _Objects_Are_ids_equal(
    98               _Thread_Executing->Object.id, the_mutex->holder_id ) ) {
    99     if ( _CORE_mutex_Is_nesting_allowed( &the_mutex->Attributes ) )
    100       the_mutex->nest_count++;
    101     else
    102       executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
    103 
    104     _ISR_Enable( level );
    105     return;
     97  if ( _Thread_Is_executing( the_mutex->holder ) ) {
     98    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
     99      case CORE_MUTEX_NESTING_ACQUIRES:
     100        the_mutex->nest_count++;
     101        _ISR_Enable( level );
     102        return;
     103      case CORE_MUTEX_NESTING_IS_ERROR:
     104        executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
     105        _ISR_Enable( level );
     106        return;
     107      case CORE_MUTEX_NESTING_BLOCKS:
     108        break;
     109    }
    106110  }
    107111
  • c/src/exec/score/src/coremutexsurrender.c

    r5283cc82 r5870ac55  
    5050{
    5151  Thread_Control *the_thread;
    52   Thread_Control *executing;
     52  Thread_Control *holder;
    5353
    54   executing = _Thread_Executing;
     54  holder    = the_mutex->holder;
    5555
    5656  /*
     
    6262   */
    6363
    64   if ( the_mutex->Attributes.allow_nesting ) {
    65     if ( !_Objects_Are_ids_equal(
    66              _Thread_Executing->Object.id, the_mutex->holder_id ) ) {
    67  
    68       switch ( the_mutex->Attributes.discipline ) {
    69         case CORE_MUTEX_DISCIPLINES_FIFO:
    70         case CORE_MUTEX_DISCIPLINES_PRIORITY:
    71           break;
    72         case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
    73         case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
    74           return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE );
    75           break;
    76       }
    77     }
     64  if ( the_mutex->Attributes.only_owner_release ) {
     65    if ( !_Thread_Is_executing( holder ) )
     66      return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE );
    7867  }
    7968
     
    8675
    8776  if ( the_mutex->nest_count != 0 ) {
    88     if ( the_mutex->Attributes.allow_nesting )
    89       return( CORE_MUTEX_STATUS_SUCCESSFUL );
    90     return( CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED );
     77    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
     78      case CORE_MUTEX_NESTING_ACQUIRES:
     79        return CORE_MUTEX_STATUS_SUCCESSFUL;
     80      case CORE_MUTEX_NESTING_IS_ERROR:
     81        /* should never occur */
     82        return CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
     83      case CORE_MUTEX_NESTING_BLOCKS:
     84        break;
     85    }
    9186  }
    9287
     
    107102    case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
    108103    case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
    109       if ( executing->resource_count == 0 &&
    110            executing->real_priority != executing->current_priority ) {
    111          _Thread_Change_priority( executing, executing->real_priority, TRUE );
     104      if ( holder->resource_count == 0 &&
     105           holder->real_priority != holder->current_priority ) {
     106         _Thread_Change_priority( holder, holder->real_priority, TRUE );
    112107      }
    113108      break;
  • cpukit/posix/src/mutexinit.c

    r5283cc82 r5870ac55  
    145145  the_mutex_attr = &the_mutex->Mutex.Attributes;
    146146
    147   the_mutex_attr->allow_nesting = the_attr->recursive;
     147  if ( the_attr->recursive )
     148    the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
     149  else
     150    the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
     151  the_mutex_attr->only_owner_release = TRUE;
    148152  the_mutex_attr->priority_ceiling =
    149153    _POSIX_Priority_To_core( the_attr->prio_ceiling );
  • cpukit/rtems/include/rtems/rtems/attr.h

    r5283cc82 r5870ac55  
    3838#define RTEMS_PRIORITY            0x00000004 /* process by priority */
    3939
    40 #define RTEMS_COUNTING_SEMAPHORE  0x00000000
    41 #define RTEMS_BINARY_SEMAPHORE    0x00000010
     40#define RTEMS_SEMAPHORE_CLASS         0x00000030 /* mask */
     41#define RTEMS_COUNTING_SEMAPHORE      0x00000000
     42#define RTEMS_BINARY_SEMAPHORE        0x00000010
     43#define RTEMS_SIMPLE_BINARY_SEMAPHORE 0x00000020
    4244
    4345#define RTEMS_NO_INHERIT_PRIORITY 0x00000000
    44 #define RTEMS_INHERIT_PRIORITY    0x00000020
     46#define RTEMS_INHERIT_PRIORITY    0x00000040
    4547
    4648#define RTEMS_NO_PRIORITY_CEILING 0x00000000
    47 #define RTEMS_PRIORITY_CEILING    0x00000040
    48 
    49 #define RTEMS_NESTING_ALLOWED     0x00000000
    50 #define RTEMS_NO_NESTING_ALLOWED  0x00000080
     49#define RTEMS_PRIORITY_CEILING    0x00000080
    5150
    5251#define RTEMS_APPLICATION_TASK    0x00000000
  • cpukit/rtems/inline/rtems/rtems/attr.inl

    r5283cc82 r5870ac55  
    120120)
    121121{
    122   return ( attribute_set & RTEMS_BINARY_SEMAPHORE );
     122  return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_BINARY_SEMAPHORE);
     123}
     124
     125/*PAGE
     126 *
     127 *  _Attributes_Is_simple_binary_semaphore
     128 *
     129 *  DESCRIPTION:
     130 *
     131 *  This function returns TRUE if the simple binary semaphore attribute is
     132 *  enabled in the attribute_set and FALSE otherwise.
     133 */
     134
     135RTEMS_INLINE_ROUTINE boolean _Attributes_Is_simple_binary_semaphore(
     136  rtems_attribute attribute_set
     137)
     138{
     139  return
     140    ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_SIMPLE_BINARY_SEMAPHORE);
     141
     142
     143/*PAGE
     144 *
     145 *  _Attributes_Is_counting_semaphore
     146 *
     147 *  DESCRIPTION:
     148 *
     149 *  This function returns TRUE if the counting semaphore attribute is
     150 *  enabled in the attribute_set and FALSE otherwise.
     151 */
     152
     153RTEMS_INLINE_ROUTINE boolean _Attributes_Is_counting_semaphore(
     154  rtems_attribute attribute_set
     155)
     156{
     157  return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_COUNTING_SEMAPHORE);
    123158}
    124159
     
    159194/*PAGE
    160195 *
    161  *  _Attributes_Is_nesting_allowed
    162  *
    163  *  DESCRIPTION:
    164  *
    165  *  This function returns TRUE if the nesting allowed attribute
    166  *  is enabled in the attribute_set and FALSE otherwise.
    167  */
    168  
    169 RTEMS_INLINE_ROUTINE boolean _Attributes_Is_nesting_allowed(
    170   rtems_attribute attribute_set
    171 )
    172 {
    173    return ( !(attribute_set & RTEMS_NO_NESTING_ALLOWED) );
    174 }
    175 
    176 /*PAGE
    177  *
    178196 *  _Attributes_Is_system_task
    179197 *
  • cpukit/rtems/macros/rtems/rtems/attr.inl

    r5283cc82 r5870ac55  
    6969
    7070#define _Attributes_Is_binary_semaphore( _attribute_set ) \
    71   ( (_attribute_set) & RTEMS_BINARY_SEMAPHORE )
     71  (((_attribute_set) & RTEMS_SEMAPHORE_CLASS) == RTEMS_BINARY_SEMAPHORE)
     72
     73/*PAGE
     74 *
     75 *  _Attributes_Is_simple_binary_semaphore
     76 *
     77 */
     78
     79#define _Attributes_Is_simple_binary_semaphore( _attribute_set ) \
     80  (((_attribute_set) & RTEMS_SEMAPHORE_CLASS) == RTEMS_SIMPLE_BINARY_SEMAPHORE)
     81
     82/*PAGE
     83 *
     84 *  _Attributes_Is_counting_semaphore
     85 *
     86 */
     87
     88#define _Attributes_Is_counting_semaphore( _attribute_set ) \
     89  (((_attribute_set) & RTEMS_SEMAPHORE_CLASS) == RTEMS_COUNTING_SEMAPHORE)
    7290
    7391/*PAGE
     
    91109/*PAGE
    92110 *
    93  *  _Attributes_Is_nesting_allowed
    94  *
    95  */
    96 
    97 #define _Attributes_Is_nesting_allowed( _attribute_set ) \
    98    ( !((_attribute_set) & RTEMS_NO_NESTING_ALLOWED) )
    99 
    100 /*PAGE
    101  *
    102111 *  _Attributes_Is_system_task
    103112 *
  • cpukit/rtems/src/semcreate.c

    r5283cc82 r5870ac55  
    9797              _Attributes_Is_priority_ceiling( attribute_set ) ) {
    9898
    99     if ( ! ( _Attributes_Is_binary_semaphore( attribute_set ) &&
     99    if ( ! ( (_Attributes_Is_binary_semaphore( attribute_set ) ||
     100              _Attributes_Is_simple_binary_semaphore( attribute_set )) &&
     101             
    100102             _Attributes_Is_priority( attribute_set ) ) )
    101103      return RTEMS_NOT_DEFINED;
     
    103105  }
    104106
    105   if ( _Attributes_Is_binary_semaphore( attribute_set ) && ( count > 1 ) )
     107  if ( !_Attributes_Is_counting_semaphore( attribute_set ) && ( count > 1 ) )
    106108    return RTEMS_INVALID_NUMBER;
    107109
     
    127129  the_semaphore->attribute_set = attribute_set;
    128130
    129   if ( _Attributes_Is_binary_semaphore( attribute_set ) ) {
     131  /*
     132   *  If it is not a counting, semaphore, then it is either a
     133   *  simple binary semaphore or a more powerful lmutex style binary
     134   *  semaphore.
     135   */
     136
     137  if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) {
    130138    if ( _Attributes_Is_inherit_priority( attribute_set ) )
    131139      the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
     
    137145      the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_FIFO;
    138146
    139     if ( _Attributes_Is_nesting_allowed( attribute_set ) )
    140       the_mutex_attributes.allow_nesting = TRUE;
    141     else
    142       the_mutex_attributes.allow_nesting = FALSE;
    143 
    144     /* Add priority ceiling code here ????? */
     147
     148    if ( _Attributes_Is_binary_semaphore( attribute_set ) ) {
     149      the_mutex_attributes.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
     150
     151      switch ( the_mutex_attributes.discipline ) {
     152        case CORE_MUTEX_DISCIPLINES_FIFO:
     153        case CORE_MUTEX_DISCIPLINES_PRIORITY:
     154          the_mutex_attributes.only_owner_release = FALSE;
     155          break;
     156        case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
     157        case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
     158          the_mutex_attributes.only_owner_release = TRUE;
     159          break;
     160      }
     161    } else {
     162      the_mutex_attributes.lock_nesting_behavior = CORE_MUTEX_NESTING_BLOCKS;
     163      the_mutex_attributes.only_owner_release = FALSE;
     164    }
    145165
    146166    the_mutex_attributes.priority_ceiling = priority_ceiling;
     
    162182#endif
    163183    );
    164   }
    165   else {
     184  } else {
    166185    if ( _Attributes_Is_priority( attribute_set ) )
    167186      the_semaphore_attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY;
     
    179198     */
    180199
    181     the_mutex_attributes.allow_nesting = TRUE;
     200    the_mutex_attributes.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
    182201    the_mutex_attributes.priority_ceiling = PRIORITY_MINIMUM;
    183202
  • cpukit/rtems/src/semdelete.c

    r5283cc82 r5870ac55  
    8282
    8383    case OBJECTS_LOCAL:
    84       if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set) ) {
     84      if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
    8585        if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) ) {
    8686          _Thread_Enable_dispatch();
  • cpukit/rtems/src/semflush.c

    r5283cc82 r5870ac55  
    7878
    7979    case OBJECTS_LOCAL:
    80       if ( _Attributes_Is_binary_semaphore(the_semaphore->attribute_set) ) {
     80      if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
    8181        _CORE_mutex_Flush(
    8282          &the_semaphore->Core_control.mutex,
  • cpukit/rtems/src/semobtain.c

    r5283cc82 r5870ac55  
    9393        wait = TRUE;
    9494
    95       if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) {
     95      if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
    9696        _CORE_mutex_Seize(
    9797          &the_semaphore->Core_control.mutex,
  • cpukit/rtems/src/semrelease.c

    r5283cc82 r5870ac55  
    8686
    8787    case OBJECTS_LOCAL:
    88       if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) {
     88      if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
    8989        mutex_status = _CORE_mutex_Surrender(
    9090                         &the_semaphore->Core_control.mutex,
  • cpukit/score/include/rtems/score/coremutex.h

    r5283cc82 r5870ac55  
    6464
    6565/*
     66 *  Mutex lock nesting behavior
     67 *
     68 *  CORE_MUTEX_NESTING_ACQUIRES:
     69 *    This sequence has no blocking or errors:
     70 *         lock(m)
     71 *         lock(m)
     72 *         unlock(m)
     73 *         unlock(m)
     74 *
     75 *  CORE_MUTEX_NESTING_IS_ERROR
     76 *    This sequence returns an error at the indicated point:
     77 *        lock(m)
     78 *        lock(m)   - already locked error
     79 *        unlock(m)
     80 *
     81 *  CORE_MUTEX_NESTING_BLOCKS
     82 *    This sequence performs as indicated:
     83 *        lock(m)
     84 *        lock(m)   - deadlocks or timeouts
     85 *        unlock(m) - releases
     86 */
     87
     88typedef enum {
     89  CORE_MUTEX_NESTING_ACQUIRES,
     90  CORE_MUTEX_NESTING_IS_ERROR,
     91  CORE_MUTEX_NESTING_BLOCKS
     92}  CORE_mutex_Nesting_behaviors;
     93 
     94/*
    6695 *  Locked and unlocked values
    6796 */
     
    76105
    77106typedef struct {
    78   boolean                 allow_nesting;
    79   CORE_mutex_Disciplines  discipline;
    80   Priority_Control        priority_ceiling;
     107  CORE_mutex_Nesting_behaviors lock_nesting_behavior;
     108  boolean                      only_owner_release;
     109  CORE_mutex_Disciplines       discipline;
     110  Priority_Control             priority_ceiling;
    81111}   CORE_mutex_Attributes;
    82112 
  • cpukit/score/include/rtems/score/interr.h

    r5283cc82 r5870ac55  
    5454  INTERNAL_ERROR_OUT_OF_PROXIES,
    5555  INTERNAL_ERROR_INVALID_GLOBAL_ID,
    56   INTERNAL_ERROR_BAD_STACK_HOOK
     56  INTERNAL_ERROR_BAD_STACK_HOOK,
     57  INTERNAL_ERROR_BAD_ATTRIBUTES
    5758} Internal_errors_Core_list;
    5859
  • cpukit/score/inline/rtems/score/coremutex.inl

    r5283cc82 r5870ac55  
    102102}
    103103 
    104 /*PAGE
    105  *
    106  *  _CORE_mutex_Is_nesting_allowed
    107  *
    108  *  DESCRIPTION:
    109  *
    110  *  This routine returns TRUE if the mutex allows a task to obtain a
    111  *  semaphore more than once and nest.
    112  */
    113  
    114 RTEMS_INLINE_ROUTINE boolean _CORE_mutex_Is_nesting_allowed(
    115   CORE_mutex_Attributes *the_attribute
    116 )
    117 {
    118   return the_attribute->allow_nesting == TRUE;
    119  
    120 }
    121  
    122104#endif
    123105/* end of include file */
  • cpukit/score/macros/rtems/score/coremutex.inl

    r5283cc82 r5870ac55  
    6464  ( (_the_attribute)->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING )
    6565 
    66 /*PAGE
    67  *
    68  *  _CORE_mutex_Is_nesting_allowed
    69  *
    70  */
    71  
    72 #define _CORE_mutex_Is_nesting_allowed( _the_attribute ) \
    73   ( (_the_attribute)->allow_nesting == TRUE )
    74 
    7566#endif
    7667/* end of include file */
  • cpukit/score/src/coremutex.c

    r5283cc82 r5870ac55  
    5656
    5757  the_mutex->Attributes = *the_mutex_attributes;
    58   the_mutex->lock          = initial_lock;
     58  the_mutex->lock       = initial_lock;
     59
     60#if 0
     61  if ( !the_mutex_attributes->only_owner_release &&
     62       the_mutex_attributes->nesting_allowed ) {
     63    _Internal_error_Occurred(
     64      INTERNAL_ERROR_CORE,
     65      TRUE,
     66      INTERNAL_ERROR_BAD_ATTRIBUTES
     67    );
     68  }
     69#endif
    5970
    6071  if ( initial_lock == CORE_MUTEX_LOCKED ) {
  • cpukit/score/src/coremutexseize.c

    r5283cc82 r5870ac55  
    9595  }
    9696
    97   if ( _Objects_Are_ids_equal(
    98               _Thread_Executing->Object.id, the_mutex->holder_id ) ) {
    99     if ( _CORE_mutex_Is_nesting_allowed( &the_mutex->Attributes ) )
    100       the_mutex->nest_count++;
    101     else
    102       executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
    103 
    104     _ISR_Enable( level );
    105     return;
     97  if ( _Thread_Is_executing( the_mutex->holder ) ) {
     98    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
     99      case CORE_MUTEX_NESTING_ACQUIRES:
     100        the_mutex->nest_count++;
     101        _ISR_Enable( level );
     102        return;
     103      case CORE_MUTEX_NESTING_IS_ERROR:
     104        executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
     105        _ISR_Enable( level );
     106        return;
     107      case CORE_MUTEX_NESTING_BLOCKS:
     108        break;
     109    }
    106110  }
    107111
  • cpukit/score/src/coremutexsurrender.c

    r5283cc82 r5870ac55  
    5050{
    5151  Thread_Control *the_thread;
    52   Thread_Control *executing;
     52  Thread_Control *holder;
    5353
    54   executing = _Thread_Executing;
     54  holder    = the_mutex->holder;
    5555
    5656  /*
     
    6262   */
    6363
    64   if ( the_mutex->Attributes.allow_nesting ) {
    65     if ( !_Objects_Are_ids_equal(
    66              _Thread_Executing->Object.id, the_mutex->holder_id ) ) {
    67  
    68       switch ( the_mutex->Attributes.discipline ) {
    69         case CORE_MUTEX_DISCIPLINES_FIFO:
    70         case CORE_MUTEX_DISCIPLINES_PRIORITY:
    71           break;
    72         case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
    73         case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
    74           return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE );
    75           break;
    76       }
    77     }
     64  if ( the_mutex->Attributes.only_owner_release ) {
     65    if ( !_Thread_Is_executing( holder ) )
     66      return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE );
    7867  }
    7968
     
    8675
    8776  if ( the_mutex->nest_count != 0 ) {
    88     if ( the_mutex->Attributes.allow_nesting )
    89       return( CORE_MUTEX_STATUS_SUCCESSFUL );
    90     return( CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED );
     77    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
     78      case CORE_MUTEX_NESTING_ACQUIRES:
     79        return CORE_MUTEX_STATUS_SUCCESSFUL;
     80      case CORE_MUTEX_NESTING_IS_ERROR:
     81        /* should never occur */
     82        return CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
     83      case CORE_MUTEX_NESTING_BLOCKS:
     84        break;
     85    }
    9186  }
    9287
     
    107102    case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
    108103    case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
    109       if ( executing->resource_count == 0 &&
    110            executing->real_priority != executing->current_priority ) {
    111          _Thread_Change_priority( executing, executing->real_priority, TRUE );
     104      if ( holder->resource_count == 0 &&
     105           holder->real_priority != holder->current_priority ) {
     106         _Thread_Change_priority( holder, holder->real_priority, TRUE );
    112107      }
    113108      break;
Note: See TracChangeset for help on using the changeset viewer.