From 73f9904f2aa7f49ed81d790d43b60b5533bfe32a Mon Sep 17 00:00:00 2001 From: mitaclaw <140017135+mitaclaw@users.noreply.github.com> Date: Fri, 22 Mar 2024 00:43:04 -0700 Subject: [PATCH] Core: Remove RunAsCPUThread It's a fine function, but CPUThreadGuard is more vogue. Also, its potential for being confused with RunOnCPUThread will not be missed. --- Source/Android/jni/MainAndroid.cpp | 1 - Source/Core/Core/AchievementManager.cpp | 20 ++++++------- Source/Core/Core/AchievementManager.h | 5 ++-- Source/Core/Core/Core.cpp | 22 +++----------- Source/Core/Core/Core.h | 20 +++---------- Source/Core/Core/HW/Wiimote.cpp | 3 +- .../Core/Core/HW/WiimoteReal/WiimoteReal.cpp | 21 +++++++------- Source/Core/Core/PowerPC/JitInterface.cpp | 29 +++++++++---------- Source/Core/DolphinQt/Host.cpp | 6 ++-- Source/Core/DolphinQt/Main.cpp | 2 +- Source/Core/DolphinQt/MainWindow.cpp | 26 ++++++++--------- 11 files changed, 64 insertions(+), 91 deletions(-) diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index 5f8f71a08b..c6f9ba0cb1 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -515,7 +515,6 @@ Java_org_dolphinemu_dolphinemu_NativeLibrary_UpdateGCAdapterScanThread(JNIEnv*, JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Initialize(JNIEnv*, jclass) { - // InitControllers ends up calling config code, and some config callbacks use RunAsCPUThread HostThreadLock guard; UICommon::CreateDirectories(); diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index 41dfac879a..9bb3bcddc2 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -689,7 +689,7 @@ void AchievementManager::DoFrame() time_t current_time = std::time(nullptr); if (difftime(current_time, m_last_ping_time) > 120) { - GenerateRichPresence(); + GenerateRichPresence(Core::CPUThreadGuard{*m_system}); m_queue.EmplaceItem([this] { PingRichPresence(m_rich_presence); }); m_last_ping_time = current_time; m_update_callback(); @@ -1341,17 +1341,15 @@ void AchievementManager::ActivateDeactivateAchievement(AchievementId id, bool en rc_runtime_deactivate_achievement(&m_runtime, id); } -void AchievementManager::GenerateRichPresence() +void AchievementManager::GenerateRichPresence(const Core::CPUThreadGuard& guard) { - Core::RunAsCPUThread([&] { - std::lock_guard lg{m_lock}; - rc_runtime_get_richpresence( - &m_runtime, m_rich_presence.data(), RP_SIZE, - [](unsigned address, unsigned num_bytes, void* ud) { - return static_cast(ud)->MemoryPeeker(address, num_bytes, ud); - }, - this, nullptr); - }); + std::lock_guard lg{m_lock}; + rc_runtime_get_richpresence( + &m_runtime, m_rich_presence.data(), RP_SIZE, + [](unsigned address, unsigned num_bytes, void* ud) { + return static_cast(ud)->MemoryPeeker(address, num_bytes, ud); + }, + this, nullptr); } AchievementManager::ResponseType AchievementManager::AwardAchievement(AchievementId achievement_id) diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index 7d6c9441b1..770e64c18c 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -23,8 +23,9 @@ namespace Core { +class CPUThreadGuard; class System; -} +} // namespace Core namespace OSD { @@ -180,7 +181,7 @@ private: std::unique_ptr& GetLoadingVolume() { return m_loading_volume; }; void ActivateDeactivateAchievement(AchievementId id, bool enabled, bool unofficial, bool encore); - void GenerateRichPresence(); + void GenerateRichPresence(const Core::CPUThreadGuard& guard); ResponseType AwardAchievement(AchievementId achievement_id); ResponseType SubmitLeaderboard(AchievementId leaderboard_id, int value); diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 565ff0d2eb..9a5242706d 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -788,14 +788,14 @@ static std::string GenerateScreenshotName() void SaveScreenShot() { - Core::RunAsCPUThread([] { g_frame_dumper->SaveScreenshot(GenerateScreenshotName()); }); + const Core::CPUThreadGuard guard(Core::System::GetInstance()); + g_frame_dumper->SaveScreenshot(GenerateScreenshotName()); } void SaveScreenShot(std::string_view name) { - Core::RunAsCPUThread([&name] { - g_frame_dumper->SaveScreenshot(fmt::format("{}{}.png", GenerateScreenshotFolderPath(), name)); - }); + const Core::CPUThreadGuard guard(Core::System::GetInstance()); + g_frame_dumper->SaveScreenshot(fmt::format("{}{}.png", GenerateScreenshotFolderPath(), name)); } static bool PauseAndLock(Core::System& system, bool do_lock, bool unpause_on_unlock) @@ -837,20 +837,6 @@ static bool PauseAndLock(Core::System& system, bool do_lock, bool unpause_on_unl return was_unpaused; } -void RunAsCPUThread(std::function function) -{ - auto& system = Core::System::GetInstance(); - const bool is_cpu_thread = IsCPUThread(); - bool was_unpaused = false; - if (!is_cpu_thread) - was_unpaused = PauseAndLock(system, true, true); - - function(); - - if (!is_cpu_thread) - PauseAndLock(system, false, was_unpaused); -} - void RunOnCPUThread(std::function function, bool wait_for_completion) { // If the CPU thread is not running, assume there is no active CPU thread we can race against. diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h index 1f9baa35b3..7564511573 100644 --- a/Source/Core/Core/Core.h +++ b/Source/Core/Core/Core.h @@ -94,13 +94,10 @@ enum class ConsoleType : u32 ReservedTDEVSystem = 0x20000007, }; -// Run a function as the CPU thread. This is an RAII alternative to the RunAsCPUThread function. -// -// If constructed from the Host thread, the CPU thread is paused and the current thread temporarily -// becomes the CPU thread. -// If constructed from the CPU thread, nothing special happens. -// -// This should only be constructed from the CPU thread or the host thread. +// This is an RAII alternative to using PauseAndLock. If constructed from the host thread, the CPU +// thread is paused, and the current thread temporarily becomes the CPU thread. If constructed from +// the CPU thread, nothing special happens. This should only be constructed on the CPU thread or the +// host thread. // // Some functions use a parameter of this type to indicate that the function should only be called // from the CPU thread. If the parameter is a pointer, the function has a fallback for being called @@ -158,15 +155,6 @@ void DisplayMessage(std::string message, int time_in_ms); void FrameUpdateOnCPUThread(); void OnFrameEnd(Core::System& system); -// Run a function as the CPU thread. -// -// If called from the Host thread, the CPU thread is paused and the current thread temporarily -// becomes the CPU thread while running the function. -// If called from the CPU thread, the function will be run directly. -// -// This should only be called from the CPU thread or the host thread. -void RunAsCPUThread(std::function function); - // Run a function on the CPU thread, asynchronously. // This is only valid to call from the host thread, since it uses PauseAndLock() internally. void RunOnCPUThread(std::function function, bool wait_for_completion); diff --git a/Source/Core/Core/HW/Wiimote.cpp b/Source/Core/Core/HW/Wiimote.cpp index 2fa2270635..4b9e95e34d 100644 --- a/Source/Core/Core/HW/Wiimote.cpp +++ b/Source/Core/Core/HW/Wiimote.cpp @@ -50,7 +50,8 @@ void OnSourceChanged(unsigned int index, WiimoteSource source) WiimoteReal::HandleWiimoteSourceChange(index); - Core::RunAsCPUThread([index] { WiimoteCommon::UpdateSource(index); }); + const Core::CPUThreadGuard guard(Core::System::GetInstance()); + WiimoteCommon::UpdateSource(index); } void RefreshConfig() diff --git a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp index c376f536fe..e6ef006f40 100644 --- a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp @@ -947,10 +947,11 @@ static bool TryToConnectWiimoteToSlot(std::unique_ptr& wm, unsigned int led_report.leds = u8(1 << (i % WIIMOTE_BALANCE_BOARD)); wm->QueueReport(led_report); - Core::RunAsCPUThread([i, &wm] { + { + const Core::CPUThreadGuard guard(Core::System::GetInstance()); g_wiimotes[i] = std::move(wm); WiimoteCommon::UpdateSource(i); - }); + } NOTICE_LOG_FMT(WIIMOTE, "Connected real wiimote to slot {}.", i + 1); @@ -967,12 +968,11 @@ static void TryToConnectBalanceBoard(std::unique_ptr wm) static void HandleWiimoteDisconnect(int index) { - Core::RunAsCPUThread([index] { - // The Wii Remote object must exist through the call to UpdateSource - // to prevent WiimoteDevice from having a dangling HIDWiimote pointer. - const auto temp_real_wiimote = std::move(g_wiimotes[index]); - WiimoteCommon::UpdateSource(index); - }); + const Core::CPUThreadGuard guard(Core::System::GetInstance()); + // The Wii Remote object must exist through the call to UpdateSource + // to prevent WiimoteDevice from having a dangling HIDWiimote pointer. + const auto temp_real_wiimote = std::move(g_wiimotes[index]); + WiimoteCommon::UpdateSource(index); } // This is called from the GUI thread @@ -1004,10 +1004,11 @@ void HandleWiimoteSourceChange(unsigned int index) { std::lock_guard wm_lk(g_wiimotes_mutex); - Core::RunAsCPUThread([index] { + { + const Core::CPUThreadGuard guard(Core::System::GetInstance()); if (auto removed_wiimote = std::move(g_wiimotes[index])) AddWiimoteToPool(std::move(removed_wiimote)); - }); + } g_controller_interface.PlatformPopulateDevices([] { ProcessWiimotePool(); }); } diff --git a/Source/Core/Core/PowerPC/JitInterface.cpp b/Source/Core/Core/PowerPC/JitInterface.cpp index 5073f297ae..8372bf302a 100644 --- a/Source/Core/Core/PowerPC/JitInterface.cpp +++ b/Source/Core/Core/PowerPC/JitInterface.cpp @@ -160,22 +160,21 @@ void JitInterface::GetProfileResults(Profiler::ProfileStats* prof_stats) const prof_stats->timecost_sum = 0; prof_stats->block_stats.clear(); - Core::RunAsCPUThread([this, &prof_stats] { - QueryPerformanceFrequency((LARGE_INTEGER*)&prof_stats->countsPerSec); - m_jit->GetBlockCache()->RunOnBlocks([&prof_stats](const JitBlock& block) { - const auto& data = block.profile_data; - u64 cost = data.downcountCounter; - u64 timecost = data.ticCounter; - // Todo: tweak. - if (data.runCount >= 1) - prof_stats->block_stats.emplace_back(block.effectiveAddress, cost, timecost, data.runCount, - block.codeSize); - prof_stats->cost_sum += cost; - prof_stats->timecost_sum += timecost; - }); - - sort(prof_stats->block_stats.begin(), prof_stats->block_stats.end()); + const Core::CPUThreadGuard guard(m_system); + QueryPerformanceFrequency((LARGE_INTEGER*)&prof_stats->countsPerSec); + m_jit->GetBlockCache()->RunOnBlocks([&prof_stats](const JitBlock& block) { + const auto& data = block.profile_data; + u64 cost = data.downcountCounter; + u64 timecost = data.ticCounter; + // Todo: tweak. + if (data.runCount >= 1) + prof_stats->block_stats.emplace_back(block.effectiveAddress, cost, timecost, data.runCount, + block.codeSize); + prof_stats->cost_sum += cost; + prof_stats->timecost_sum += timecost; }); + + sort(prof_stats->block_stats.begin(), prof_stats->block_stats.end()); } std::variant diff --git a/Source/Core/DolphinQt/Host.cpp b/Source/Core/DolphinQt/Host.cpp index c7f7c1d6fb..6cc4b952ed 100644 --- a/Source/Core/DolphinQt/Host.cpp +++ b/Source/Core/DolphinQt/Host.cpp @@ -112,9 +112,9 @@ static void RunWithGPUThreadInactive(std::function f) } else { - // If we reach here, we can call Core::PauseAndLock (which we do using RunAsCPUThread). - - Core::RunAsCPUThread(std::move(f)); + // If we reach here, we can call Core::PauseAndLock (which we do using a CPUThreadGuard). + const Core::CPUThreadGuard guard(Core::System::GetInstance()); + f(); } } diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp index 52f1583309..6ea70886ee 100644 --- a/Source/Core/DolphinQt/Main.cpp +++ b/Source/Core/DolphinQt/Main.cpp @@ -52,7 +52,7 @@ static bool QtMsgAlertHandler(const char* caption, const char* text, bool yes_no std::optional r = RunOnObject(QApplication::instance(), [&] { // If we were called from the CPU/GPU thread, set us as the CPU/GPU thread. // This information is used in order to avoid deadlocks when calling e.g. - // Host::SetRenderFocus or Core::RunAsCPUThread. (Host::SetRenderFocus + // Host::SetRenderFocus or Core::CPUThreadGuard. (Host::SetRenderFocus // can get called automatically when a dialog steals the focus.) Common::ScopeGuard cpu_scope_guard(&Core::UndeclareAsCPUThread); diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index 576759bd52..4b70c1cb79 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -1932,12 +1932,13 @@ void MainWindow::OnStopRecording() void MainWindow::OnExportRecording() { - Core::RunAsCPUThread([this] { - QString dtm_file = DolphinFileDialog::getSaveFileName( - this, tr("Save Recording File As"), QString(), tr("Dolphin TAS Movies (*.dtm)")); - if (!dtm_file.isEmpty()) - Core::System::GetInstance().GetMovie().SaveRecording(dtm_file.toStdString()); - }); + auto& system = Core::System::GetInstance(); + const Core::CPUThreadGuard guard(system); + + QString dtm_file = DolphinFileDialog::getSaveFileName( + this, tr("Save Recording File As"), QString(), tr("Dolphin TAS Movies (*.dtm)")); + if (!dtm_file.isEmpty()) + system.GetMovie().SaveRecording(dtm_file.toStdString()); } void MainWindow::OnActivateChat() @@ -1990,13 +1991,12 @@ void MainWindow::ShowTASInput() void MainWindow::OnConnectWiiRemote(int id) { - Core::RunAsCPUThread([&] { - if (const auto bt = WiiUtils::GetBluetoothEmuDevice()) - { - const auto wm = bt->AccessWiimoteByIndex(id); - wm->Activate(!wm->IsConnected()); - } - }); + const Core::CPUThreadGuard guard(Core::System::GetInstance()); + if (const auto bt = WiiUtils::GetBluetoothEmuDevice()) + { + const auto wm = bt->AccessWiimoteByIndex(id); + wm->Activate(!wm->IsConnected()); + } } #ifdef USE_RETRO_ACHIEVEMENTS