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.
This commit is contained in:
Sebastian Huber
2016-04-28 06:51:25 +02:00
parent 500a8e9c62
commit d5cc9fd6f1
5 changed files with 183 additions and 323 deletions

View File

@@ -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"],

View File

@@ -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

View File

@@ -122,64 +122,6 @@ RTEMS_INLINE_ROUTINE void _CORE_mutex_Release(
_Thread_queue_Release( &the_mutex->Wait_queue, lock_context );
}
/**
* @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.
*
@@ -213,153 +155,6 @@ void _CORE_mutex_Seize_interrupt_blocking(
&& (_wait) \
&& (_System_state_Get() >= SYSTEM_STATE_UP))
/**
* @brief Attempt to obtain the mutex.
*
* This routine attempts to obtain the mutex. If the mutex is available,
* then it will return immediately. Otherwise, it will invoke the
* support routine @a _Core_mutex_Seize_interrupt_blocking.
*
* @param[in] the_mutex is the mutex to attempt to lock
* @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
*
* @note If the mutex is called from an interrupt service routine,
* with context switching disabled, or before multitasking,
* then a fatal error is generated.
*
* The logic on this routine is as follows:
*
* * If incorrect system state
* return an error
* * If mutex is available without any contention or blocking
* obtain it with interrupts disabled and returned
* * If the caller is willing to wait
* then they are blocked.
*/
RTEMS_INLINE_ROUTINE void _CORE_mutex_Seize_body(
CORE_mutex_Control *the_mutex,
Thread_Control *executing,
bool wait,
Watchdog_Interval timeout,
ISR_lock_Context *lock_context
)
{
if ( _CORE_mutex_Check_dispatch_for_seize( wait ) ) {
_Terminate(
INTERNAL_ERROR_CORE,
false,
INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE
);
}
_CORE_mutex_Acquire_critical( the_mutex, lock_context );
if ( _CORE_mutex_Seize_interrupt_trylock( the_mutex, executing, lock_context ) ) {
if ( !wait ) {
_CORE_mutex_Release( the_mutex, lock_context );
executing->Wait.return_code =
CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT;
} else {
_CORE_mutex_Seize_interrupt_blocking(
the_mutex,
executing,
timeout,
lock_context
);
}
}
}
/**
* 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)
Thread_queue_MP_callout mp_callout,
Objects_Id mp_id,
#endif
ISR_lock_Context *lock_context
);
#if defined(RTEMS_MULTIPROCESSING)
#define _CORE_mutex_Surrender( \
the_mutex, \
mp_callout, \
mp_id, \
lock_context \
) \
_CORE_mutex_Do_surrender( \
the_mutex, \
mp_callout, \
mp_id, \
lock_context \
)
#else
#define _CORE_mutex_Surrender( \
the_mutex, \
mp_callout, \
mp_id, \
lock_context \
) \
_CORE_mutex_Do_surrender( \
the_mutex, \
lock_context \
)
#endif
Thread_Control *_CORE_mutex_Was_deleted(
Thread_Control *the_thread,
Thread_queue_Queue *queue,
ISR_lock_Context *lock_context
);
Thread_Control *_CORE_mutex_Unsatisfied_nowait(
Thread_Control *the_thread,
Thread_queue_Queue *queue,
ISR_lock_Context *lock_context
);
/* Must be a macro due to the multiprocessing dependent parameters */
#define _CORE_mutex_Flush( \
the_mutex, \
filter, \
mp_callout, \
mp_id, \
lock_context \
) \
_Thread_queue_Flush_critical( \
&( the_mutex )->Wait_queue.Queue, \
( the_mutex )->operations, \
filter, \
mp_callout, \
mp_id, \
lock_context \
)
/**
* @brief Is mutex locked.
*
@@ -378,51 +173,6 @@ RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked(
return the_mutex->holder != NULL;
}
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_owner(
const CORE_mutex_Control *the_mutex,
const Thread_Control *the_thread
)
{
return the_mutex->holder == the_thread;
}
/**
* @brief Does core mutex use FIFO blocking.
*
* This routine returns true if the mutex's wait discipline is FIFO and false
* otherwise.
*
* @param[in] the_attribute is the attribute set of the mutex.
*
* @retval true The mutex is using FIFO blocking order.
* @retval false The mutex is not using FIFO blocking order.
*/
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_fifo(
const CORE_mutex_Attributes *the_attribute
)
{
return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_FIFO;
}
/**
* @brief Doex core mutex use priority blocking.
*
* This routine returns true if the mutex's wait discipline is PRIORITY and
* false otherwise.
*
* @param[in] the_attribute is the attribute set of the mutex.
*
* @retval true The mutex is using priority blocking order.
* @retval false The mutex is not using priority blocking order.
*
*/
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority(
const CORE_mutex_Attributes *the_attribute
)
{
return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY;
}
/**
* @brief Does mutex use priority inheritance.
*
@@ -459,16 +209,24 @@ RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling(
return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
}
/*
* Seize Mutex with Quick Success Path
/**
* @brief Attempt to receive a unit from the_mutex.
*
* NOTE: There is no MACRO version of this routine. A body is in
* coremutexseize.c that is duplicated from the .inl by hand.
* 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.
*
* NOTE: The Doxygen for this routine is in the .h file.
* @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_body(
RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock(
CORE_mutex_Control *the_mutex,
Thread_Control *executing,
ISR_lock_Context *lock_context
@@ -554,6 +312,173 @@ RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body(
return 1;
}
/**
* @brief Attempt to obtain the mutex.
*
* This routine attempts to obtain the mutex. If the mutex is available,
* then it will return immediately. Otherwise, it will invoke the
* support routine @a _Core_mutex_Seize_interrupt_blocking.
*
* @param[in] the_mutex is the mutex to attempt to lock
* @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
*
* @note If the mutex is called from an interrupt service routine,
* with context switching disabled, or before multitasking,
* then a fatal error is generated.
*
* The logic on this routine is as follows:
*
* * If incorrect system state
* return an error
* * If mutex is available without any contention or blocking
* obtain it with interrupts disabled and returned
* * If the caller is willing to wait
* then they are blocked.
*/
RTEMS_INLINE_ROUTINE void _CORE_mutex_Seize(
CORE_mutex_Control *the_mutex,
Thread_Control *executing,
bool wait,
Watchdog_Interval timeout,
ISR_lock_Context *lock_context
)
{
if ( _CORE_mutex_Check_dispatch_for_seize( wait ) ) {
_Terminate(
INTERNAL_ERROR_CORE,
false,
INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE
);
}
_CORE_mutex_Acquire_critical( the_mutex, lock_context );
if ( _CORE_mutex_Seize_interrupt_trylock( the_mutex, executing, lock_context ) ) {
if ( !wait ) {
_CORE_mutex_Release( the_mutex, lock_context );
executing->Wait.return_code =
CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT;
} else {
_CORE_mutex_Seize_interrupt_blocking(
the_mutex,
executing,
timeout,
lock_context
);
}
}
}
CORE_mutex_Status _CORE_mutex_Do_surrender(
CORE_mutex_Control *the_mutex,
#if defined(RTEMS_MULTIPROCESSING)
Thread_queue_MP_callout mp_callout,
Objects_Id mp_id,
#endif
ISR_lock_Context *lock_context
);
#if defined(RTEMS_MULTIPROCESSING)
#define _CORE_mutex_Surrender( \
the_mutex, \
mp_callout, \
mp_id, \
lock_context \
) \
_CORE_mutex_Do_surrender( \
the_mutex, \
mp_callout, \
mp_id, \
lock_context \
)
#else
#define _CORE_mutex_Surrender( \
the_mutex, \
mp_callout, \
mp_id, \
lock_context \
) \
_CORE_mutex_Do_surrender( \
the_mutex, \
lock_context \
)
#endif
Thread_Control *_CORE_mutex_Was_deleted(
Thread_Control *the_thread,
Thread_queue_Queue *queue,
ISR_lock_Context *lock_context
);
Thread_Control *_CORE_mutex_Unsatisfied_nowait(
Thread_Control *the_thread,
Thread_queue_Queue *queue,
ISR_lock_Context *lock_context
);
/* Must be a macro due to the multiprocessing dependent parameters */
#define _CORE_mutex_Flush( \
the_mutex, \
filter, \
mp_callout, \
mp_id, \
lock_context \
) \
_Thread_queue_Flush_critical( \
&( the_mutex )->Wait_queue.Queue, \
( the_mutex )->operations, \
filter, \
mp_callout, \
mp_id, \
lock_context \
)
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_owner(
const CORE_mutex_Control *the_mutex,
const Thread_Control *the_thread
)
{
return the_mutex->holder == the_thread;
}
/**
* @brief Does core mutex use FIFO blocking.
*
* This routine returns true if the mutex's wait discipline is FIFO and false
* otherwise.
*
* @param[in] the_attribute is the attribute set of the mutex.
*
* @retval true The mutex is using FIFO blocking order.
* @retval false The mutex is not using FIFO blocking order.
*/
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_fifo(
const CORE_mutex_Attributes *the_attribute
)
{
return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_FIFO;
}
/**
* @brief Doex core mutex use priority blocking.
*
* This routine returns true if the mutex's wait discipline is PRIORITY and
* false otherwise.
*
* @param[in] the_attribute is the attribute set of the mutex.
*
* @retval true The mutex is using priority blocking order.
* @retval false The mutex is not using priority blocking order.
*
*/
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority(
const CORE_mutex_Attributes *the_attribute
)
{
return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY;
}
/** @} */
#ifdef __cplusplus

View File

@@ -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,

View File

@@ -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