ChibiOS/RT
2.6.0
Mutexes
Collaboration diagram for Mutexes:

Detailed Description

Mutexes related APIs and services.

Operation mode

A mutex is a threads synchronization object that can be in two distinct states:

Operations defined for mutexes:

Constraints

In ChibiOS/RT the Unlock operations are always performed in lock-reverse order. The unlock API does not even have a parameter, the mutex to unlock is selected from an internal, per-thread, stack of owned mutexes. This both improves the performance and is required for an efficient implementation of the priority inheritance mechanism.

The priority inversion problem

The mutexes in ChibiOS/RT implements the full priority inheritance mechanism in order handle the priority inversion problem.
When a thread is queued on a mutex, any thread, directly or indirectly, holding the mutex gains the same priority of the waiting thread (if their priority was not already equal or higher). The mechanism works with any number of nested mutexes and any number of involved threads. The algorithm complexity (worst case) is N with N equal to the number of nested mutexes.

Precondition:
In order to use the mutex APIs the CH_USE_MUTEXES option must be enabled in chconf.h.
Postcondition:
Enabling mutexes requires 5-12 (depending on the architecture) extra bytes in the Thread structure.

Data Structures

struct  Mutex
 Mutex structure. More...

Functions

void chMtxInit (Mutex *mp)
 Initializes s Mutex structure.
void chMtxLock (Mutex *mp)
 Locks the specified mutex.
void chMtxLockS (Mutex *mp)
 Locks the specified mutex.
bool_t chMtxTryLock (Mutex *mp)
 Tries to lock a mutex.
bool_t chMtxTryLockS (Mutex *mp)
 Tries to lock a mutex.
MutexchMtxUnlock (void)
 Unlocks the next owned mutex in reverse lock order.
MutexchMtxUnlockS (void)
 Unlocks the next owned mutex in reverse lock order.
void chMtxUnlockAll (void)
 Unlocks all the mutexes owned by the invoking thread.

Macro Functions

#define chMtxQueueNotEmptyS(mp)   notempty(&(mp)->m_queue)
 Returns TRUE if the mutex queue contains at least a waiting thread.

Defines

#define _MUTEX_DATA(name)   {_THREADSQUEUE_DATA(name.m_queue), NULL, NULL}
 Data part of a static mutex initializer.
#define MUTEX_DECL(name)   Mutex name = _MUTEX_DATA(name)
 Static mutex initializer.

Typedefs

typedef struct Mutex Mutex
 Mutex structure.

Function Documentation

void chMtxInit ( Mutex mp)

Initializes s Mutex structure.

Parameters:
[out]mppointer to a Mutex structure
Function Class:
Initializer, this function just initializes an object and can be invoked before the kernel is initialized.

Definition at line 86 of file chmtx.c.

References chDbgCheck, Mutex::m_owner, Mutex::m_queue, and queue_init.

Referenced by _heap_init(), adcObjectInit(), chHeapInit(), i2cObjectInit(), and spiObjectInit().

void chMtxLock ( Mutex mp)

Locks the specified mutex.

Postcondition:
The mutex is locked and inserted in the per-thread stack of owned mutexes.
Parameters:
[in]mppointer to the Mutex structure
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 103 of file chmtx.c.

References chMtxLockS(), chSysLock, and chSysUnlock.

Referenced by adcAcquireBus(), i2cAcquireBus(), and spiAcquireBus().

Here is the call graph for this function:

void chMtxLockS ( Mutex mp)

Locks the specified mutex.

Postcondition:
The mutex is locked and inserted in the per-thread stack of owned mutexes.
Parameters:
[in]mppointer to the Mutex structure
Function Class:
This is an S-Class API, this function can be invoked from within a system lock zone by threads only.

Definition at line 121 of file chmtx.c.

References chDbgAssert, chDbgCheck, chDbgCheckClassS(), chSchGoSleepS(), chSchReadyI(), currp, dequeue(), Mutex::m_next, Mutex::m_owner, Mutex::m_queue, Thread::p_mtxlist, Thread::p_prio, Thread::p_state, prio_insert(), THD_STATE_CURRENT, THD_STATE_READY, THD_STATE_SNDMSGQ, THD_STATE_WTCOND, THD_STATE_WTMTX, THD_STATE_WTSEM, and Thread::wtobjp.

Referenced by chCondWaitS(), chCondWaitTimeoutS(), and chMtxLock().

Here is the call graph for this function:

bool_t chMtxTryLock ( Mutex mp)

Tries to lock a mutex.

This function attempts to lock a mutex, if the mutex is already locked by another thread then the function exits without waiting.

Postcondition:
The mutex is locked and inserted in the per-thread stack of owned mutexes.
Note:
This function does not have any overhead related to the priority inheritance mechanism because it does not try to enter a sleep state.
Parameters:
[in]mppointer to the Mutex structure
Returns:
The operation status.
Return values:
TRUEif the mutex has been successfully acquired
FALSEif the lock attempt failed.
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 206 of file chmtx.c.

References chMtxTryLockS(), chSysLock, and chSysUnlock.

Here is the call graph for this function:

bool_t chMtxTryLockS ( Mutex mp)

Tries to lock a mutex.

This function attempts to lock a mutex, if the mutex is already taken by another thread then the function exits without waiting.

Postcondition:
The mutex is locked and inserted in the per-thread stack of owned mutexes.
Note:
This function does not have any overhead related to the priority inheritance mechanism because it does not try to enter a sleep state.
Parameters:
[in]mppointer to the Mutex structure
Returns:
The operation status.
Return values:
TRUEif the mutex has been successfully acquired
FALSEif the lock attempt failed.
Function Class:
This is an S-Class API, this function can be invoked from within a system lock zone by threads only.

Definition at line 234 of file chmtx.c.

References chDbgCheck, chDbgCheckClassS(), currp, FALSE, Mutex::m_next, Mutex::m_owner, and TRUE.

Referenced by chMtxTryLock().

Here is the call graph for this function:

Mutex * chMtxUnlock ( void  )

Unlocks the next owned mutex in reverse lock order.

Precondition:
The invoking thread must have at least one owned mutex.
Postcondition:
The mutex is unlocked and removed from the per-thread stack of owned mutexes.
Returns:
A pointer to the unlocked mutex.
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 257 of file chmtx.c.

References chDbgAssert, chMtxQueueNotEmptyS, chSchWakeupS(), chSysLock, chSysUnlock, currp, fifo_remove(), Mutex::m_next, Mutex::m_owner, Mutex::m_queue, Thread::p_mtxlist, ThreadsQueue::p_next, Thread::p_prio, Thread::p_realprio, and RDY_OK.

Referenced by adcReleaseBus(), i2cReleaseBus(), and spiReleaseBus().

Here is the call graph for this function:

Mutex * chMtxUnlockS ( void  )

Unlocks the next owned mutex in reverse lock order.

Precondition:
The invoking thread must have at least one owned mutex.
Postcondition:
The mutex is unlocked and removed from the per-thread stack of owned mutexes.
This function does not reschedule so a call to a rescheduling function must be performed before unlocking the kernel.
Returns:
A pointer to the unlocked mutex.
Function Class:
This is an S-Class API, this function can be invoked from within a system lock zone by threads only.

Definition at line 317 of file chmtx.c.

References chDbgAssert, chDbgCheckClassS(), chMtxQueueNotEmptyS, chSchReadyI(), currp, fifo_remove(), Mutex::m_next, Mutex::m_owner, Mutex::m_queue, Thread::p_mtxlist, ThreadsQueue::p_next, Thread::p_prio, and Thread::p_realprio.

Referenced by chCondWaitS(), and chCondWaitTimeoutS().

Here is the call graph for this function:

void chMtxUnlockAll ( void  )

Unlocks all the mutexes owned by the invoking thread.

Postcondition:
The stack of owned mutexes is emptied and all the found mutexes are unlocked.
Note:
This function is MUCH MORE efficient than releasing the mutexes one by one and not just because the call overhead, this function does not have any overhead related to the priority inheritance mechanism.
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 374 of file chmtx.c.

References chMtxQueueNotEmptyS, chSchReadyI(), chSchRescheduleS(), chSysLock, chSysUnlock, currp, fifo_remove(), Mutex::m_next, Mutex::m_owner, Mutex::m_queue, Thread::p_mtxlist, Thread::p_prio, and Thread::p_realprio.

Here is the call graph for this function:


Define Documentation

#define _MUTEX_DATA (   name)    {_THREADSQUEUE_DATA(name.m_queue), NULL, NULL}

Data part of a static mutex initializer.

This macro should be used when statically initializing a mutex that is part of a bigger structure.

Parameters:
[in]namethe name of the mutex variable

Definition at line 75 of file chmtx.h.

#define MUTEX_DECL (   name)    Mutex name = _MUTEX_DATA(name)

Static mutex initializer.

Statically initialized mutexes require no explicit initialization using chMtxInit().

Parameters:
[in]namethe name of the mutex variable

Definition at line 84 of file chmtx.h.

#define chMtxQueueNotEmptyS (   mp)    notempty(&(mp)->m_queue)

Returns TRUE if the mutex queue contains at least a waiting thread.

Function Class:
This is an S-Class API, this function can be invoked from within a system lock zone by threads only.

Definition at line 96 of file chmtx.h.

Referenced by chMtxUnlock(), chMtxUnlockAll(), and chMtxUnlockS().


Typedef Documentation

typedef struct Mutex Mutex

Mutex structure.