Mutex for thread synchronization.
More...
Mutex for thread synchronization.
Mutex Implementation Basics
Data Structures and Encoding
A mutex_t
contains basically a point, which can have one of the following values:
NULL
, in case it is unlocked
MUTEX_LOCKED
in case it is locked, but no other thread is waiting on it
- A pointer to the head of single linked list of threads (or more precisely their
thread_t
structures) blocked waiting for obtaining the mutex. This list is terminated by NULL
, not by MUTEX_LOCKED
The same information graphically:
Unlocked mutex:
+-------+
+-------+
Locked mutex, no waiters:
+-------+
|
Mutex | --> MUTEX_LOCKED
+-------+
Locked mutex, one waiter:
+-------+ +--------+
|
Mutex | --> | Waiter | --> NULL
+-------+ +--------+
Locked mutex, 2 waiters:
+-------+ +--------+ +--------+
|
Mutex | --> | Waiter | --> | Waiter | --> NULL
+-------+ +--------+ +--------+
Obtaining a Mutex
If a mutex_lock()
is called, one of the following happens:
- If the mutex was unlocked (value of
NULL
), its value is changed to MUTEX_LOCKED
and the call to mutex_lock()
returns right away without blocking.
- If the mutex as a vale of
MUTEX_LOCKED
, it will be changed to point to the thread_t
of the running thread. The single item list is terminated be setting the thread_t::rq_entry.next
of the running thread to NULL
. The running thread blocks as described below.
- Otherwise, the current thread is inserted into the list of waiting threads sorted by thread priority. The running thread blocks as described below.
In case 2) and 3), the running thread will mark itself as blocked (waiting for a mutex) and yields. Once control is transferred back to this thread (which is done in the call to mutex_unlock()
), it has the mutex and the function mutex_lock()
returns.
Returning a Mutex
If mutex_unlock()
is called, one of the following happens:
- If the mutex was already unlocked (value of
NULL
), the call returns without modifying the mutex.
- If the mutex was locked without waiters (value of
MUTEX_LOCKED
), it is unlocked by setting its value to NULL
.
- Otherwise the first
thread_t
from the linked list of waiters is removed from the list.
- This thread is the one with the highest priority, as the list is sorted by priority.
- This thread's status is set to pending and its added to the appropriate run queue.
- If that thread was the last item in the list, the mutex is set to
MUTEX_LOCK
.
- The scheduler is run, so that if the unblocked waiting thread can run now, in case it has a higher priority than the running thread.
◆ MUTEX_INIT
#define MUTEX_INIT { { NULL } } |
◆ mutex_init()
static void mutex_init |
( |
mutex_t * |
mutex | ) |
|
|
inlinestatic |
Initializes a mutex object.
For initialization of variables use MUTEX_INIT instead. Only use the function call for dynamically allocated mutexes.
- Parameters
-
[out] | mutex | pre-allocated mutex structure, must not be NULL. |
Definition at line 156 of file mutex.h.
◆ mutex_lock()
Locks a mutex, blocking.
- Parameters
-
[in,out] | mutex | Mutex object to lock. |
- Precondition
mutex
is not NULL
-
Mutex at
mutex
has been initialized
-
Must be called in thread context
- Postcondition
- The mutex
is
locked and held by the calling thread.
◆ mutex_trylock()
static int mutex_trylock |
( |
mutex_t * |
mutex | ) |
|
|
inlinestatic |
Tries to get a mutex, non-blocking.
- Parameters
-
[in,out] | mutex | Mutex object to lock. |
- Return values
-
1 | if mutex was unlocked, now it is locked. |
0 | if the mutex was locked. |
- Precondition
mutex
is not NULL
-
Mutex at
mutex
has been initialized
-
Must be called in thread context
Definition at line 173 of file mutex.h.
◆ mutex_unlock()
void mutex_unlock |
( |
mutex_t * |
mutex | ) |
|
Unlocks the mutex.
- Parameters
-
[in,out] | mutex | Mutex object to unlock. |
- Precondition
mutex
is not NULL
- Note
- It is safe to unlock a mutex held by a different thread.
-
It is safe to call this function from IRQ context.
◆ mutex_unlock_and_sleep()
void mutex_unlock_and_sleep |
( |
mutex_t * |
mutex | ) |
|
Unlocks the mutex and sends the current thread to sleep.
- Parameters
-
[in,out] | mutex | Mutex object to unlock. |
- Precondition
mutex
is not NULL
-
Must be called in thread context.