ChibiOS/RT  5.1.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)   {_THREADS_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 mutex_tchMtxGetNextMutexS (void)
 Returns the next mutex in the mutexes stack of the current thread. More...
 

Macro Definition Documentation

#define _MUTEX_DATA (   name)    {_THREADS_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.

#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

typedef struct ch_mutex mutex_t

Type of a mutex structure.

Definition at line 52 of file chmtx.h.

Function Documentation

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 chDbgCheck, ch_mutex::cnt, ch_mutex::owner, ch_mutex::queue, and queue_init().

Referenced by _factory_init(), _heap_init(), and chHeapObjectInit().

Here is the call graph for this function:

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:

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_STATE_CURRENT, CH_STATE_READY, CH_STATE_SNDMSGQ, CH_STATE_WTCOND, CH_STATE_WTMTX, CH_STATE_WTSEM, chDbgAssert, chDbgCheck, chDbgCheckClassS(), chSchGoSleepS(), chSchReadyI(), ch_mutex::cnt, currp, ch_thread::mtxlist, ch_mutex::next, ch_mutex::owner, ch_thread::prio, ch_mutex::queue, queue_dequeue(), queue_prio_insert(), ch_thread::state, ch_thread::u, and ch_thread::wtmtxp.

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

Here is the call graph for this function:

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 255 of file chmtx.c.

References chMtxTryLockS(), chSysLock(), and chSysUnlock().

Here is the call graph for this function:

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 282 of file chmtx.c.

References chDbgAssert, chDbgCheck, chDbgCheckClassS(), ch_mutex::cnt, currp, ch_mutex::next, and ch_mutex::owner.

Referenced by chMtxTryLock().

Here is the call graph for this function:

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 323 of file chmtx.c.

References chDbgAssert, chDbgCheck, chMtxQueueNotEmptyS(), chSchReadyI(), chSchRescheduleS(), chSysLock(), chSysUnlock(), ch_mutex::cnt, currp, ch_thread::mtxlist, ch_mutex::next, ch_threads_queue::next, ch_mutex::owner, ch_thread::prio, ch_mutex::queue, queue_fifo_remove(), and ch_thread::realprio.

Here is the call graph for this function:

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 410 of file chmtx.c.

References chDbgAssert, chDbgCheck, chDbgCheckClassS(), chMtxQueueNotEmptyS(), chSchReadyI(), ch_mutex::cnt, currp, ch_thread::mtxlist, ch_mutex::next, ch_threads_queue::next, ch_mutex::owner, ch_thread::prio, ch_mutex::queue, queue_fifo_remove(), and ch_thread::realprio.

Referenced by chCondWaitS(), and chCondWaitTimeoutS().

Here is the call graph for this function:

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 487 of file chmtx.c.

References chMtxQueueNotEmptyS(), chSchReadyI(), ch_mutex::cnt, currp, ch_thread::mtxlist, ch_mutex::next, ch_mutex::owner, ch_thread::prio, ch_mutex::queue, queue_fifo_remove(), and ch_thread::realprio.

Here is the call graph for this function:

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 524 of file chmtx.c.

References chMtxQueueNotEmptyS(), chSchReadyI(), chSchRescheduleS(), chSysLock(), chSysUnlock(), ch_mutex::cnt, currp, ch_thread::mtxlist, ch_mutex::next, ch_mutex::owner, ch_thread::prio, ch_mutex::queue, queue_fifo_remove(), and ch_thread::realprio.

Here is the call graph for this function:

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.
Deprecated:
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 129 of file chmtx.h.

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

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

Here is the call graph for this function:

static mutex_t* chMtxGetNextMutexS ( 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 S-Class API, this function can be invoked from within a system lock zone by threads only.

Definition at line 144 of file chmtx.h.

References chThdGetSelfX(), and ch_thread::mtxlist.

Referenced by chCondWaitS(), and chCondWaitTimeoutS().

Here is the call graph for this function: