ChibiOS  21.6.0
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 must always be performed in lock-reverse order. This restriction both improves the performance and is required for an efficient implementation of the priority inheritance mechanism.
Operating under this restriction also ensures that deadlocks are no possible.

Recursive mode

By default mutexes are not recursive, this mean that it is not possible to take a mutex already owned by the same thread. It is possible to enable the recursive behavior by enabling the option CH_CFG_USE_MUTEXES_RECURSIVE.

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_CFG_USE_MUTEXES option must be enabled in chconf.h.
Postcondition
Enabling mutexes requires 5-12 (depending on the architecture) extra bytes in the thread_t structure.

Macros

#define __MUTEX_DATA(name)   {__CH_QUEUE_DATA(name.queue), NULL, NULL, 0}
 Data part of a static mutex initializer. More...
 
#define MUTEX_DECL(name)   mutex_t name = __MUTEX_DATA(name)
 Static mutex initializer. More...
 

Typedefs

typedef struct ch_mutex mutex_t
 Type of a mutex structure. More...
 

Data Structures

struct  ch_mutex
 Mutex structure. More...
 

Functions

void chMtxObjectInit (mutex_t *mp)
 Initializes s mutex_t structure. More...
 
void chMtxLock (mutex_t *mp)
 Locks the specified mutex. More...
 
void chMtxLockS (mutex_t *mp)
 Locks the specified mutex. More...
 
bool chMtxTryLock (mutex_t *mp)
 Tries to lock a mutex. More...
 
bool chMtxTryLockS (mutex_t *mp)
 Tries to lock a mutex. More...
 
void chMtxUnlock (mutex_t *mp)
 Unlocks the specified mutex. More...
 
void chMtxUnlockS (mutex_t *mp)
 Unlocks the specified mutex. More...
 
void chMtxUnlockAllS (void)
 Unlocks all mutexes owned by the invoking thread. More...
 
void chMtxUnlockAll (void)
 Unlocks all mutexes owned by the invoking thread. More...
 
static bool chMtxQueueNotEmptyS (mutex_t *mp)
 Returns true if the mutex queue contains at least a waiting thread. More...
 
static thread_tchMtxGetOwnerI (mutex_t *mp)
 Returns the mutex owner thread. More...
 
static mutex_tchMtxGetNextMutexX (void)
 Returns the next mutex in the mutexes stack of the current thread. More...
 

Macro Definition Documentation

◆ __MUTEX_DATA

#define __MUTEX_DATA (   name)    {__CH_QUEUE_DATA(name.queue), NULL, NULL, 0}

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 81 of file chmtx.h.

◆ MUTEX_DECL

#define MUTEX_DECL (   name)    mutex_t 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 93 of file chmtx.h.

Typedef Documentation

◆ mutex_t

typedef struct ch_mutex mutex_t

Type of a mutex structure.

Definition at line 52 of file chmtx.h.

Function Documentation

◆ chMtxObjectInit()

void chMtxObjectInit ( mutex_t mp)

Initializes s mutex_t structure.

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

Definition at line 103 of file chmtx.c.

References ch_queue_init(), chDbgCheck, ch_mutex::cnt, ch_mutex::owner, and ch_mutex::queue.

Referenced by __factory_init().

Here is the call graph for this function:

◆ chMtxLock()

void chMtxLock ( mutex_t 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_t structure
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 123 of file chmtx.c.

References chMtxLockS(), chSysLock, and chSysUnlock.

Here is the call graph for this function:

◆ chMtxLockS()

void chMtxLockS ( mutex_t 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_t 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 139 of file chmtx.c.

References chThdGetSelfX.

Referenced by chMtxLock().

◆ chMtxTryLock()

bool chMtxTryLock ( mutex_t 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_t 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 257 of file chmtx.c.

References chMtxTryLockS(), chSysLock, and chSysUnlock.

Here is the call graph for this function:

◆ chMtxTryLockS()

bool chMtxTryLockS ( mutex_t 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_t 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 284 of file chmtx.c.

References chThdGetSelfX.

Referenced by chMtxTryLock().

◆ chMtxUnlock()

void chMtxUnlock ( mutex_t mp)

Unlocks the specified mutex.

Note
Mutexes must be unlocked in reverse lock order. Violating this rules will result in a panic if assertions are enabled.
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.
Parameters
[in]mppointer to the mutex_t structure
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 326 of file chmtx.c.

References ch_queue_fifo_remove(), chDbgAssert, chDbgCheck, chMtxQueueNotEmptyS(), chSchReadyI(), chSchRescheduleS(), chSysLock, chSysUnlock, chThdGetSelfX, ch_mutex::cnt, ch_thread::hdr, ch_thread::mtxlist, ch_mutex::next, ch_queue::next, ch_mutex::owner, ch_thread::pqueue, ch_priority_queue::prio, ch_mutex::queue, and ch_thread::realprio.

Here is the call graph for this function:

◆ chMtxUnlockS()

void chMtxUnlockS ( mutex_t mp)

Unlocks the specified mutex.

Note
Mutexes must be unlocked in reverse lock order. Violating this rules will result in a panic if assertions are enabled.
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.
Parameters
[in]mppointer to the mutex_t 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 413 of file chmtx.c.

References chThdGetSelfX.

◆ chMtxUnlockAllS()

void chMtxUnlockAllS ( void  )

Unlocks all mutexes owned by the invoking thread.

Postcondition
The stack of owned mutexes is emptied and all the found mutexes are unlocked.
This function does not reschedule so a call to a rescheduling function must be performed before unlocking the kernel.
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:
This is an S-Class API, this function can be invoked from within a system lock zone by threads only.

Definition at line 490 of file chmtx.c.

References ch_queue_fifo_remove(), chMtxQueueNotEmptyS(), chSchReadyI(), chSchRescheduleS(), chThdGetSelfX, ch_mutex::cnt, ch_thread::hdr, ch_thread::mtxlist, ch_mutex::next, ch_mutex::owner, ch_thread::pqueue, ch_priority_queue::prio, ch_mutex::queue, and ch_thread::realprio.

Referenced by chMtxUnlockAll().

Here is the call graph for this function:

◆ chMtxUnlockAll()

void chMtxUnlockAll ( void  )

Unlocks all 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 531 of file chmtx.c.

References chMtxUnlockAllS(), chSysLock, and chSysUnlock.

Here is the call graph for this function:

◆ chMtxQueueNotEmptyS()

static bool chMtxQueueNotEmptyS ( mutex_t mp)
inlinestatic

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

Parameters
[out]mppointer to a mutex_t structure
Returns
The mutex queue status.
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 128 of file chmtx.h.

Referenced by chMtxUnlock(), and chMtxUnlockAllS().

◆ chMtxGetOwnerI()

static thread_t* chMtxGetOwnerI ( mutex_t mp)
inlinestatic

Returns the mutex owner thread.

Parameters
[out]mppointer to a mutex_t structure
Returns
The owner thread.
Return values
NULLif the mutex is not owned.
Function Class:
This is an I-Class API, this function can be invoked from within a system lock zone by both threads and interrupt handlers.

Definition at line 144 of file chmtx.h.

◆ chMtxGetNextMutexX()

static mutex_t* chMtxGetNextMutexX ( void  )
inlinestatic

Returns the next mutex in the mutexes stack of the current thread.

Returns
A pointer to the next mutex in the stack.
Return values
NULLif the stack is empty.
Function Class:
This is an X-Class API, this function can be invoked from any context.

Definition at line 159 of file chmtx.h.

References chThdGetSelfX.

Referenced by chCondWaitS(), and chCondWaitTimeoutS().