RTEMS CPU Kit with SuperCore  4.10.99.0
Data Structures | Defines | Typedefs | Enumerations | Functions
Mutex Handler
SuperCore

This handler encapsulates functionality which provides the foundation Mutex services used in all of the APIs supported by RTEMS. More...

Collaboration diagram for Mutex Handler:

Data Structures

struct  CORE_mutex_Attributes
 The control block used to manage attributes of each mutex. More...
struct  CORE_mutex_Control
 Control block used to manage each mutex. More...

Defines

#define CORE_MUTEX_STATUS_LAST   CORE_MUTEX_STATUS_CEILING_VIOLATED
 The last status value.
#define CORE_MUTEX_UNLOCKED   1
 This is the value of a mutex when it is unlocked.
#define CORE_MUTEX_LOCKED   0
 This is the value of a mutex when it is locked.
#define _CORE_mutex_Seize_interrupt_trylock(_mutex, _level)   _CORE_mutex_Seize_interrupt_trylock_body( _mutex, _level )
 The default is to favor speed and inlining this definitely saves a few instructions.
#define _CORE_mutex_Check_dispatch_for_seize(_wait)   0
 Verifies that a mutex blocking seize is performed safely.
#define _CORE_mutex_Seize_body(_the_mutex, _id, _wait, _timeout, _level)
 Attempt to obtain the mutex.
#define _CORE_mutex_Seize(_the_mutex, _id, _wait, _timeout, _level)   _CORE_mutex_Seize_body( _the_mutex, _id, _wait, _timeout, _level )
 This method is used to obtain a core mutex.

Typedefs

typedef void(* CORE_mutex_API_mp_support_callout )(Thread_Control *, Objects_Id)
 Callout which provides to support global/multiprocessor operations.

Enumerations

enum  CORE_mutex_Disciplines { CORE_MUTEX_DISCIPLINES_FIFO, CORE_MUTEX_DISCIPLINES_PRIORITY, CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT, CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING }
 The blocking disciplines for a mutex. More...
enum  CORE_mutex_Status {
  CORE_MUTEX_STATUS_SUCCESSFUL, CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT, CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED, CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE,
  CORE_MUTEX_WAS_DELETED, CORE_MUTEX_TIMEOUT, CORE_MUTEX_STATUS_CEILING_VIOLATED
}
 The possible Mutex handler return statuses. More...
enum  CORE_mutex_Nesting_behaviors { CORE_MUTEX_NESTING_ACQUIRES, CORE_MUTEX_NESTING_IS_ERROR, CORE_MUTEX_NESTING_BLOCKS }
 The possible behaviors for lock nesting. More...

Functions

CORE_mutex_Status _CORE_mutex_Initialize (CORE_mutex_Control *the_mutex, CORE_mutex_Attributes *the_mutex_attributes, uint32_t initial_lock)
 Initializes the mutex based on the parameters passed.
RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body (CORE_mutex_Control *the_mutex, ISR_Level level)
 Attempt to receive a unit from the_mutex.
void _CORE_mutex_Seize_interrupt_blocking (CORE_mutex_Control *the_mutex, Watchdog_Interval timeout)
 Performs the blocking portion of a mutex obtain.
CORE_mutex_Status _CORE_mutex_Surrender (CORE_mutex_Control *the_mutex, Objects_Id id, CORE_mutex_API_mp_support_callout api_mutex_mp_support)
 Frees a unit to the mutex.
void _CORE_mutex_Flush (CORE_mutex_Control *the_mutex, Thread_queue_Flush_callout remote_extract_callout, uint32_t status)
 Flush all waiting threads.
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked (CORE_mutex_Control *the_mutex)
 Is mutex locked.
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_fifo (CORE_mutex_Attributes *the_attribute)
 Does core mutex use FIFO blocking.
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority (CORE_mutex_Attributes *the_attribute)
 Doex core mutex use priority blocking.
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority (CORE_mutex_Attributes *the_attribute)
 Does mutex use priority inheritance.
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling (CORE_mutex_Attributes *the_attribute)
 Does mutex use priority ceiling.

Detailed Description

This handler encapsulates functionality which provides the foundation Mutex services used in all of the APIs supported by RTEMS.


Define Documentation

#define _CORE_mutex_Check_dispatch_for_seize (   _wait)    0

Verifies that a mutex blocking seize is performed safely.

This macro is to verify that a mutex blocking seize is performed from a safe system state. For example, one cannot block inside an isr.

Return values:
thismethod returns true if dispatch is in an unsafe state.
#define _CORE_mutex_Seize (   _the_mutex,
  _id,
  _wait,
  _timeout,
  _level 
)    _CORE_mutex_Seize_body( _the_mutex, _id, _wait, _timeout, _level )

This method is used to obtain a core mutex.

