Changeset 21e2b2b in rtems


Ignore:
Timestamp:
Jul 6, 2000, 7:32:00 PM (20 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
3ef54dc
Parents:
8d5b438b
Message:

Reimplemented _Core_MUTEX_Seize to return with interrupts disabled
if the mutex is successfully obtained.

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/score/include/rtems/score/coremutex.h

    r8d5b438b r21e2b2b  
    150150 *  returns.  Otherwise, the calling task is blocked until a unit becomes
    151151 *  available.
    152  */
    153 
    154 void _CORE_mutex_Seize(
     152 *
     153 *  NOTE:  For performance reasons, this routine is implemented as
     154 *         a macro that uses two support routines.
     155 */
     156
     157RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock(
    155158  CORE_mutex_Control  *the_mutex,
    156   Objects_Id           id,
     159  ISR_Level           *level_p
     160);
     161
     162void _CORE_mutex_Seize_interrupt_blocking(
     163  CORE_mutex_Control  *the_mutex,
    157164  boolean              wait,
    158165  Watchdog_Interval    timeout
    159166);
    160  
     167
     168#define _CORE_mutex_Seize( \
     169  _the_mutex, _id, _wait, _timeout, _level ) \
     170  do { \
     171    if ( _CORE_mutex_Seize_interrupt_trylock( _the_mutex, &_level ) ) {  \
     172      if ( !_wait ) { \
     173        _ISR_Enable( _level ); \
     174        _Thread_Executing->Wait.return_code = \
     175          CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT; \
     176      } else { \
     177        _Thread_queue_Enter_critical_section( &(_the_mutex)->Wait_queue ); \
     178        _Thread_Executing->Wait.queue = &(_the_mutex)->Wait_queue; \
     179        _Thread_Executing->Wait.id    = _id; \
     180        _Thread_Disable_dispatch(); \
     181        _ISR_Enable( _level ); \
     182       _CORE_mutex_Seize_interrupt_blocking( _the_mutex, _id, _timeout ); \
     183      } \
     184    } \
     185  } while (0)
     186
    161187/*
    162188 *  _CORE_mutex_Surrender
     
    190216);
    191217 
    192 #ifndef __RTEMS_APPLICATION__
    193 #include <rtems/score/coremutex.inl>
    194 #endif
    195 
    196218#ifdef __cplusplus
    197219}
  • c/src/exec/score/inline/rtems/score/coremutex.inl

    r8d5b438b r21e2b2b  
    102102}
    103103 
     104/*PAGE
     105 *
     106 *  _CORE_mutex_Seize_interrupt_trylock
     107 *
     108 *  DESCRIPTION:
     109 *
     110 *  This routine returns 0 if "trylock" can resolve whether or not the
     111 *  mutex is immediately obtained or there was an error attempting to
     112 *  get it.  It returns 1 to indicate that the caller cannot obtain
     113 *  the mutex and will have to block to do so.
     114 *
     115 *  NOTE: There is no MACRO version of this routine.
     116 */
     117
     118RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock(
     119  CORE_mutex_Control  *the_mutex,
     120  ISR_Level           *level_p
     121)
     122{
     123  Thread_Control   *executing;
     124  ISR_Level         level = *level_p;
     125
     126  /* disabled when you get here */
     127
     128  executing = _Thread_Executing;
     129  executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
     130  if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
     131    the_mutex->lock       = CORE_MUTEX_LOCKED;
     132    the_mutex->holder     = executing;
     133    the_mutex->holder_id  = executing->Object.id;
     134    the_mutex->nest_count = 1;
     135    executing->resource_count++;
     136    if ( the_mutex->Attributes.discipline !=
     137           CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING ) {
     138        _ISR_Enable( level );
     139        return 0;
     140    }
     141    /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING */
     142    {
     143       Priority_Control  ceiling;
     144       Priority_Control  current;
     145
     146       ceiling = the_mutex->Attributes.priority_ceiling;
     147       current = executing->current_priority;
     148       if ( current == ceiling ) {
     149         _ISR_Enable( level );
     150         return 0;
     151       }
     152       if ( current > ceiling ) {
     153        _Thread_Disable_dispatch();
     154        _ISR_Enable( level );
     155        _Thread_Change_priority(
     156          the_mutex->holder,
     157          the_mutex->Attributes.priority_ceiling,
     158          FALSE
     159        );
     160        _Thread_Enable_dispatch();
     161        return 0;
     162      }
     163      /* if ( current < ceiling ) */ {
     164        executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
     165        the_mutex->nest_count = 0;     /* undo locking above */
     166        executing->resource_count--;   /* undo locking above */
     167        _ISR_Enable( level );
     168        return 0;
     169      }
     170    }
     171    return 0;
     172  }
     173
     174  if ( _Thread_Is_executing( the_mutex->holder ) ) {
     175    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
     176      case CORE_MUTEX_NESTING_ACQUIRES:
     177        the_mutex->nest_count++;
     178        _ISR_Enable( level );
     179        return 0;
     180      case CORE_MUTEX_NESTING_IS_ERROR:
     181        executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
     182        _ISR_Enable( level );
     183        return 0;
     184      case CORE_MUTEX_NESTING_BLOCKS:
     185        break;
     186    }
     187  }
     188
     189  return 1;
     190}
     191 
     192#endif
     193
    104194#endif
    105195/* end of include file */
  • cpukit/score/include/rtems/score/coremutex.h

    r8d5b438b r21e2b2b  
    150150 *  returns.  Otherwise, the calling task is blocked until a unit becomes
    151151 *  available.
    152  */
    153 
    154 void _CORE_mutex_Seize(
     152 *
     153 *  NOTE:  For performance reasons, this routine is implemented as
     154 *         a macro that uses two support routines.
     155 */
     156
     157RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock(
    155158  CORE_mutex_Control  *the_mutex,
    156   Objects_Id           id,
     159  ISR_Level           *level_p
     160);
     161
     162void _CORE_mutex_Seize_interrupt_blocking(
     163  CORE_mutex_Control  *the_mutex,
    157164  boolean              wait,
    158165  Watchdog_Interval    timeout
    159166);
    160  
     167
     168#define _CORE_mutex_Seize( \
     169  _the_mutex, _id, _wait, _timeout, _level ) \
     170  do { \
     171    if ( _CORE_mutex_Seize_interrupt_trylock( _the_mutex, &_level ) ) {  \
     172      if ( !_wait ) { \
     173        _ISR_Enable( _level ); \
     174        _Thread_Executing->Wait.return_code = \
     175          CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT; \
     176      } else { \
     177        _Thread_queue_Enter_critical_section( &(_the_mutex)->Wait_queue ); \
     178        _Thread_Executing->Wait.queue = &(_the_mutex)->Wait_queue; \
     179        _Thread_Executing->Wait.id    = _id; \
     180        _Thread_Disable_dispatch(); \
     181        _ISR_Enable( _level ); \
     182       _CORE_mutex_Seize_interrupt_blocking( _the_mutex, _id, _timeout ); \
     183      } \
     184    } \
     185  } while (0)
     186
    161187/*
    162188 *  _CORE_mutex_Surrender
     
    190216);
    191217 
    192 #ifndef __RTEMS_APPLICATION__
    193 #include <rtems/score/coremutex.inl>
    194 #endif
    195 
    196218#ifdef __cplusplus
    197219}
  • cpukit/score/inline/rtems/score/coremutex.inl

    r8d5b438b r21e2b2b  
    102102}
    103103 
     104/*PAGE
     105 *
     106 *  _CORE_mutex_Seize_interrupt_trylock
     107 *
     108 *  DESCRIPTION:
     109 *
     110 *  This routine returns 0 if "trylock" can resolve whether or not the
     111 *  mutex is immediately obtained or there was an error attempting to
     112 *  get it.  It returns 1 to indicate that the caller cannot obtain
     113 *  the mutex and will have to block to do so.
     114 *
     115 *  NOTE: There is no MACRO version of this routine.
     116 */
     117
     118RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock(
     119  CORE_mutex_Control  *the_mutex,
     120  ISR_Level           *level_p
     121)
     122{
     123  Thread_Control   *executing;
     124  ISR_Level         level = *level_p;
     125
     126  /* disabled when you get here */
     127
     128  executing = _Thread_Executing;
     129  executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
     130  if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
     131    the_mutex->lock       = CORE_MUTEX_LOCKED;
     132    the_mutex->holder     = executing;
     133    the_mutex->holder_id  = executing->Object.id;
     134    the_mutex->nest_count = 1;
     135    executing->resource_count++;
     136    if ( the_mutex->Attributes.discipline !=
     137           CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING ) {
     138        _ISR_Enable( level );
     139        return 0;
     140    }
     141    /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING */
     142    {
     143       Priority_Control  ceiling;
     144       Priority_Control  current;
     145
     146       ceiling = the_mutex->Attributes.priority_ceiling;
     147       current = executing->current_priority;
     148       if ( current == ceiling ) {
     149         _ISR_Enable( level );
     150         return 0;
     151       }
     152       if ( current > ceiling ) {
     153        _Thread_Disable_dispatch();
     154        _ISR_Enable( level );
     155        _Thread_Change_priority(
     156          the_mutex->holder,
     157          the_mutex->Attributes.priority_ceiling,
     158          FALSE
     159        );
     160        _Thread_Enable_dispatch();
     161        return 0;
     162      }
     163      /* if ( current < ceiling ) */ {
     164        executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
     165        the_mutex->nest_count = 0;     /* undo locking above */
     166        executing->resource_count--;   /* undo locking above */
     167        _ISR_Enable( level );
     168        return 0;
     169      }
     170    }
     171    return 0;
     172  }
     173
     174  if ( _Thread_Is_executing( the_mutex->holder ) ) {
     175    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
     176      case CORE_MUTEX_NESTING_ACQUIRES:
     177        the_mutex->nest_count++;
     178        _ISR_Enable( level );
     179        return 0;
     180      case CORE_MUTEX_NESTING_IS_ERROR:
     181        executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
     182        _ISR_Enable( level );
     183        return 0;
     184      case CORE_MUTEX_NESTING_BLOCKS:
     185        break;
     186    }
     187  }
     188
     189  return 1;
     190}
     191 
     192#endif
     193
    104194#endif
    105195/* end of include file */
Note: See TracChangeset for help on using the changeset viewer.