mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
named_thread: implement "default" event loop
Fixup "sleepy" thread at startup on Windows. Permit threads which lack operator()() overload.
This commit is contained in:
parent
29e7eda887
commit
3aaa0172d5
@ -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;
|
||||
|
@ -42,6 +42,8 @@ class need_wakeup {};
|
||||
template <class Context>
|
||||
class named_thread;
|
||||
|
||||
class thread_base;
|
||||
|
||||
template <typename Ctx, typename X = void, typename... Args>
|
||||
struct result_storage
|
||||
{
|
||||
@ -234,7 +236,7 @@ public:
|
||||
}
|
||||
|
||||
// Wait for both thread sync var and provided atomic var
|
||||
template <typename T, atomic_wait::op op = atomic_wait::op::eq, typename U>
|
||||
template <atomic_wait::op Op = atomic_wait::op::eq, typename T, typename U>
|
||||
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<Context>, thread_base
|
||||
if constexpr (result::empty)
|
||||
{
|
||||
// No result
|
||||
Context::operator()();
|
||||
if constexpr (std::is_invocable_v<Context>)
|
||||
{
|
||||
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);
|
||||
|
@ -377,8 +377,11 @@ int main(int argc, char** argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize TSC freq (in case it isn't)
|
||||
static_cast<void>(utils::get_tsc_freq());
|
||||
|
||||
// Initialize thread pool finalizer (on first use)
|
||||
named_thread("", []{})();
|
||||
static_cast<void>(named_thread("", [](int) {}));
|
||||
|
||||
static std::unique_ptr<logs::listener> log_file;
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user