Lines Matching full:mutex
8 * @file @brief mutex kernel services
10 * This module contains routines for handling mutex locking and unlocking.
14 * priority thread waiting on the mutex.
16 * Each mutex that contributes to priority inheritance must be released in the
17 * reverse order in which it was acquired. Furthermore each subsequent mutex
22 * priority level, the second mutex M2 must be acquired by thread A after
23 * thread A's priority level was bumped due to owning the first mutex M1.
24 * When releasing the mutex, thread A must release M2 before it releases M1.
55 int z_impl_k_mutex_init(struct k_mutex *mutex) in z_impl_k_mutex_init() argument
57 mutex->owner = NULL; in z_impl_k_mutex_init()
58 mutex->lock_count = 0U; in z_impl_k_mutex_init()
60 z_waitq_init(&mutex->wait_q); in z_impl_k_mutex_init()
62 k_object_init(mutex); in z_impl_k_mutex_init()
65 k_obj_core_init_and_link(K_OBJ_CORE(mutex), &obj_type_mutex); in z_impl_k_mutex_init()
68 SYS_PORT_TRACING_OBJ_INIT(k_mutex, mutex, 0); in z_impl_k_mutex_init()
74 static inline int z_vrfy_k_mutex_init(struct k_mutex *mutex) in z_vrfy_k_mutex_init() argument
76 K_OOPS(K_SYSCALL_OBJ_INIT(mutex, K_OBJ_MUTEX)); in z_vrfy_k_mutex_init()
77 return z_impl_k_mutex_init(mutex); in z_vrfy_k_mutex_init()
91 static bool adjust_owner_prio(struct k_mutex *mutex, int32_t new_prio) in adjust_owner_prio() argument
93 if (mutex->owner->base.prio != new_prio) { in adjust_owner_prio()
96 mutex->owner, z_is_thread_ready(mutex->owner) ? in adjust_owner_prio()
98 new_prio, mutex->owner->base.prio); in adjust_owner_prio()
100 return z_thread_prio_set(mutex->owner, new_prio); in adjust_owner_prio()
105 int z_impl_k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout) in z_impl_k_mutex_lock() argument
113 SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_mutex, lock, mutex, timeout); in z_impl_k_mutex_lock()
117 if (likely((mutex->lock_count == 0U) || (mutex->owner == arch_current_thread()))) { in z_impl_k_mutex_lock()
119 mutex->owner_orig_prio = (mutex->lock_count == 0U) ? in z_impl_k_mutex_lock()
121 mutex->owner_orig_prio; in z_impl_k_mutex_lock()
123 mutex->lock_count++; in z_impl_k_mutex_lock()
124 mutex->owner = arch_current_thread(); in z_impl_k_mutex_lock()
126 LOG_DBG("%p took mutex %p, count: %d, orig prio: %d", in z_impl_k_mutex_lock()
127 arch_current_thread(), mutex, mutex->lock_count, in z_impl_k_mutex_lock()
128 mutex->owner_orig_prio); in z_impl_k_mutex_lock()
132 SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_mutex, lock, mutex, timeout, 0); in z_impl_k_mutex_lock()
140 SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_mutex, lock, mutex, timeout, -EBUSY); in z_impl_k_mutex_lock()
145 SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_mutex, lock, mutex, timeout); in z_impl_k_mutex_lock()
148 mutex->owner->base.prio); in z_impl_k_mutex_lock()
150 LOG_DBG("adjusting prio up on mutex %p", mutex); in z_impl_k_mutex_lock()
152 if (z_is_prio_higher(new_prio, mutex->owner->base.prio)) { in z_impl_k_mutex_lock()
153 resched = adjust_owner_prio(mutex, new_prio); in z_impl_k_mutex_lock()
156 int got_mutex = z_pend_curr(&lock, key, &mutex->wait_q, timeout); in z_impl_k_mutex_lock()
158 LOG_DBG("on mutex %p got_mutex value: %d", mutex, got_mutex); in z_impl_k_mutex_lock()
160 LOG_DBG("%p got mutex %p (y/n): %c", arch_current_thread(), mutex, in z_impl_k_mutex_lock()
164 SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_mutex, lock, mutex, timeout, 0); in z_impl_k_mutex_lock()
170 LOG_DBG("%p timeout on mutex %p", arch_current_thread(), mutex); in z_impl_k_mutex_lock()
175 * Check if mutex was unlocked after this thread was unpended. in z_impl_k_mutex_lock()
178 if (likely(mutex->owner != NULL)) { in z_impl_k_mutex_lock()
179 struct k_thread *waiter = z_waitq_head(&mutex->wait_q); in z_impl_k_mutex_lock()
182 new_prio_for_inheritance(waiter->base.prio, mutex->owner_orig_prio) : in z_impl_k_mutex_lock()
183 mutex->owner_orig_prio; in z_impl_k_mutex_lock()
185 LOG_DBG("adjusting prio down on mutex %p", mutex); in z_impl_k_mutex_lock()
187 resched = adjust_owner_prio(mutex, new_prio) || resched; in z_impl_k_mutex_lock()
196 SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_mutex, lock, mutex, timeout, -EAGAIN); in z_impl_k_mutex_lock()
202 static inline int z_vrfy_k_mutex_lock(struct k_mutex *mutex, in z_vrfy_k_mutex_lock() argument
205 K_OOPS(K_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); in z_vrfy_k_mutex_lock()
206 return z_impl_k_mutex_lock(mutex, timeout); in z_vrfy_k_mutex_lock()
211 int z_impl_k_mutex_unlock(struct k_mutex *mutex) in z_impl_k_mutex_unlock() argument
217 SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_mutex, unlock, mutex); in z_impl_k_mutex_unlock()
219 CHECKIF(mutex->owner == NULL) { in z_impl_k_mutex_unlock()
220 SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_mutex, unlock, mutex, -EINVAL); in z_impl_k_mutex_unlock()
225 * The current thread does not own the mutex. in z_impl_k_mutex_unlock()
227 CHECKIF(mutex->owner != arch_current_thread()) { in z_impl_k_mutex_unlock()
228 SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_mutex, unlock, mutex, -EPERM); in z_impl_k_mutex_unlock()
234 * Attempt to unlock a mutex which is unlocked. mutex->lock_count in z_impl_k_mutex_unlock()
235 * cannot be zero if the current thread is equal to mutex->owner, in z_impl_k_mutex_unlock()
239 __ASSERT_NO_MSG(mutex->lock_count > 0U); in z_impl_k_mutex_unlock()
241 LOG_DBG("mutex %p lock_count: %d", mutex, mutex->lock_count); in z_impl_k_mutex_unlock()
247 if (mutex->lock_count > 1U) { in z_impl_k_mutex_unlock()
248 mutex->lock_count--; in z_impl_k_mutex_unlock()
254 adjust_owner_prio(mutex, mutex->owner_orig_prio); in z_impl_k_mutex_unlock()
257 new_owner = z_unpend_first_thread(&mutex->wait_q); in z_impl_k_mutex_unlock()
259 mutex->owner = new_owner; in z_impl_k_mutex_unlock()
261 LOG_DBG("new owner of mutex %p: %p (prio: %d)", in z_impl_k_mutex_unlock()
262 mutex, new_owner, new_owner ? new_owner->base.prio : -1000); in z_impl_k_mutex_unlock()
270 mutex->owner_orig_prio = new_owner->base.prio; in z_impl_k_mutex_unlock()
275 mutex->lock_count = 0U; in z_impl_k_mutex_unlock()
281 SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_mutex, unlock, mutex, 0); in z_impl_k_mutex_unlock()
287 static inline int z_vrfy_k_mutex_unlock(struct k_mutex *mutex) in z_vrfy_k_mutex_unlock() argument
289 K_OOPS(K_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); in z_vrfy_k_mutex_unlock()
290 return z_impl_k_mutex_unlock(mutex); in z_vrfy_k_mutex_unlock()
298 /* Initialize mutex object type */ in init_mutex_obj_core_list()
305 STRUCT_SECTION_FOREACH(k_mutex, mutex) { in init_mutex_obj_core_list()
306 k_obj_core_init_and_link(K_OBJ_CORE(mutex), &obj_type_mutex); in init_mutex_obj_core_list()