From 90aafeedc1d980849894f5bf251313db95594e8a Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 17 Sep 2026 00:28:37 +0200 Subject: [PATCH] [k_scheduler] fix for libc++ that lazily initializes mutexes (#4447) `__m_` is nullptr when `unlock();` is called, so `try_lock();` will force materialization of the backing mutex. Signed-off-by: lizzie - [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions). - [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md) - [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability. ------------------- Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4447 Reviewed-by: CamilleLaVey Reviewed-by: MaranBr --- src/core/hle/kernel/k_scheduler.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 8e629f6456..3156a17064 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -465,6 +465,10 @@ void KScheduler::ScheduleImplFiber(KernelCore& kernel) { // Check if we need scheduling. If we do, then we can't complete the switch and should // retry. if (m_state.needs_scheduling.load(std::memory_order_seq_cst)) { + // Some libc++ lazily init mutex + [[maybe_unused]] auto const can_lock = highest_priority_thread->m_context_guard.try_lock(); + DEBUG_ASSERT(!can_lock); + // Our switch failed. // We should unlock the thread context, and then retry. highest_priority_thread->m_context_guard.unlock(); @@ -496,6 +500,10 @@ void KScheduler::Unload(KernelCore& kernel, KThread* thread) { // Check if the thread is terminated by checking the DPC flags. if ((thread->GetStackParameters().dpc_flags & static_cast(DpcFlag::Terminated)) == 0) { + // Some libc++ lazily init mutex + [[maybe_unused]] auto const can_lock = thread->m_context_guard.try_lock(); + DEBUG_ASSERT(!can_lock); + // The thread isn't terminated, so we want to unlock it. thread->m_context_guard.unlock(); }