diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_light_lock.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_light_lock.hpp index 0c0f601a7..0949a5902 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_light_lock.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_light_lock.hpp @@ -31,15 +31,18 @@ namespace ams::kern { MESOSPHERE_ASSERT_THIS(); const uintptr_t cur_thread = reinterpret_cast(GetCurrentThreadPointer()); + const uintptr_t cur_thread_tag = (cur_thread | 1); while (true) { uintptr_t old_tag = this->tag.load(std::memory_order_relaxed); while (!this->tag.compare_exchange_weak(old_tag, (old_tag == 0) ? cur_thread : old_tag | 1, std::memory_order_acquire)) { - /* ... */ + if ((old_tag | 1) == cur_thread_tag) { + return; + } } - if ((old_tag == 0) || ((old_tag | 1) == (cur_thread | 1))) { + if ((old_tag == 0) || ((old_tag | 1) == cur_thread_tag)) { break; } @@ -52,9 +55,11 @@ namespace ams::kern { const uintptr_t cur_thread = reinterpret_cast(GetCurrentThreadPointer()); uintptr_t expected = cur_thread; - if (!this->tag.compare_exchange_weak(expected, 0, std::memory_order_release)) { - this->UnlockSlowPath(cur_thread); - } + do { + if (expected != cur_thread) { + return this->UnlockSlowPath(cur_thread); + } + } while (!this->tag.compare_exchange_weak(expected, 0, std::memory_order_release)); } void LockSlowPath(uintptr_t owner, uintptr_t cur_thread); diff --git a/libraries/libmesosphere/source/kern_k_light_lock.cpp b/libraries/libmesosphere/source/kern_k_light_lock.cpp index 9f91d67bf..e0a317539 100644 --- a/libraries/libmesosphere/source/kern_k_light_lock.cpp +++ b/libraries/libmesosphere/source/kern_k_light_lock.cpp @@ -38,6 +38,7 @@ namespace ams::kern { if (AMS_LIKELY(cur_thread->GetState() == KThread::ThreadState_Runnable)) { cur_thread->SetState(KThread::ThreadState_Waiting); } + if (owner_thread->IsSuspended()) { owner_thread->ContinueIfHasKernelWaiters(); } @@ -75,6 +76,10 @@ namespace ams::kern { if (AMS_LIKELY(next_owner->GetState() == KThread::ThreadState_Waiting)) { next_owner->SetState(KThread::ThreadState_Runnable); } + + if (next_owner->IsSuspended()) { + next_owner->ContinueIfHasKernelWaiters(); + } } /* We may have unsuspended in the process of acquiring the lock, so we'll re-suspend now if so. */ diff --git a/libraries/libmesosphere/source/svc/kern_svc_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_memory.cpp index 7a8ec7891..fafee3650 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_memory.cpp @@ -95,9 +95,6 @@ namespace ams::kern::svc { } Result UnmapMemory(uintptr_t dst_address, uintptr_t src_address, size_t size) { - /* Log the call parameters for debugging. */ - MESOSPHERE_LOG("UnmapMemory(%zx, %zx, %zx)\n", dst_address, src_address, size); - /* Validate that addresses are page aligned. */ R_UNLESS(util::IsAligned(dst_address, PageSize), svc::ResultInvalidAddress()); R_UNLESS(util::IsAligned(src_address, PageSize), svc::ResultInvalidAddress());