mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
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
This commit is contained in:
parent
13188e13f2
commit
1d99f4f758
@ -216,8 +216,6 @@ void mutex_unlock(mutex_t *mutex)
|
|||||||
mutex->queue.next = MUTEX_LOCKED;
|
mutex->queue.next = MUTEX_LOCKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t process_priority = process->priority;
|
|
||||||
|
|
||||||
#if IS_USED(MODULE_CORE_MUTEX_PRIORITY_INHERITANCE)
|
#if IS_USED(MODULE_CORE_MUTEX_PRIORITY_INHERITANCE)
|
||||||
thread_t *owner = thread_get(mutex->owner);
|
thread_t *owner = thread_get(mutex->owner);
|
||||||
if ((owner) && (owner->priority != mutex->owner_original_priority)) {
|
if ((owner) && (owner->priority != mutex->owner_original_priority)) {
|
||||||
@ -232,7 +230,7 @@ void mutex_unlock(mutex_t *mutex)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
irq_restore(irqstate);
|
irq_restore(irqstate);
|
||||||
sched_switch(process_priority);
|
thread_yield_higher();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mutex_unlock_and_sleep(mutex_t *mutex)
|
void mutex_unlock_and_sleep(mutex_t *mutex)
|
||||||
|
Loading…
Reference in New Issue
Block a user