From 3aaa0172d54f2e7082e337fe83840effc32421e0 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 24 Feb 2021 13:56:02 +0300 Subject: [PATCH] named_thread: implement "default" event loop Fixup "sleepy" thread at startup on Windows. Permit threads which lack operator()() overload. --- Utilities/Thread.cpp | 4 +--- Utilities/Thread.h | 21 +++++++++++++++++---- rpcs3/main.cpp | 5 ++++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 12ab58c18d..9f7c4c1f10 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -2336,16 +2336,14 @@ bool thread_base::join(bool dtor) const if (i > 20 && Emu.IsStopped()) { - stamp0 = __rdtsc(); atomic_wait_engine::raw_notify(0, get_native_id()); - stamp0 = __rdtsc() - stamp0; warn = true; } } if (warn) { - sig_log.error(u8"Thread [%s] is too sleepy. Took %.3fµs to wake it up!", *m_tname.load(), stamp0 / (utils::get_tsc_freq() / 1000000.)); + sig_log.error(u8"Thread [%s] is too sleepy. Took %.3fµs to wake it up!", *m_tname.load(), (__rdtsc() - stamp0) / (utils::get_tsc_freq() / 1000000.)); } return (m_sync & 3) == 3; diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 1b67009ca4..9e09fdacbc 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -42,6 +42,8 @@ class need_wakeup {}; template class named_thread; +class thread_base; + template struct result_storage { @@ -234,7 +236,7 @@ public: } // Wait for both thread sync var and provided atomic var - template + template static inline void wait_on(T& wait, U old, u64 usec = -1) { auto _this = g_tls_this_thread; @@ -245,7 +247,7 @@ public: } atomic_wait::list<2> list{}; - list.set<0, op>(wait, old); + list.set<0, Op>(wait, old); list.set<1>(_this->m_sync, 0, 4 + 1); list.wait(atomic_wait_timeout{usec <= 0xffff'ffff'ffff'ffff / 1000 ? usec * 1000 : 0xffff'ffff'ffff'ffff}); } @@ -329,12 +331,23 @@ class named_thread final : public Context, result_storage, thread_base if constexpr (result::empty) { // No result - Context::operator()(); + if constexpr (std::is_invocable_v) + { + Context::operator()(); + } + else + { + // Default event loop + while (thread_ctrl::state() != thread_state::aborting) + { + thread_ctrl::wait(); + } + } } else { // Construct the result using placement new (copy elision should happen) - new (result::get()) typename result::type(Context::operator()()); + new (result::get()) decltype(auto)(Context::operator()()); } return thread::finalize(thread_state::finished); diff --git a/rpcs3/main.cpp b/rpcs3/main.cpp index 97f8698869..baf2fa5fd4 100644 --- a/rpcs3/main.cpp +++ b/rpcs3/main.cpp @@ -377,8 +377,11 @@ int main(int argc, char** argv) } #endif + // Initialize TSC freq (in case it isn't) + static_cast(utils::get_tsc_freq()); + // Initialize thread pool finalizer (on first use) - named_thread("", []{})(); + static_cast(named_thread("", [](int) {})); static std::unique_ptr log_file; {