From 1d99f4f758d9353ac7e0ff0944ea3152c035de28 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Sat, 5 Oct 2024 21:58:26 +0200 Subject: [PATCH] core/mutex: use thread_yield_higher() in mutex_unlock() Using `sched_switch()` in `mutex_unlock()` can result in crashes when `mutex_unlock()` is called from IRQ context. This however is a common pattern in RIOT to wake up a thread from IRQ. The reason for the crash is that `sched_switch()` assumes `thread_get_active()` to always return a non-`NULL` value. But when thread-less idle is used, no thread may be active after the last runnable thread exited. Using `thread_yield_higher()` instead solves the issue, as `thread_yield_higher()` is safe to call from IRQ context without an active thread. This fixes https://github.com/RIOT-OS/RIOT/issues/20812 --- core/mutex.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/mutex.c b/core/mutex.c index 6c8db0385e..4e2502d1bd 100644 --- a/core/mutex.c +++ b/core/mutex.c @@ -216,8 +216,6 @@ void mutex_unlock(mutex_t *mutex) mutex->queue.next = MUTEX_LOCKED; } - uint16_t process_priority = process->priority; - #if IS_USED(MODULE_CORE_MUTEX_PRIORITY_INHERITANCE) thread_t *owner = thread_get(mutex->owner); if ((owner) && (owner->priority != mutex->owner_original_priority)) { @@ -232,7 +230,7 @@ void mutex_unlock(mutex_t *mutex) #endif irq_restore(irqstate); - sched_switch(process_priority); + thread_yield_higher(); } void mutex_unlock_and_sleep(mutex_t *mutex)