Parameters:
[in]_the_mutexis the mutex to attempt to lock
[in]_idis the Id of the owning API level Semaphore object
[in]_waitis true if the thread is willing to wait
[in]_timeoutis the maximum number of ticks to block
[in]_levelis a temporary variable used to contain the ISR disable level cookie
#define _CORE_mutex_Seize_body (   _the_mutex,
  _id,
  _wait,
  _timeout,
  _level 
)
Value:
do { \
    if ( _CORE_mutex_Check_dispatch_for_seize(_wait) ) { \
        _Internal_error_Occurred( \
           INTERNAL_ERROR_CORE, \
           false, \
           INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE \
           ); \
    } \
    if ( _CORE_mutex_Seize_interrupt_trylock( _the_mutex, _level ) ) {  \
      if ( !(_wait) ) { \
        _ISR_Enable( _level ); \
        _Thread_Executing->Wait.return_code = \
          CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT; \
      } else { \
        _Thread_queue_Enter_critical_section( &(_the_mutex)->Wait_queue ); \
        _Thread_Executing->Wait.queue = &(_the_mutex)->Wait_queue; \
        _Thread_Executing->Wait.id    = _id; \
        _Thread_Disable_dispatch(); \
        _ISR_Enable( _level ); \
       _CORE_mutex_Seize_interrupt_blocking( _the_mutex, _timeout ); \
      } \
    } \
  } while (0)

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 _Core_mutex_Seize_interrupt_blocking.

Parameters:
[in]_the_mutexis the mutex to attempt to lock
[in]_idis the Id of the owning API level Semaphore object
[in]_waitis true if the thread is willing to wait
[in]_timeoutis the maximum number of ticks to block
[in]_levelis 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.

#define _CORE_mutex_Seize_interrupt_trylock (   _mutex,
  _level 
)    _CORE_mutex_Seize_interrupt_trylock_body( _mutex, _level )

The default is to favor speed and inlining this definitely saves a few instructions.

This is very important for mutex performance.

Parameters:
[in]_mutexwill attempt to lock
[in]_levelis the interrupt level
#define CORE_MUTEX_STATUS_LAST   CORE_MUTEX_STATUS_CEILING_VIOLATED

The last status value.

This is the last status value.


Typedef Documentation

Callout which provides to support global/multiprocessor operations.

The following type defines the callout which the API provides to support global/multiprocessor operations on mutexes.


Enumeration Type Documentation

The blocking disciplines for a mutex.

This enumerated type defines the blocking disciplines for a mutex.

Enumerator:
CORE_MUTEX_DISCIPLINES_FIFO 

This specifies that threads will wait for the mutex in FIFO order.

CORE_MUTEX_DISCIPLINES_PRIORITY 

This specifies that threads will wait for the mutex in priority order.

CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT 

This specifies that threads will wait for the mutex in priority order.

Additionally, the Priority Inheritance Protocol will be in effect.

CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING 

This specifies that threads will wait for the mutex in priority order.

Additionally, the Priority Ceiling Protocol will be in effect.

The possible behaviors for lock nesting.

This enumerated type defines the possible behaviors for lock nesting.

Enumerator:
CORE_MUTEX_NESTING_ACQUIRES 

This sequence has no blocking or errors:

+ lock(m) + lock(m) + unlock(m) + unlock(m)

CORE_MUTEX_NESTING_IS_ERROR 

This sequence returns an error at the indicated point:

+ lock(m) + lock(m) - already locked error + unlock(m)

CORE_MUTEX_NESTING_BLOCKS 

This sequence performs as indicated: + lock(m) + lock(m) - deadlocks or timeouts + unlock(m) - releases.

The possible Mutex handler return statuses.

This enumerated type defines the possible Mutex handler return statuses.

Enumerator:
CORE_MUTEX_STATUS_SUCCESSFUL 

This status indicates that the operation completed successfully.

CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT 

This status indicates that the calling task did not want to block and the operation was unable to complete immediately because the resource was unavailable.

CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED 

This status indicates that an attempt was made to relock a mutex for which nesting is not configured.

CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE 

This status indicates that an attempt was made to release a mutex by a thread other than the thread which locked it.

CORE_MUTEX_WAS_DELETED 

This status indicates that the thread was blocked waiting for an operation to complete and the mutex was deleted.

CORE_MUTEX_TIMEOUT 

This status indicates that the calling task was willing to block but the operation was unable to complete within the time allotted because the resource never became available.

CORE_MUTEX_STATUS_CEILING_VIOLATED 

This status indicates that a thread of logically greater importance than the ceiling priority attempted to lock this mutex.


Function Documentation

void _CORE_mutex_Flush ( CORE_mutex_Control the_mutex,
Thread_queue_Flush_callout  remote_extract_callout,
uint32_t  status 
)

Flush all waiting threads.

This routine assists in the deletion of a mutex by flushing the associated wait queue.

Parameters:
[in]the_mutexis the mutex to flush
[in]remote_extract_calloutis the routine to invoke when a remote thread is extracted
[in]statusis the status value which each unblocked thread will return to its caller.
CORE_mutex_Status _CORE_mutex_Initialize ( CORE_mutex_Control the_mutex,
CORE_mutex_Attributes the_mutex_attributes,
uint32_t  initial_lock 
)

Initializes the mutex based on the parameters passed.

This routine initializes the mutex based on the parameters passed.

