1.. _mutexes_v2:
2
3Mutexes
4#######
5
6A :dfn:`mutex` is a kernel object that implements a traditional
7reentrant mutex. A mutex allows multiple threads to safely share
8an associated hardware or software resource by ensuring mutually exclusive
9access to the resource.
10
11.. contents::
12    :local:
13    :depth: 2
14
15Concepts
16********
17
18Any number of mutexes can be defined (limited only by available RAM). Each mutex
19is referenced by its memory address.
20
21A mutex has the following key properties:
22
23* A **lock count** that indicates the number of times the mutex has been locked
24  by the thread that has locked it. A count of zero indicates that the mutex
25  is unlocked.
26
27* An **owning thread** that identifies the thread that has locked the mutex,
28  when it is locked.
29
30A mutex must be initialized before it can be used. This sets its lock count
31to zero.
32
33A thread that needs to use a shared resource must first gain exclusive rights
34to access it by **locking** the associated mutex. If the mutex is already locked
35by another thread, the requesting thread may choose to wait for the mutex
36to be unlocked.
37
38After locking a mutex, the thread may safely use the associated resource
39for as long as needed; however, it is considered good practice to hold the lock
40for as short a time as possible to avoid negatively impacting other threads
41that want to use the resource. When the thread no longer needs the resource
42it must **unlock** the mutex to allow other threads to use the resource.
43
44Any number of threads may wait on a locked mutex simultaneously.
45When the mutex becomes unlocked it is then locked by the highest-priority
46thread that has waited the longest.
47
48.. note::
49    Mutex objects are *not* designed for use by ISRs.
50
51Reentrant Locking
52=================
53
54A thread is permitted to lock a mutex it has already locked.
55This allows the thread to access the associated resource at a point
56in its execution when the mutex may or may not already be locked.
57
58A mutex that is repeatedly locked by a thread must be unlocked an equal number
59of times before the mutex becomes fully unlocked so it can be claimed
60by another thread.
61
62Priority Inheritance
63====================
64
65The thread that has locked a mutex is eligible for :dfn:`priority inheritance`.
66This means the kernel will *temporarily* elevate the thread's priority
67if a higher priority thread begins waiting on the mutex. This allows the owning
68thread to complete its work and release the mutex more rapidly by executing
69at the same priority as the waiting thread. Once the mutex has been unlocked,
70the unlocking thread resets its priority to the level it had before locking
71that mutex.
72
73.. note::
74    The :kconfig:option:`CONFIG_PRIORITY_CEILING` configuration option limits
75    how high the kernel can raise a thread's priority due to priority
76    inheritance. The default value of 0 permits unlimited elevation.
77
78The owning thread's base priority is saved in the mutex when it obtains the
79lock. Each time a higher priority thread waits on a mutex, the kernel adjusts
80the owning thread's priority. When the owning thread releases the lock (or if
81the high priority waiting thread times out), the kernel restores the thread's
82base priority from the value saved in the mutex.
83
84This works well for priority inheritance as long as only one locked mutex is
85involved. However, if multiple mutexes are involved, sub-optimal behavior will
86be observed if the mutexes are not unlocked in the reverse order to which the
87owning thread's priority was previously raised. Consequently it is recommended
88that a thread lock only a single mutex at a time when multiple mutexes are
89shared between threads of different priorities.
90
91Implementation
92**************
93
94Defining a Mutex
95================
96
97A mutex is defined using a variable of type :c:struct:`k_mutex`.
98It must then be initialized by calling :c:func:`k_mutex_init`.
99
100The following code defines and initializes a mutex.
101
102.. code-block:: c
103
104    struct k_mutex my_mutex;
105
106    k_mutex_init(&my_mutex);
107
108Alternatively, a mutex can be defined and initialized at compile time
109by calling :c:macro:`K_MUTEX_DEFINE`.
110
111The following code has the same effect as the code segment above.
112
113.. code-block:: c
114
115    K_MUTEX_DEFINE(my_mutex);
116
117Locking a Mutex
118===============
119
120A mutex is locked by calling :c:func:`k_mutex_lock`.
121
122The following code builds on the example above, and waits indefinitely
123for the mutex to become available if it is already locked by another thread.
124
125.. code-block:: c
126
127    k_mutex_lock(&my_mutex, K_FOREVER);
128
129The following code waits up to 100 milliseconds for the mutex to become
130available, and gives a warning if the mutex does not become available.
131
132.. code-block:: c
133
134    if (k_mutex_lock(&my_mutex, K_MSEC(100)) == 0) {
135        /* mutex successfully locked */
136    } else {
137        printf("Cannot lock XYZ display\n");
138    }
139
140Unlocking a Mutex
141=================
142
143A mutex is unlocked by calling :c:func:`k_mutex_unlock`.
144
145The following code builds on the example above,
146and unlocks the mutex that was previously locked by the thread.
147
148.. code-block:: c
149
150    k_mutex_unlock(&my_mutex);
151
152Suggested Uses
153**************
154
155Use a mutex to provide exclusive access to a resource, such as a physical
156device.
157
158Configuration Options
159*********************
160
161Related configuration options:
162
163* :kconfig:option:`CONFIG_PRIORITY_CEILING`
164
165API Reference
166*************
167
168.. doxygengroup:: mutex_apis
169
170Futex API Reference
171*******************
172
173k_futex is a lightweight mutual exclusion primitive designed to minimize
174kernel involvement. Uncontended operation relies only on atomic access
175to shared memory. k_futex are tracked as kernel objects and can live in
176user memory so that any access bypasses the kernel object permission
177management mechanism.
178
179.. doxygengroup:: futex_apis
180
181User Mode Mutex API Reference
182*****************************
183
184sys_mutex behaves almost exactly like k_mutex, with the added advantage
185that a sys_mutex instance can reside in user memory. When user mode isn't
186enabled, sys_mutex behaves like k_mutex.
187
188.. doxygengroup:: user_mutex_apis
189