Просмотр исходного кода

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.
lat9nq 3 лет назад
Родитель
Сommit
e34e1b1c95
2 измененных файлов с 14 добавлено и 5 удалено
  1. 11 4
      src/core/hle/kernel/k_thread.cpp
  2. 3 1
      src/core/hle/kernel/k_thread.h

+ 11 - 4
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) {

+ 3 - 1
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{};