Changeset d5cc9fd6 in rtems


Ignore:
Timestamp:
Apr 28, 2016, 4:51:25 AM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
259d885
Parents:
500a8e9c
git-author:
Sebastian Huber <sebastian.huber@…> (04/28/16 04:51:25)
git-committer:
Sebastian Huber <sebastian.huber@…> (05/02/16 05:46:16)
Message:

score: RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE

Delete RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE as a preparation to
restructure the CORE mutex variants and reduce the branch complexity.

Location:
cpukit
Files:
1 deleted
4 edited

Legend:

Unmodified
Added
Removed
  • cpukit/configure.ac

    r500a8e9c rd5cc9fd6  
    264264RTEMS_CPUOPT([__RTEMS_DO_NOT_INLINE_THREAD_ENABLE_DISPATCH__],
    265265  [test x"${RTEMS_DO_NOT_INLINE_THREAD_ENABLE_DISPATCH}" = x"1"],
    266   [1],
    267   [disable inlining _Thread_Enable_dispatch])
    268 
    269 ## This improves both the size and coverage analysis.
    270 RTEMS_CPUOPT([__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__],
    271   [test x"${RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE}" = x"1"],
    272266  [1],
    273267  [disable inlining _Thread_Enable_dispatch])
  • cpukit/score/Makefile.am

    r500a8e9c rd5cc9fd6  
    177177## CORE_MUTEX_C_FILES
    178178libscore_a_SOURCES += src/coremutex.c \
    179     src/coremutexseize.c src/coremutexsurrender.c \
    180     src/coremutexseizeintr.c
     179    src/coremutexseize.c src/coremutexsurrender.c
    181180
    182181## CORE_PERCPU_C_FILES
  • cpukit/score/include/rtems/score/coremuteximpl.h

    r500a8e9c rd5cc9fd6  
    124124
    125125/**
    126  *  @brief Attempt to receive a unit from the_mutex.
    127  *
    128  *  This routine attempts to receive a unit from the_mutex.
    129  *  If a unit is available or if the wait flag is false, then the routine
    130  *  returns.  Otherwise, the calling task is blocked until a unit becomes
    131  *  available.
    132  *
    133  *  @param[in,out] executing The currently executing thread.
    134  *  @param[in,out] the_mutex is the mutex to attempt to lock
    135  *  @param[in] lock_context is the interrupt level
    136  *
    137  *  @retval This routine returns 0 if "trylock" can resolve whether or not
    138  *  the mutex is immediately obtained or there was an error attempting to
    139  *  get it.  It returns 1 to indicate that the caller cannot obtain
    140  *  the mutex and will have to block to do so.
    141  *
    142  *  @note  For performance reasons, this routine is implemented as
    143  *         a macro that uses two support routines.
    144  */
    145 
    146 RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body(
    147   CORE_mutex_Control  *the_mutex,
    148   Thread_Control      *executing,
    149   ISR_lock_Context    *lock_context
    150 );
    151 
    152 #if defined(__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__)
    153   /**
    154    *  @brief Interrupt trylock CORE mutex seize.
    155    *
    156    *  When doing test coverage analysis or trying to minimize the code
    157    *  space for RTEMS, it is often helpful to not inline this method
    158    *  multiple times.  It is fairly large and has a high branch complexity
    159    *  which makes it harder to get full binary test coverage.
    160    *
    161    *  @param[in] the_mutex will attempt to lock
    162    *  @param[in] _executing points to the executing thread
    163    *  @param[in] level_p is the interrupt level
    164    */
    165   int _CORE_mutex_Seize_interrupt_trylock(
    166     CORE_mutex_Control  *the_mutex,
    167     Thread_Control      *executing,
    168     ISR_lock_Context    *lock_context
    169   );
    170 #else
    171   /**
    172    *  The default is to favor speed and inlining this definitely saves
    173    *  a few instructions.  This is very important for mutex performance.
    174    *
    175    *  @param[in] _mutex will attempt to lock
    176    *  @param[in] _executing points to the executing thread
    177    *  @param[in] _lock_context is the interrupt level
    178    */
    179   #define _CORE_mutex_Seize_interrupt_trylock( _mutex, _executing, _lock_context ) \
    180      _CORE_mutex_Seize_interrupt_trylock_body( _mutex, _executing, _lock_context )
    181 #endif
    182 
    183 /**
    184126 *  @brief Performs the blocking portion of a mutex obtain.
    185127 *
     
    215157
    216158/**
     159 * @brief Is mutex locked.
     160 *
     161 * This routine returns true if the mutex specified is locked and false
     162 * otherwise.
     163 *
     164 * @param[in] the_mutex is the mutex to check.
     165 *
     166 * @retval true The mutex is locked.
     167 * @retval false The mutex is not locked.
     168 */
     169RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked(
     170  const CORE_mutex_Control *the_mutex
     171)
     172{
     173  return the_mutex->holder != NULL;
     174}
     175
     176/**
     177 * @brief Does mutex use priority inheritance.
     178 *
     179 * This routine returns true if the mutex's wait discipline is
     180 * INHERIT_PRIORITY and false otherwise.
     181 *
     182 * @param[in] the_attribute is the attribute set of the mutex.
     183 *
     184 * @retval true The mutex is using priority inheritance.
     185 * @retval false The mutex is not using priority inheritance.
     186 */
     187RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority(
     188  const CORE_mutex_Attributes *the_attribute
     189)
     190{
     191  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
     192}
     193
     194/**
     195 * @brief Does mutex use priority ceiling.
     196 *
     197 * This routine returns true if the mutex's wait discipline is
     198 * PRIORITY_CEILING and false otherwise.
     199 *
     200 * @param[in] the_attribute is the attribute set of the mutex.
     201 *
     202 * @retval true The mutex is using priority ceiling.
     203 * @retval false The mutex is not using priority ceiling.
     204 */
     205RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling(
     206  const CORE_mutex_Attributes *the_attribute
     207)
     208{
     209  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
     210}
     211
     212/**
     213 *  @brief Attempt to receive a unit from the_mutex.
     214 *
     215 *  This routine attempts to receive a unit from the_mutex.
     216 *  If a unit is available or if the wait flag is false, then the routine
     217 *  returns.  Otherwise, the calling task is blocked until a unit becomes
     218 *  available.
     219 *
     220 *  @param[in,out] executing The currently executing thread.
     221 *  @param[in,out] the_mutex is the mutex to attempt to lock
     222 *  @param[in] lock_context is the interrupt level
     223 *
     224 *  @retval This routine returns 0 if "trylock" can resolve whether or not
     225 *  the mutex is immediately obtained or there was an error attempting to
     226 *  get it.  It returns 1 to indicate that the caller cannot obtain
     227 *  the mutex and will have to block to do so.
     228 */
     229RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock(
     230  CORE_mutex_Control  *the_mutex,
     231  Thread_Control      *executing,
     232  ISR_lock_Context    *lock_context
     233)
     234{
     235  /* disabled when you get here */
     236
     237  executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
     238  if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
     239    the_mutex->holder     = executing;
     240    the_mutex->nest_count = 1;
     241    if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
     242         _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ){
     243      executing->resource_count++;
     244    }
     245
     246    if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
     247      _CORE_mutex_Release( the_mutex, lock_context );
     248      return 0;
     249    } /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
     250       *
     251       * we possibly bump the priority of the current holder -- which
     252       * happens to be _Thread_Executing.
     253       */
     254    {
     255      Priority_Control  ceiling;
     256      Priority_Control  current;
     257
     258      ceiling = the_mutex->Attributes.priority_ceiling;
     259      current = executing->current_priority;
     260      if ( current == ceiling ) {
     261        _CORE_mutex_Release( the_mutex, lock_context );
     262        return 0;
     263      }
     264
     265      if ( current > ceiling ) {
     266        Per_CPU_Control *cpu_self;
     267
     268        cpu_self = _Thread_Dispatch_disable_critical( lock_context );
     269        _CORE_mutex_Release( the_mutex, lock_context );
     270        _Thread_Raise_priority( executing, ceiling );
     271        _Thread_Dispatch_enable( cpu_self );
     272        return 0;
     273      }
     274      /* if ( current < ceiling ) */ {
     275        executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
     276        the_mutex->holder = NULL;
     277        the_mutex->nest_count = 0;     /* undo locking above */
     278        executing->resource_count--;   /* undo locking above */
     279        _CORE_mutex_Release( the_mutex, lock_context );
     280        return 0;
     281      }
     282    }
     283    return 0;
     284  }
     285
     286  /*
     287   *  At this point, we know the mutex was not available.  If this thread
     288   *  is the thread that has locked the mutex, let's see if we are allowed
     289   *  to nest access.
     290   */
     291  if ( _Thread_Is_executing( the_mutex->holder ) ) {
     292    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
     293      case CORE_MUTEX_NESTING_ACQUIRES:
     294        the_mutex->nest_count++;
     295        _CORE_mutex_Release( the_mutex, lock_context );
     296        return 0;
     297      #if defined(RTEMS_POSIX_API)
     298        case CORE_MUTEX_NESTING_IS_ERROR:
     299          executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
     300          _CORE_mutex_Release( the_mutex, lock_context );
     301          return 0;
     302      #endif
     303      case CORE_MUTEX_NESTING_BLOCKS:
     304        break;
     305    }
     306  }
     307
     308  /*
     309   *  The mutex is not available and the caller must deal with the possibility
     310   *  of blocking.
     311   */
     312  return 1;
     313}
     314
     315/**
    217316 *  @brief Attempt to obtain the mutex.
    218317 *
     
    240339 *      then they are blocked.
    241340 */
    242 RTEMS_INLINE_ROUTINE void _CORE_mutex_Seize_body(
     341RTEMS_INLINE_ROUTINE void _CORE_mutex_Seize(
    243342  CORE_mutex_Control  *the_mutex,
    244343  Thread_Control      *executing,
     
    271370  }
    272371}
    273 
    274 /**
    275  *  This method is used to obtain a core mutex.
    276  *
    277  *  @param[in] _the_mutex is the mutex to attempt to lock
    278  *  @param[in] _executing The currently executing thread.
    279  *  @param[in] _wait is true if the thread is willing to wait
    280  *  @param[in] _timeout is the maximum number of ticks to block
    281  *  @param[in] _lock_context is a temporary variable used to contain the ISR
    282  *         disable level cookie
    283  */
    284 #if defined(__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__)
    285   void _CORE_mutex_Seize(
    286     CORE_mutex_Control  *_the_mutex,
    287     Thread_Control      *_executing,
    288     bool                 _wait,
    289     Watchdog_Interval    _timeout,
    290     ISR_lock_Context    *_lock_context
    291   );
    292 #else
    293   #define _CORE_mutex_Seize( \
    294       _the_mutex, _executing, _wait, _timeout, _lock_context ) \
    295        _CORE_mutex_Seize_body( \
    296          _the_mutex, _executing, _wait, _timeout, _lock_context )
    297 #endif
    298372
    299373CORE_mutex_Status _CORE_mutex_Do_surrender(
     
    361435  )
    362436
    363 /**
    364  * @brief Is mutex locked.
    365  *
    366  * This routine returns true if the mutex specified is locked and false
    367  * otherwise.
    368  *
    369  * @param[in] the_mutex is the mutex to check.
    370  *
    371  * @retval true The mutex is locked.
    372  * @retval false The mutex is not locked.
    373  */
    374 RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked(
    375   const CORE_mutex_Control *the_mutex
    376 )
    377 {
    378   return the_mutex->holder != NULL;
    379 }
    380 
    381437RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_owner(
    382438  const CORE_mutex_Control *the_mutex,
     
    424480}
    425481
    426 /**
    427  * @brief Does mutex use priority inheritance.
    428  *
    429  * This routine returns true if the mutex's wait discipline is
    430  * INHERIT_PRIORITY and false otherwise.
    431  *
    432  * @param[in] the_attribute is the attribute set of the mutex.
    433  *
    434  * @retval true The mutex is using priority inheritance.
    435  * @retval false The mutex is not using priority inheritance.
    436  */
    437 RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority(
    438   const CORE_mutex_Attributes *the_attribute
    439 )
    440 {
    441   return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
    442 }
    443 
    444 /**
    445  * @brief Does mutex use priority ceiling.
    446  *
    447  * This routine returns true if the mutex's wait discipline is
    448  * PRIORITY_CEILING and false otherwise.
    449  *
    450  * @param[in] the_attribute is the attribute set of the mutex.
    451  *
    452  * @retval true The mutex is using priority ceiling.
    453  * @retval false The mutex is not using priority ceiling.
    454  */
    455 RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling(
    456   const CORE_mutex_Attributes *the_attribute
    457 )
    458 {
    459   return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
    460 }
    461 
    462 /*
    463  *  Seize Mutex with Quick Success Path
    464  *
    465  *  NOTE: There is no MACRO version of this routine.  A body is in
    466  *  coremutexseize.c that is duplicated from the .inl by hand.
    467  *
    468  *  NOTE: The Doxygen for this routine is in the .h file.
    469  */
    470 
    471 RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body(
    472   CORE_mutex_Control  *the_mutex,
    473   Thread_Control      *executing,
    474   ISR_lock_Context    *lock_context
    475 )
    476 {
    477   /* disabled when you get here */
    478 
    479   executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
    480   if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
    481     the_mutex->holder     = executing;
    482     the_mutex->nest_count = 1;
    483     if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
    484          _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ){
    485       executing->resource_count++;
    486     }
    487 
    488     if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
    489       _CORE_mutex_Release( the_mutex, lock_context );
    490       return 0;
    491     } /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
    492        *
    493        * we possibly bump the priority of the current holder -- which
    494        * happens to be _Thread_Executing.
    495        */
    496     {
    497       Priority_Control  ceiling;
    498       Priority_Control  current;
    499 
    500       ceiling = the_mutex->Attributes.priority_ceiling;
    501       current = executing->current_priority;
    502       if ( current == ceiling ) {
    503         _CORE_mutex_Release( the_mutex, lock_context );
    504         return 0;
    505       }
    506 
    507       if ( current > ceiling ) {
    508         Per_CPU_Control *cpu_self;
    509 
    510         cpu_self = _Thread_Dispatch_disable_critical( lock_context );
    511         _CORE_mutex_Release( the_mutex, lock_context );
    512         _Thread_Raise_priority( executing, ceiling );
    513         _Thread_Dispatch_enable( cpu_self );
    514         return 0;
    515       }
    516       /* if ( current < ceiling ) */ {
    517         executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
    518         the_mutex->holder = NULL;
    519         the_mutex->nest_count = 0;     /* undo locking above */
    520         executing->resource_count--;   /* undo locking above */
    521         _CORE_mutex_Release( the_mutex, lock_context );
    522         return 0;
    523       }
    524     }
    525     return 0;
    526   }
    527 
    528   /*
    529    *  At this point, we know the mutex was not available.  If this thread
    530    *  is the thread that has locked the mutex, let's see if we are allowed
    531    *  to nest access.
    532    */
    533   if ( _Thread_Is_executing( the_mutex->holder ) ) {
    534     switch ( the_mutex->Attributes.lock_nesting_behavior ) {
    535       case CORE_MUTEX_NESTING_ACQUIRES:
    536         the_mutex->nest_count++;
    537         _CORE_mutex_Release( the_mutex, lock_context );
    538         return 0;
    539       #if defined(RTEMS_POSIX_API)
    540         case CORE_MUTEX_NESTING_IS_ERROR:
    541           executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
    542           _CORE_mutex_Release( the_mutex, lock_context );
    543           return 0;
    544       #endif
    545       case CORE_MUTEX_NESTING_BLOCKS:
    546         break;
    547     }
    548   }
    549 
    550   /*
    551    *  The mutex is not available and the caller must deal with the possibility
    552    *  of blocking.
    553    */
    554   return 1;
    555 }
    556 
    557482/** @} */
    558483
  • cpukit/score/src/coremutexseize.c

    r500a8e9c rd5cc9fd6  
    2424#include <rtems/score/statesimpl.h>
    2525#include <rtems/score/thread.h>
    26 
    27 #if defined(__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__)
    28 void _CORE_mutex_Seize(
    29   CORE_mutex_Control  *_the_mutex,
    30   Thread_Control      *_executing,
    31   bool                 _wait,
    32   Watchdog_Interval    _timeout,
    33   ISR_Level            _level
    34 )
    35 {
    36   _CORE_mutex_Seize_body(
    37     _the_mutex,
    38     _executing,
    39     _wait,
    40     _timeout,
    41     _level
    42   );
    43 }
    44 #endif
    4526
    4627void _CORE_mutex_Seize_interrupt_blocking(
Note: See TracChangeset for help on using the changeset viewer.