Sfoglia il codice sorgente

Merge pull request #10859 from liamwhite/no-more-atomic-wait

general: remove atomic signal and wait
liamwhite 3 anni fa
parent
commit
a674022434

+ 1 - 1
src/common/thread.h

@@ -55,7 +55,7 @@ public:
         is_set = false;
     }
 
-    [[nodiscard]] bool IsSet() {
+    [[nodiscard]] bool IsSet() const {
         return is_set;
     }
 

+ 4 - 10
src/core/hle/service/nvnflinger/nvnflinger.cpp

@@ -43,14 +43,10 @@ void Nvnflinger::SplitVSync(std::stop_token stop_token) {
     Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
 
     while (!stop_token.stop_requested()) {
-        vsync_signal.wait(false);
-        vsync_signal.store(false);
-
-        guard->lock();
+        vsync_signal.Wait();
 
+        const auto lock_guard = Lock();
         Compose();
-
-        guard->unlock();
     }
 }
 
@@ -69,9 +65,8 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
         "ScreenComposition",
         [this](std::uintptr_t, s64 time,
                std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
-            vsync_signal.store(true);
             { const auto lock_guard = Lock(); }
-            vsync_signal.notify_one();
+            vsync_signal.Set();
             return std::chrono::nanoseconds(GetNextTicks());
         });
 
@@ -97,8 +92,7 @@ Nvnflinger::~Nvnflinger() {
     if (system.IsMulticore()) {
         system.CoreTiming().UnscheduleEvent(multi_composition_event, {});
         vsync_thread.request_stop();
-        vsync_signal.store(true);
-        vsync_signal.notify_all();
+        vsync_signal.Set();
     } else {
         system.CoreTiming().UnscheduleEvent(single_composition_event, {});
     }

+ 2 - 1
src/core/hle/service/nvnflinger/nvnflinger.h

@@ -12,6 +12,7 @@
 
 #include "common/common_types.h"
 #include "common/polyfill_thread.h"
+#include "common/thread.h"
 #include "core/hle/result.h"
 #include "core/hle/service/kernel_helpers.h"
 
@@ -143,7 +144,7 @@ private:
 
     Core::System& system;
 
-    std::atomic<bool> vsync_signal;
+    Common::Event vsync_signal;
 
     std::jthread vsync_thread;
 

+ 2 - 5
src/core/hle/service/server_manager.cpp

@@ -44,7 +44,7 @@ ServerManager::~ServerManager() {
     m_event->Signal();
 
     // Wait for processing to stop.
-    m_stopped.wait(false);
+    m_stopped.Wait();
     m_threads.clear();
 
     // Clean up ports.
@@ -182,10 +182,7 @@ void ServerManager::StartAdditionalHostThreads(const char* name, size_t num_thre
 }
 
 Result ServerManager::LoopProcess() {
-    SCOPE_EXIT({
-        m_stopped.store(true);
-        m_stopped.notify_all();
-    });
+    SCOPE_EXIT({ m_stopped.Set(); });
 
     R_RETURN(this->LoopProcessImpl());
 }

+ 2 - 2
src/core/hle/service/server_manager.h

@@ -3,7 +3,6 @@
 
 #pragma once
 
-#include <atomic>
 #include <functional>
 #include <list>
 #include <map>
@@ -12,6 +11,7 @@
 #include <vector>
 
 #include "common/polyfill_thread.h"
+#include "common/thread.h"
 #include "core/hle/result.h"
 #include "core/hle/service/mutex.h"
 
@@ -82,7 +82,7 @@ private:
     std::list<RequestState> m_deferrals{};
 
     // Host state tracking
-    std::atomic<bool> m_stopped{};
+    Common::Event m_stopped{};
     std::vector<std::jthread> m_threads{};
     std::stop_source m_stop_source{};
 };

+ 9 - 13
src/video_core/renderer_vulkan/vk_master_semaphore.cpp

@@ -75,15 +75,9 @@ void MasterSemaphore::Refresh() {
 
 void MasterSemaphore::Wait(u64 tick) {
     if (!semaphore) {
-        // If we don't support timeline semaphores, use an atomic wait
-        while (true) {
-            u64 current_value = gpu_tick.load(std::memory_order_relaxed);
-            if (current_value >= tick) {
-                return;
-            }
-            gpu_tick.wait(current_value);
-        }
-
+        // If we don't support timeline semaphores, wait for the value normally
+        std::unique_lock lk{free_mutex};
+        free_cv.wait(lk, [&] { return gpu_tick.load(std::memory_order_relaxed) >= tick; });
         return;
     }
 
@@ -198,11 +192,13 @@ void MasterSemaphore::WaitThread(std::stop_token token) {
 
         fence.Wait();
         fence.Reset();
-        gpu_tick.store(host_tick);
-        gpu_tick.notify_all();
 
-        std::scoped_lock lock{free_mutex};
-        free_queue.push_front(std::move(fence));
+        {
+            std::scoped_lock lock{free_mutex};
+            free_queue.push_front(std::move(fence));
+            gpu_tick.store(host_tick);
+        }
+        free_cv.notify_one();
     }
 }
 

+ 1 - 0
src/video_core/renderer_vulkan/vk_master_semaphore.h

@@ -72,6 +72,7 @@ private:
     std::atomic<u64> current_tick{1}; ///< Current logical tick.
     std::mutex wait_mutex;
     std::mutex free_mutex;
+    std::condition_variable free_cv;
     std::condition_variable_any wait_cv;
     std::queue<Waitable> wait_queue;  ///< Queue for the fences to be waited on by the wait thread.
     std::deque<vk::Fence> free_queue; ///< Holds available fences for submission.

+ 2 - 4
src/yuzu/bootmanager.cpp

@@ -105,14 +105,12 @@ void EmuThread::run() {
         std::unique_lock lk{m_should_run_mutex};
         if (m_should_run) {
             m_system.Run();
-            m_is_running.store(true);
-            m_is_running.notify_all();
+            m_stopped.Reset();
 
             Common::CondvarWait(m_should_run_cv, lk, stop_token, [&] { return !m_should_run; });
         } else {
             m_system.Pause();
-            m_is_running.store(false);
-            m_is_running.notify_all();
+            m_stopped.Set();
 
             EmulationPaused(lk);
             Common::CondvarWait(m_should_run_cv, lk, stop_token, [&] { return m_should_run; });

+ 3 - 4
src/yuzu/bootmanager.h

@@ -3,7 +3,6 @@
 
 #pragma once
 
-#include <atomic>
 #include <condition_variable>
 #include <cstddef>
 #include <memory>
@@ -88,7 +87,7 @@ public:
 
         // Wait until paused, if pausing.
         if (!should_run) {
-            m_is_running.wait(true);
+            m_stopped.Wait();
         }
     }
 
@@ -97,7 +96,7 @@ public:
      * @return True if the emulation thread is running, otherwise false
      */
     bool IsRunning() const {
-        return m_is_running.load() || m_should_run;
+        return m_should_run;
     }
 
     /**
@@ -118,7 +117,7 @@ private:
     std::stop_source m_stop_source;
     std::mutex m_should_run_mutex;
     std::condition_variable_any m_should_run_cv;
-    std::atomic<bool> m_is_running{false};
+    Common::Event m_stopped;
     bool m_should_run{true};
 
 signals: