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