forked from eden-emu/eden
		
	Merge pull request #10859 from liamwhite/no-more-atomic-wait
general: remove atomic signal and wait
This commit is contained in:
		
						commit
						fa8419f54e
					
				
					 9 changed files with 26 additions and 40 deletions
				
			
		|  | @ -55,7 +55,7 @@ public: | |||
|         is_set = false; | ||||
|     } | ||||
| 
 | ||||
|     [[nodiscard]] bool IsSet() { | ||||
|     [[nodiscard]] bool IsSet() const { | ||||
|         return is_set; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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, {}); | ||||
|     } | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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()); | ||||
| } | ||||
|  |  | |||
|  | @ -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{}; | ||||
| }; | ||||
|  |  | |||
|  | @ -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)); | ||||
|             gpu_tick.store(host_tick); | ||||
|         } | ||||
|         free_cv.notify_one(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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.
 | ||||
|  |  | |||
|  | @ -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,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: | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 liamwhite
						liamwhite