Core: Centralize the async task queue

Will be needed for multithreaded shader compilation, and it was
duplicated code anyway.
pull/3732/head
Stenzek 5 months ago
parent 348eaeef6f
commit 735dc5ba2a
No known key found for this signature in database

@ -28,6 +28,7 @@
#include "common/path.h"
#include "common/ryml_helpers.h"
#include "common/string_util.h"
#include "common/task_queue.h"
#include "common/threading.h"
#include "common/timer.h"
@ -49,6 +50,9 @@ LOG_CHANNEL(Core);
namespace Core {
/// Use two async worker threads, should be enough for most tasks.
static constexpr u32 NUM_ASYNC_WORKER_THREADS = 2;
static bool SetAppRootAndResources(const char* resources_subdir, Error* error);
static bool SetDataRoot(Error* error);
static void SetDefaultSettings(SettingsInterface& si, bool host, bool system, bool controller);
@ -66,6 +70,8 @@ struct CoreLocals
Threading::ThreadHandle core_thread_handle;
Timer::Value process_start_time = 0;
TaskQueue async_task_queue;
};
} // namespace
@ -695,7 +701,7 @@ void Core::ProcessShutdown()
System::ReleasePersistentMemory();
}
bool Core::CoreThreadInitialize(Error* error)
bool Core::CoreThreadInitialize(bool disable_worker_threads, Error* error)
{
#ifdef _WIN32
// On Win32, we have a bunch of things which use COM (e.g. SDL, Cubeb, etc).
@ -711,6 +717,9 @@ bool Core::CoreThreadInitialize(Error* error)
s_locals.core_thread_handle = Threading::ThreadHandle::GetForCallingThread();
if (!disable_worker_threads)
s_locals.async_task_queue.SetWorkerCount(NUM_ASYNC_WORKER_THREADS);
System::LoadSettings(false);
LogStartupInformation();
@ -729,6 +738,8 @@ bool Core::CoreThreadInitialize(Error* error)
void Core::CoreThreadShutdown()
{
s_locals.async_task_queue.SetWorkerCount(0);
#ifdef ENABLE_DISCORD_PRESENCE
DiscordPresence::Shutdown();
#endif
@ -760,6 +771,16 @@ bool Host::IsOnCoreThread()
return Core::s_locals.core_thread_handle.IsCallingThread();
}
void Host::QueueAsyncTask(std::function<void()> function)
{
Core::s_locals.async_task_queue.SubmitTask(std::move(function));
}
void Host::WaitForAllAsyncTasks()
{
Core::s_locals.async_task_queue.WaitForAll();
}
float Core::GetProcessUptime()
{
return static_cast<float>(Timer::ConvertValueToSeconds(Timer::GetCurrentValue() - s_locals.process_start_time));

@ -42,7 +42,7 @@ bool ProcessStartup(Error* error);
void ProcessShutdown();
/// Called on CPU thread initialization.
bool CoreThreadInitialize(Error* error);
bool CoreThreadInitialize(bool disable_worker_threads, Error* error);
/// Called on CPU thread shutdown.
void CoreThreadShutdown();

@ -46,7 +46,6 @@
#include "common/path.h"
#include "common/scoped_guard.h"
#include "common/string_util.h"
#include "common/task_queue.h"
#include "common/threading.h"
#include "util/audio_stream.h"
@ -106,9 +105,6 @@ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU", "About %1")
static constexpr u32 SETTINGS_SAVE_DELAY = 1000;
/// Use two async worker threads, should be enough for most tasks.
static constexpr u32 NUM_ASYNC_WORKER_THREADS = 2;
/// Interval at which the controllers are polled when the system is not active.
static constexpr int BACKGROUND_CONTROLLER_POLLING_INTERVAL_WITH_DEVICES = 100;
static constexpr int BACKGROUND_CONTROLLER_POLLING_INTERVAL_WITHOUT_DEVICES = 1000;
@ -180,7 +176,6 @@ struct State
} // namespace
ALIGN_TO_CACHE_LINE static State s_state;
ALIGN_TO_CACHE_LINE static TaskQueue s_async_task_queue;
} // namespace QtHost
@ -1712,16 +1707,6 @@ void Host::RunOnUIThread(std::function<void()> function, bool block /* = false*/
block ? Qt::BlockingQueuedConnection : Qt::QueuedConnection, std::move(function));
}
void Host::QueueAsyncTask(std::function<void()> function)
{
QtHost::s_async_task_queue.SubmitTask(std::move(function));
}
void Host::WaitForAllAsyncTasks()
{
QtHost::s_async_task_queue.WaitForAll();
}
QtAsyncTask::QtAsyncTask(WorkCallback callback)
{
m_callback = std::move(callback);
@ -2218,7 +2203,7 @@ void CoreThread::run()
// input source setup must happen on emu thread
{
Error startup_error;
if (!Core::CoreThreadInitialize(&startup_error))
if (!Core::CoreThreadInitialize(false, &startup_error))
{
moveToThread(m_ui_thread);
Host::ReportFatalError("Fatal Startup Error", startup_error.GetDescription());
@ -2226,10 +2211,6 @@ void CoreThread::run()
}
}
// start up worker threads
// TODO: Replace this with QThreads
QtHost::s_async_task_queue.SetWorkerCount(NUM_ASYNC_WORKER_THREADS);
// connections
connect(qApp, &QGuiApplication::applicationStateChanged, this, &CoreThread::applicationStateChanged);
@ -2266,9 +2247,6 @@ void CoreThread::run()
destroyBackgroundControllerPollTimer();
// join worker threads
QtHost::s_async_task_queue.SetWorkerCount(0);
// and tidy up everything left
Core::CoreThreadShutdown();

@ -36,7 +36,6 @@
#include "common/path.h"
#include "common/sha256_digest.h"
#include "common/string_util.h"
#include "common/task_queue.h"
#include "common/threading.h"
#include "common/time_helpers.h"
#include "common/timer.h"
@ -71,7 +70,6 @@ struct RegTestHostState
};
static RegTestHostState s_state;
ALIGN_TO_CACHE_LINE static TaskQueue s_async_task_queue;
} // namespace RegTestHost
@ -365,16 +363,6 @@ void Host::RunOnUIThread(std::function<void()> function, bool block /* = false *
RunOnCoreThread(std::move(function), block);
}
void Host::QueueAsyncTask(std::function<void()> function)
{
RegTestHost::s_async_task_queue.SubmitTask(std::move(function));
}
void Host::WaitForAllAsyncTasks()
{
RegTestHost::s_async_task_queue.WaitForAll();
}
void Host::RequestResizeHostDisplay(s32 width, s32 height)
{
//
@ -989,15 +977,12 @@ int main(int argc, char* argv[])
if (!RegTestHost::SetNewDataRoot(autoboot->path))
return EXIT_FAILURE;
if (!Core::CoreThreadInitialize(&error))
if (!Core::CoreThreadInitialize(true, &error))
{
ERROR_LOG("CoreThreadInitialize() failed: {}", error.GetDescription());
return EXIT_FAILURE;
}
// Only one async worker, keep the CPU usage down so we can parallelize execution of regtest itself.
RegTestHost::s_async_task_queue.SetWorkerCount(1);
RegTestHost::HookSignals();
int result = -1;
@ -1045,8 +1030,6 @@ int main(int argc, char* argv[])
result = 0;
cleanup:
RegTestHost::s_async_task_queue.SetWorkerCount(0);
RegTestHost::ProcessCoreThreadEvents();
Core::CoreThreadShutdown();
Core::ProcessShutdown();

Loading…
Cancel
Save