ChibiOS/RT 7.0.5

Detailed Description

Mutexes related APIs and services.

Operation mode

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

  • Not owned (unlocked).
  • Owned by a thread (locked).

Operations defined for mutexes:

  • Lock: The mutex is checked, if the mutex is not owned by some other thread then it is associated to the locking thread else the thread is queued on the mutex in a list ordered by priority.
  • Unlock: The mutex is released by the owner and the highest priority thread waiting in the queue, if any, is resumed and made owner of the mutex.

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.
Collaboration diagram for Mutexes:

Data Structures

struct  ch_mutex
 Mutex structure. More...

Macros

#define __MUTEX_DATA(name)
 Data part of a static mutex initializer.
#define MUTEX_DECL(name)
 Static mutex initializer.

Typedefs

typedef struct ch_mutex mutex_t
 Type of a mutex structure.

Functions

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

Macro Definition Documentation

◆ __MUTEX_DATA

#define __MUTEX_DATA ( name)
Value:
{__CH_QUEUE_DATA(name.queue), NULL, NULL, 0}
#define __CH_QUEUE_DATA(name)
Data part of a static queue object initializer.
Definition chlists.h:117

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)
Value:
mutex_t name = __MUTEX_DATA(name)
#define __MUTEX_DATA(name)
Data part of a static mutex initializer.
Definition chmtx.h:81
struct ch_mutex mutex_t
Type of a mutex structure.
Definition chmtx.h:52

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:
Object or module nitializer function.

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(), __heap_init(), and chHeapObjectInit().

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 ch_queue_dequeue(), ch_sch_prio_insert(), CH_STATE_CURRENT, CH_STATE_READY, CH_STATE_SNDMSGQ, CH_STATE_WTCOND, CH_STATE_WTMTX, CH_STATE_WTSEM, chDbgAssert, chDbgCheck, chDbgCheckClassS, chSchGoSleepS(), chSchReadyI(), 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, ch_thread::queue, ch_thread::state, threadref, ch_thread::u, and ch_thread::wtmtxp.

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

Here is the call graph for this function:

◆ 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 chDbgAssert, chDbgCheck, chDbgCheckClassS, chThdGetSelfX(), ch_mutex::cnt, ch_thread::mtxlist, ch_mutex::next, and ch_mutex::owner.

Referenced by chMtxTryLock().

Here is the call graph for this function:

◆ 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, ch_thread::realprio, and threadref.

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 ch_queue_fifo_remove(), chDbgAssert, chDbgCheck, chDbgCheckClassS, chMtxQueueNotEmptyS(), chSchReadyI(), 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, ch_thread::realprio, and threadref.

Referenced by chCondWaitS(), and chCondWaitTimeoutS().

Here is the call graph for this function:

◆ 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, ch_thread::realprio, and threadref.

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()

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.

References ch_queue_notempty(), chDbgCheckClassS, and ch_mutex::queue.

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

Here is the call graph for this function:

◆ chMtxGetOwnerI()

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.

References chDbgCheckClassI, and ch_mutex::owner.

◆ chMtxGetNextMutexX()

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(), and ch_thread::mtxlist.

Referenced by chCondWaitS(), and chCondWaitTimeoutS().

Here is the call graph for this function: