[PATCH 17/19] score: __RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__

Chris Johns chrisj at rtems.org
Tue May 3 03:24:35 UTC 2016


On 29/04/2016 19:13, Sebastian Huber wrote:
> Delete __RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__ as a preparation to
> restructure the CORE mutex variants and reduce the branch complexity.
> ---
>   cpukit/configure.ac                              |   6 -
>   cpukit/score/Makefile.am                         |   3 +-
>   cpukit/score/include/rtems/score/coremuteximpl.h | 391 +++++++++--------------
>   cpukit/score/src/coremutexseize.c                |  19 --
>   cpukit/score/src/coremutexseizeintr.c            |  39 ---
>   5 files changed, 159 insertions(+), 299 deletions(-)
>   delete mode 100644 cpukit/score/src/coremutexseizeintr.c
>
> diff --git a/cpukit/configure.ac b/cpukit/configure.ac
> index 4b9020c..054e60e 100644
> --- a/cpukit/configure.ac
> +++ b/cpukit/configure.ac
> @@ -266,12 +266,6 @@ RTEMS_CPUOPT([__RTEMS_DO_NOT_INLINE_THREAD_ENABLE_DISPATCH__],
>     [1],
>     [disable inlining _Thread_Enable_dispatch])
>
> -## This improves both the size and coverage analysis.
> -RTEMS_CPUOPT([__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__],
> -  [test x"${RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE}" = x"1"],
> -  [1],
> -  [disable inlining _Thread_Enable_dispatch])
> -
>   ## Deactivate ada bindings
>   RTEMS_CPUOPT([__RTEMS_ADA__],
>     [test x"${enable_ada}" = x"yes"],
> diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
> index 566182f..c10f2fd 100644
> --- a/cpukit/score/Makefile.am
> +++ b/cpukit/score/Makefile.am
> @@ -176,8 +176,7 @@ libscore_a_SOURCES += src/coremsg.c src/coremsgbroadcast.c \
>
>   ## CORE_MUTEX_C_FILES
>   libscore_a_SOURCES += src/coremutex.c \
> -    src/coremutexseize.c src/coremutexsurrender.c \
> -    src/coremutexseizeintr.c
> +    src/coremutexseize.c src/coremutexsurrender.c
>
>   ## CORE_PERCPU_C_FILES
>   libscore_a_SOURCES += src/percpu.c
> diff --git a/cpukit/score/include/rtems/score/coremuteximpl.h b/cpukit/score/include/rtems/score/coremuteximpl.h
> index 69935b5..ef116ec 100644
> --- a/cpukit/score/include/rtems/score/coremuteximpl.h
> +++ b/cpukit/score/include/rtems/score/coremuteximpl.h
> @@ -123,64 +123,6 @@ RTEMS_INLINE_ROUTINE void _CORE_mutex_Release(
>   }
>
>   /**
> - *  @brief Attempt to receive a unit from the_mutex.
> - *
> - *  This routine attempts to receive a unit from the_mutex.
> - *  If a unit is available or if the wait flag is false, then the routine
> - *  returns.  Otherwise, the calling task is blocked until a unit becomes
> - *  available.
> - *
> - *  @param[in,out] executing The currently executing thread.
> - *  @param[in,out] the_mutex is the mutex to attempt to lock
> - *  @param[in] lock_context is the interrupt level
> - *
> - *  @retval This routine returns 0 if "trylock" can resolve whether or not
> - *  the mutex is immediately obtained or there was an error attempting to
> - *  get it.  It returns 1 to indicate that the caller cannot obtain
> - *  the mutex and will have to block to do so.
> - *
> - *  @note  For performance reasons, this routine is implemented as
> - *         a macro that uses two support routines.
> - */
> -
> -RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body(
> -  CORE_mutex_Control  *the_mutex,
> -  Thread_Control      *executing,
> -  ISR_lock_Context    *lock_context
> -);
> -
> -#if defined(__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__)
> -  /**
> -   *  @brief Interrupt trylock CORE mutex seize.
> -   *
> -   *  When doing test coverage analysis or trying to minimize the code
> -   *  space for RTEMS, it is often helpful to not inline this method
> -   *  multiple times.  It is fairly large and has a high branch complexity
> -   *  which makes it harder to get full binary test coverage.
> -   *
> -   *  @param[in] the_mutex will attempt to lock
> -   *  @param[in] _executing points to the executing thread
> -   *  @param[in] level_p is the interrupt level
> -   */
> -  int _CORE_mutex_Seize_interrupt_trylock(
> -    CORE_mutex_Control  *the_mutex,
> -    Thread_Control      *executing,
> -    ISR_lock_Context    *lock_context
> -  );
> -#else
> -  /**
> -   *  The default is to favor speed and inlining this definitely saves
> -   *  a few instructions.  This is very important for mutex performance.
> -   *
> -   *  @param[in] _mutex will attempt to lock
> -   *  @param[in] _executing points to the executing thread
> -   *  @param[in] _lock_context is the interrupt level
> -   */
> -  #define _CORE_mutex_Seize_interrupt_trylock( _mutex, _executing, _lock_context ) \
> -     _CORE_mutex_Seize_interrupt_trylock_body( _mutex, _executing, _lock_context )
> -#endif
> -
> -/**
>    *  @brief Performs the blocking portion of a mutex obtain.
>    *
>    *  This routine performs the blocking portion of a mutex obtain.
> @@ -214,6 +156,163 @@ void _CORE_mutex_Seize_interrupt_blocking(
>       && (_System_state_Get() >= SYSTEM_STATE_UP))
>
>   /**
> + * @brief Is mutex locked.
> + *
> + * This routine returns true if the mutex specified is locked and false
> + * otherwise.
> + *
> + * @param[in] the_mutex is the mutex to check.
> + *
> + * @retval true The mutex is locked.
> + * @retval false The mutex is not locked.
> + */
> +RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked(
> +  const CORE_mutex_Control *the_mutex
> +)
> +{
> +  return the_mutex->holder != NULL;
> +}
> +
> +/**
> + * @brief Does mutex use priority inheritance.
> + *
> + * This routine returns true if the mutex's wait discipline is
> + * INHERIT_PRIORITY and false otherwise.
> + *
> + * @param[in] the_attribute is the attribute set of the mutex.
> + *
> + * @retval true The mutex is using priority inheritance.
> + * @retval false The mutex is not using priority inheritance.
> + */
> +RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority(
> +  const CORE_mutex_Attributes *the_attribute
> +)
> +{
> +  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
> +}
> +
> +/**
> + * @brief Does mutex use priority ceiling.
> + *
> + * This routine returns true if the mutex's wait discipline is
> + * PRIORITY_CEILING and false otherwise.
> + *
> + * @param[in] the_attribute is the attribute set of the mutex.
> + *
> + * @retval true The mutex is using priority ceiling.
> + * @retval false The mutex is not using priority ceiling.
> + */
> +RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling(
> +  const CORE_mutex_Attributes *the_attribute
> +)
> +{
> +  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
> +}
> +
> +/**
> + *  @brief Attempt to receive a unit from the_mutex.
> + *

  [ I know this is copied in here. ]

What is a unit?

> + *  This routine attempts to receive a unit from the_mutex.
> + *  If a unit is available or if the wait flag is false, then the routine
> + *  returns.  Otherwise, the calling task is blocked until a unit becomes
> + *  available.

The comment says the thread will block but this is a trylock call so is 
this comment OK? The function name has interrupt in it, why?

> + *
> + *  @param[in,out] executing The currently executing thread.
> + *  @param[in,out] the_mutex is the mutex to attempt to lock
> + *  @param[in] lock_context is the interrupt level
> + *
> + *  @retval This routine returns 0 if "trylock" can resolve whether or not
> + *  the mutex is immediately obtained or there was an error attempting to
> + *  get it.  It returns 1 to indicate that the caller cannot obtain
> + *  the mutex and will have to block to do so.
> + */
> +RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock(
> +  CORE_mutex_Control  *the_mutex,
> +  Thread_Control      *executing,
> +  ISR_lock_Context    *lock_context
> +)
> +{
> +  /* disabled when you get here */

What is disabled?

Chris

> +
> +  executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
> +  if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
> +    the_mutex->holder     = executing;
> +    the_mutex->nest_count = 1;
> +    if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
> +         _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ){
> +      executing->resource_count++;
> +    }
> +
> +    if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
> +      _CORE_mutex_Release( the_mutex, lock_context );
> +      return 0;
> +    } /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
> +       *
> +       * we possibly bump the priority of the current holder -- which
> +       * happens to be _Thread_Executing.
> +       */
> +    {
> +      Priority_Control  ceiling;
> +      Priority_Control  current;
> +
> +      ceiling = the_mutex->Attributes.priority_ceiling;
> +      current = executing->current_priority;
> +      if ( current == ceiling ) {
> +        _CORE_mutex_Release( the_mutex, lock_context );
> +        return 0;
> +      }
> +
> +      if ( current > ceiling ) {
> +        Per_CPU_Control *cpu_self;
> +
> +        cpu_self = _Thread_Dispatch_disable_critical( lock_context );
> +        _CORE_mutex_Release( the_mutex, lock_context );
> +        _Thread_Raise_priority( executing, ceiling );
> +        _Thread_Dispatch_enable( cpu_self );
> +        return 0;
> +      }
> +      /* if ( current < ceiling ) */ {
> +        executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
> +        the_mutex->holder = NULL;
> +        the_mutex->nest_count = 0;     /* undo locking above */
> +        executing->resource_count--;   /* undo locking above */
> +        _CORE_mutex_Release( the_mutex, lock_context );
> +        return 0;
> +      }
> +    }
> +    return 0;
> +  }
> +
> +  /*
> +   *  At this point, we know the mutex was not available.  If this thread
> +   *  is the thread that has locked the mutex, let's see if we are allowed
> +   *  to nest access.
> +   */
> +  if ( _Thread_Is_executing( the_mutex->holder ) ) {
> +    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
> +      case CORE_MUTEX_NESTING_ACQUIRES:
> +        the_mutex->nest_count++;
> +        _CORE_mutex_Release( the_mutex, lock_context );
> +        return 0;
> +      #if defined(RTEMS_POSIX_API)
> +        case CORE_MUTEX_NESTING_IS_ERROR:
> +          executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
> +          _CORE_mutex_Release( the_mutex, lock_context );
> +          return 0;
> +      #endif
> +      case CORE_MUTEX_NESTING_BLOCKS:
> +        break;
> +    }
> +  }
> +
> +  /*
> +   *  The mutex is not available and the caller must deal with the possibility
> +   *  of blocking.
> +   */
> +  return 1;
> +}
> +
> +/**
>    *  @brief Attempt to obtain the mutex.
>    *
>    *  This routine attempts to obtain the mutex.  If the mutex is available,
> @@ -239,7 +338,7 @@ void _CORE_mutex_Seize_interrupt_blocking(
>    *  * If the caller is willing to wait
>    *      then they are blocked.
>    */
> -RTEMS_INLINE_ROUTINE void _CORE_mutex_Seize_body(
> +RTEMS_INLINE_ROUTINE void _CORE_mutex_Seize(
>     CORE_mutex_Control  *the_mutex,
>     Thread_Control      *executing,
>     bool                 wait,
> @@ -271,31 +370,6 @@ RTEMS_INLINE_ROUTINE void _CORE_mutex_Seize_body(
>     }
>   }
>
> -/**
> - *  This method is used to obtain a core mutex.
> - *
> - *  @param[in] _the_mutex is the mutex to attempt to lock
> - *  @param[in] _executing The currently executing thread.
> - *  @param[in] _wait is true if the thread is willing to wait
> - *  @param[in] _timeout is the maximum number of ticks to block
> - *  @param[in] _lock_context is a temporary variable used to contain the ISR
> - *         disable level cookie
> - */
> -#if defined(__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__)
> -  void _CORE_mutex_Seize(
> -    CORE_mutex_Control  *_the_mutex,
> -    Thread_Control      *_executing,
> -    bool                 _wait,
> -    Watchdog_Interval    _timeout,
> -    ISR_lock_Context    *_lock_context
> -  );
> -#else
> -  #define _CORE_mutex_Seize( \
> -      _the_mutex, _executing, _wait, _timeout, _lock_context ) \
> -       _CORE_mutex_Seize_body( \
> -         _the_mutex, _executing, _wait, _timeout, _lock_context )
> -#endif
> -
>   CORE_mutex_Status _CORE_mutex_Do_surrender(
>     CORE_mutex_Control      *the_mutex,
>   #if defined(RTEMS_MULTIPROCESSING)
> @@ -360,24 +434,6 @@ Thread_Control *_CORE_mutex_Unsatisfied_nowait(
>       lock_context \
>     )
>
> -/**
> - * @brief Is mutex locked.
> - *
> - * This routine returns true if the mutex specified is locked and false
> - * otherwise.
> - *
> - * @param[in] the_mutex is the mutex to check.
> - *
> - * @retval true The mutex is locked.
> - * @retval false The mutex is not locked.
> - */
> -RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked(
> -  const CORE_mutex_Control *the_mutex
> -)
> -{
> -  return the_mutex->holder != NULL;
> -}
> -
>   RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_owner(
>     const CORE_mutex_Control *the_mutex,
>     const Thread_Control     *the_thread
> @@ -423,137 +479,6 @@ RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority(
>     return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY;
>   }
>
> -/**
> - * @brief Does mutex use priority inheritance.
> - *
> - * This routine returns true if the mutex's wait discipline is
> - * INHERIT_PRIORITY and false otherwise.
> - *
> - * @param[in] the_attribute is the attribute set of the mutex.
> - *
> - * @retval true The mutex is using priority inheritance.
> - * @retval false The mutex is not using priority inheritance.
> - */
> -RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority(
> -  const CORE_mutex_Attributes *the_attribute
> -)
> -{
> -  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
> -}
> -
> -/**
> - * @brief Does mutex use priority ceiling.
> - *
> - * This routine returns true if the mutex's wait discipline is
> - * PRIORITY_CEILING and false otherwise.
> - *
> - * @param[in] the_attribute is the attribute set of the mutex.
> - *
> - * @retval true The mutex is using priority ceiling.
> - * @retval false The mutex is not using priority ceiling.
> - */
> -RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling(
> -  const CORE_mutex_Attributes *the_attribute
> -)
> -{
> -  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
> -}
> -
> -/*
> - *  Seize Mutex with Quick Success Path
> - *
> - *  NOTE: There is no MACRO version of this routine.  A body is in
> - *  coremutexseize.c that is duplicated from the .inl by hand.
> - *
> - *  NOTE: The Doxygen for this routine is in the .h file.
> - */
> -
> -RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body(
> -  CORE_mutex_Control  *the_mutex,
> -  Thread_Control      *executing,
> -  ISR_lock_Context    *lock_context
> -)
> -{
> -  /* disabled when you get here */
> -
> -  executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
> -  if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
> -    the_mutex->holder     = executing;
> -    the_mutex->nest_count = 1;
> -    if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
> -         _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ){
> -      executing->resource_count++;
> -    }
> -
> -    if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
> -      _CORE_mutex_Release( the_mutex, lock_context );
> -      return 0;
> -    } /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
> -       *
> -       * we possibly bump the priority of the current holder -- which
> -       * happens to be _Thread_Executing.
> -       */
> -    {
> -      Priority_Control  ceiling;
> -      Priority_Control  current;
> -
> -      ceiling = the_mutex->Attributes.priority_ceiling;
> -      current = executing->current_priority;
> -      if ( current == ceiling ) {
> -        _CORE_mutex_Release( the_mutex, lock_context );
> -        return 0;
> -      }
> -
> -      if ( current > ceiling ) {
> -        Per_CPU_Control *cpu_self;
> -
> -        cpu_self = _Thread_Dispatch_disable_critical( lock_context );
> -        _CORE_mutex_Release( the_mutex, lock_context );
> -        _Thread_Raise_priority( executing, ceiling );
> -        _Thread_Dispatch_enable( cpu_self );
> -        return 0;
> -      }
> -      /* if ( current < ceiling ) */ {
> -        executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
> -        the_mutex->holder = NULL;
> -        the_mutex->nest_count = 0;     /* undo locking above */
> -        executing->resource_count--;   /* undo locking above */
> -        _CORE_mutex_Release( the_mutex, lock_context );
> -        return 0;
> -      }
> -    }
> -    return 0;
> -  }
> -
> -  /*
> -   *  At this point, we know the mutex was not available.  If this thread
> -   *  is the thread that has locked the mutex, let's see if we are allowed
> -   *  to nest access.
> -   */
> -  if ( _Thread_Is_executing( the_mutex->holder ) ) {
> -    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
> -      case CORE_MUTEX_NESTING_ACQUIRES:
> -        the_mutex->nest_count++;
> -        _CORE_mutex_Release( the_mutex, lock_context );
> -        return 0;
> -      #if defined(RTEMS_POSIX_API)
> -        case CORE_MUTEX_NESTING_IS_ERROR:
> -          executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
> -          _CORE_mutex_Release( the_mutex, lock_context );
> -          return 0;
> -      #endif
> -      case CORE_MUTEX_NESTING_BLOCKS:
> -        break;
> -    }
> -  }
> -
> -  /*
> -   *  The mutex is not available and the caller must deal with the possibility
> -   *  of blocking.
> -   */
> -  return 1;
> -}
> -
>   /** @} */
>
>   #ifdef __cplusplus
> diff --git a/cpukit/score/src/coremutexseize.c b/cpukit/score/src/coremutexseize.c
> index d76c977..168d697 100644
> --- a/cpukit/score/src/coremutexseize.c
> +++ b/cpukit/score/src/coremutexseize.c
> @@ -24,25 +24,6 @@
>   #include <rtems/score/statesimpl.h>
>   #include <rtems/score/thread.h>
>
> -#if defined(__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__)
> -void _CORE_mutex_Seize(
> -  CORE_mutex_Control  *_the_mutex,
> -  Thread_Control      *_executing,
> -  bool                 _wait,
> -  Watchdog_Interval    _timeout,
> -  ISR_Level            _level
> -)
> -{
> -  _CORE_mutex_Seize_body(
> -    _the_mutex,
> -    _executing,
> -    _wait,
> -    _timeout,
> -    _level
> -  );
> -}
> -#endif
> -
>   void _CORE_mutex_Seize_interrupt_blocking(
>     CORE_mutex_Control  *the_mutex,
>     Thread_Control      *executing,
> diff --git a/cpukit/score/src/coremutexseizeintr.c b/cpukit/score/src/coremutexseizeintr.c
> deleted file mode 100644
> index b02c092..0000000
> --- a/cpukit/score/src/coremutexseizeintr.c
> +++ /dev/null
> @@ -1,39 +0,0 @@
> -/**
> - *  @file
> - *
> - *  @brief Trylock CORE Mutex Seize Interrupt
> - *  @ingroup ScoreMutex
> - */
> -
> -/*
> - *  COPYRIGHT (c) 1989-2007.
> - *  On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/system.h>
> -#include <rtems/score/isr.h>
> -#include <rtems/score/coremuteximpl.h>
> -#include <rtems/score/thread.h>
> -
> -#if defined(__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__)
> -int _CORE_mutex_Seize_interrupt_trylock(
> -  CORE_mutex_Control  *the_mutex,
> -  Thread_Control      *executing,
> -  ISR_Level            level
> -)
> -{
> -  return _CORE_mutex_Seize_interrupt_trylock_body(
> -    the_mutex,
> -    executing,
> -    level
> -  );
> -}
> -#endif
>


More information about the devel mailing list