Skip to content

Commit 9169122

Browse files
committed
[kernel/mutex] fix waiter lifetime and wakeup races
Mutex waiters can race with timeout callbacks, mutex release, object deletions, and thread exit. A waiter may already be READY while its take path has not resumed, so clearing or reusing the mutex object at the wrong time can lead to stale accesses, incorrect error values, or corrupted priority-inheritance state. - Add rt_mutex_timeout_waiter() to detach a timed-out waiter while the scheduler is locked. Update the mutex priority and the owner priority before the waiter is inserted into the ready queue. - Use rt_sched_thread_ready() to arbitrate timeout, release, and delete wakeups. This prevents two paths from claiming the same waiter and lets mutex release skip a waiter whose timeout callback owns the wakeup. - Keep thread->pending_object pointing to the mutex after release hands ownership to a waiter. The pointer is used as an in-flight handoff token until _rt_mutex_take() completes its wakeup handling. - Consume the handoff token under the scheduler lock before touching the mutex. Clear the token only after the handoff is validated, and return RT_EINTR for an unexpected resume that did not grant ownership. - Clear the handoff token and set RT_ERROR before deleting or detaching the mutex. This prevents the resumed waiter from dereferencing an object whose storage has already been released or reused. - Handle the handoff token during thread exit so a handed-off owner is not incorrectly removed from the mutex wait list. - Add regression tests covering dynamic and static mutex deletion, timeout-to-READY races, timeout and release races, timeout-owned release heads, cross-thread owner cleanup, and post-handoff deletion. The mutex structure and ABI remain unchanged. The internal timeout waiter interface is exposed only to kernel and IPC sources. Verified on QEMU with core.mutex using SMP with 2 CPUs, UP with 1 CPU, and SMP with 1 CPU with RT_DEBUGING_ASSERT and RT_DEBUGING_CRITICAL enabled. Signed-off-by: Hui Su <3164683437@qq.com>
1 parent bf38ee2 commit 9169122

4 files changed

Lines changed: 1004 additions & 145 deletions

File tree

‎include/rtthread.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,10 @@ rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag);
466466
rt_err_t rt_mutex_delete(rt_mutex_t mutex);
467467
#endif /* RT_USING_HEAP */
468468
void rt_mutex_drop_thread(rt_mutex_t mutex, rt_thread_t thread);
469+
#if defined(__RT_KERNEL_SOURCE__) || defined(__RT_IPC_SOURCE__)
470+
void rt_mutex_drop_thread_locked(rt_mutex_t mutex, rt_thread_t thread);
471+
rt_bool_t rt_mutex_timeout_waiter(rt_thread_t thread);
472+
#endif /* defined(__RT_KERNEL_SOURCE__) || defined(__RT_IPC_SOURCE__) */
469473
rt_uint8_t rt_mutex_setprioceiling(rt_mutex_t mutex, rt_uint8_t priority);
470474
rt_uint8_t rt_mutex_getprioceiling(rt_mutex_t mutex);
471475

0 commit comments

Comments
 (0)