Parameters:
[in]the_mutexis the mutex to initalize
[in]the_mutex_attributesis the attributes associated with this mutex instance
[in]initial_lockis the initial value of the mutex
Return values:
Thismethod returns CORE_MUTEX_STATUS_SUCCESSFUL if successful.
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_fifo ( CORE_mutex_Attributes the_attribute)

Does core mutex use FIFO blocking.

This routine returns true if the mutex's wait discipline is FIFO and false otherwise.

Parameters:
[in]the_attributeis the attribute set of the mutex.
Return values:
trueThe mutex is using FIFO blocking order.
falseThe mutex is not using FIFO blocking order.

References CORE_mutex_Attributes::discipline, and CORE_MUTEX_DISCIPLINES_FIFO.

RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority ( CORE_mutex_Attributes the_attribute)

Does mutex use priority inheritance.

This routine returns true if the mutex's wait discipline is INHERIT_PRIORITY and false otherwise.

Parameters:
[in]the_attributeis the attribute set of the mutex.
Return values:
trueThe mutex is using priority inheritance.
falseThe mutex is not using priority inheritance.

References CORE_mutex_Attributes::discipline, and CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT.

Referenced by _CORE_mutex_Seize_interrupt_trylock_body().

RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked ( CORE_mutex_Control the_mutex)

Is mutex locked.

This routine returns true if the mutex specified is locked and false otherwise.

Parameters:
[in]the_mutexis the mutex to check.
Return values:
trueThe mutex is locked.
falseThe mutex is not locked.

References CORE_mutex_Control::lock, and CORE_MUTEX_LOCKED.

Referenced by _CORE_mutex_Seize_interrupt_trylock_body().

RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority ( CORE_mutex_Attributes the_attribute)

Doex core mutex use priority blocking.

This routine returns true if the mutex's wait discipline is PRIORITY and false otherwise.

Parameters:
[in]the_attributeis the attribute set of the mutex.
Return values:
trueThe mutex is using priority blocking order.
falseThe mutex is not using priority blocking order.

References CORE_mutex_Attributes::discipline, and CORE_MUTEX_DISCIPLINES_PRIORITY.

RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling ( CORE_mutex_Attributes the_attribute)

Does mutex use priority ceiling.

This routine returns true if the mutex's wait discipline is PRIORITY_CEILING and false otherwise.

Parameters:
[in]the_attributeis the attribute set of the mutex.
Return values:
trueThe mutex is using priority ceiling.
falseThe mutex is not using priority ceiling.

References CORE_mutex_Attributes::discipline, and CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING.

Referenced by _CORE_mutex_Seize_interrupt_trylock_body().

void _CORE_mutex_Seize_interrupt_blocking ( CORE_mutex_Control the_mutex,
Watchdog_Interval  timeout 
)

Performs the blocking portion of a mutex obtain.

This routine performs the blocking portion of a mutex obtain. It is an actual subroutine and is not implemented as something that may be inlined.

Parameters:
[in]the_mutexis the mutex to attempt to lock
[in]timeoutis the maximum number of ticks to block
RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body ( CORE_mutex_Control the_mutex,
ISR_Level  level 
)

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.

Parameters:
[in]the_mutexis the mutex to attempt to lock
[in]levelis the interrupt level
Return values:
Thisroutine 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.

References Thread_Control_struct::Wait, Thread_Wait_information::return_code, CORE_MUTEX_STATUS_SUCCESSFUL, _CORE_mutex_Is_locked(), CORE_mutex_Control::lock, CORE_MUTEX_LOCKED, CORE_mutex_Control::holder, CORE_mutex_Control::holder_id, Thread_Control_struct::Object, Objects_Control::id, CORE_mutex_Control::nest_count, _CORE_mutex_Is_inherit_priority(), CORE_mutex_Control::Attributes, _CORE_mutex_Is_priority_ceiling(), _Chain_Prepend_unprotected(), Thread_Control_struct::current_priority, Thread_Control_struct::resource_count, _ISR_Enable, CORE_mutex_Attributes::priority_ceiling, _Thread_Disable_dispatch(), _Thread_Change_priority(), _Thread_Enable_dispatch(), CORE_MUTEX_STATUS_CEILING_VIOLATED, CORE_MUTEX_UNLOCKED, _Thread_Is_executing(), CORE_mutex_Attributes::lock_nesting_behavior, CORE_MUTEX_NESTING_ACQUIRES, CORE_MUTEX_NESTING_IS_ERROR, CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED, and CORE_MUTEX_NESTING_BLOCKS.

CORE_mutex_Status _CORE_mutex_Surrender ( CORE_mutex_Control the_mutex,
Objects_Id  id,
CORE_mutex_API_mp_support_callout  api_mutex_mp_support 
)

Frees a unit to the mutex.

This routine frees a unit to the mutex. If a task was blocked waiting for a unit from this mutex, then that task will be readied and the unit given to that task. Otherwise, the unit will be returned to the mutex.

Parameters:
[in]the_mutexis the mutex to surrender
[in]idis the id of the RTEMS Object associated with this mutex
[in]api_mutex_mp_supportis the routine that will be called when unblocking a remote mutex
Return values:
anindication of whether the routine succeeded or failed