From e34e1b1c95779e7d569fa03120d0a6083f0864ee Mon Sep 17 00:00:00 2001
From: lat9nq <22451773+lat9nq@users.noreply.github.com>
Date: Sat, 17 Jun 2023 00:36:00 -0400
Subject: [PATCH] k_thread: Use a mutex and cond_var to sync bool

std::atomic<bool> is broken on MinGW and causes deadlocks there.
Use a normal cond var in its stead.
---
 src/core/hle/kernel/k_thread.cpp | 15 +++++++++++----
 src/core/hle/kernel/k_thread.h   |  4 +++-
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 70480b7258..908811e2c7 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -4,6 +4,8 @@
 #include <algorithm>
 #include <atomic>
 #include <cinttypes>
+#include <condition_variable>
+#include <mutex>
 #include <optional>
 #include <vector>
 
@@ -1313,7 +1315,8 @@ void KThread::RequestDummyThreadWait() {
     ASSERT(this->IsDummyThread());
 
     // We will block when the scheduler lock is released.
-    m_dummy_thread_runnable.store(false);
+    std::scoped_lock lock{m_dummy_thread_mutex};
+    m_dummy_thread_runnable = false;
 }
 
 void KThread::DummyThreadBeginWait() {
@@ -1323,7 +1326,8 @@ void KThread::DummyThreadBeginWait() {
     }
 
     // Block until runnable is no longer false.
-    m_dummy_thread_runnable.wait(false);
+    std::unique_lock lock{m_dummy_thread_mutex};
+    m_dummy_thread_cv.wait(lock, [this] { return m_dummy_thread_runnable; });
 }
 
 void KThread::DummyThreadEndWait() {
@@ -1331,8 +1335,11 @@ void KThread::DummyThreadEndWait() {
     ASSERT(this->IsDummyThread());
 
     // Wake up the waiting thread.
-    m_dummy_thread_runnable.store(true);
-    m_dummy_thread_runnable.notify_one();
+    {
+        std::scoped_lock lock{m_dummy_thread_mutex};
+        m_dummy_thread_runnable = true;
+    }
+    m_dummy_thread_cv.notify_one();
 }
 
 void KThread::BeginWait(KThreadQueue* queue) {
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index f9814ac8f6..37fe5db77e 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -892,7 +892,9 @@ private:
     std::shared_ptr<Common::Fiber> m_host_context{};
     ThreadType m_thread_type{};
     StepState m_step_state{};
-    std::atomic<bool> m_dummy_thread_runnable{true};
+    bool m_dummy_thread_runnable{true};
+    std::mutex m_dummy_thread_mutex{};
+    std::condition_variable m_dummy_thread_cv{};
 
     // For debugging
     std::vector<KSynchronizationObject*> m_wait_objects_for_debugging{};