Merge pull request #12658 from mitaclaw/core-global-system-2b

Core: Remove RunAsCPUThread
This commit is contained in:
JMC47 2024-03-28 13:04:08 -04:00 committed by GitHub
commit aa9601a563
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 64 additions and 91 deletions

View File

@ -515,7 +515,6 @@ Java_org_dolphinemu_dolphinemu_NativeLibrary_UpdateGCAdapterScanThread(JNIEnv*,
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Initialize(JNIEnv*, jclass) 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; HostThreadLock guard;
UICommon::CreateDirectories(); UICommon::CreateDirectories();

View File

@ -689,7 +689,7 @@ void AchievementManager::DoFrame()
time_t current_time = std::time(nullptr); time_t current_time = std::time(nullptr);
if (difftime(current_time, m_last_ping_time) > 120) if (difftime(current_time, m_last_ping_time) > 120)
{ {
GenerateRichPresence(); GenerateRichPresence(Core::CPUThreadGuard{*m_system});
m_queue.EmplaceItem([this] { PingRichPresence(m_rich_presence); }); m_queue.EmplaceItem([this] { PingRichPresence(m_rich_presence); });
m_last_ping_time = current_time; m_last_ping_time = current_time;
m_update_callback(); m_update_callback();
@ -1341,17 +1341,15 @@ void AchievementManager::ActivateDeactivateAchievement(AchievementId id, bool en
rc_runtime_deactivate_achievement(&m_runtime, id); 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};
std::lock_guard lg{m_lock}; rc_runtime_get_richpresence(
rc_runtime_get_richpresence( &m_runtime, m_rich_presence.data(), RP_SIZE,
&m_runtime, m_rich_presence.data(), RP_SIZE, [](unsigned address, unsigned num_bytes, void* ud) {
[](unsigned address, unsigned num_bytes, void* ud) { return static_cast<AchievementManager*>(ud)->MemoryPeeker(address, num_bytes, ud);
return static_cast<AchievementManager*>(ud)->MemoryPeeker(address, num_bytes, ud); },
}, this, nullptr);
this, nullptr);
});
} }
AchievementManager::ResponseType AchievementManager::AwardAchievement(AchievementId achievement_id) AchievementManager::ResponseType AchievementManager::AwardAchievement(AchievementId achievement_id)

View File

@ -23,8 +23,9 @@
namespace Core namespace Core
{ {
class CPUThreadGuard;
class System; class System;
} } // namespace Core
namespace OSD namespace OSD
{ {
@ -180,7 +181,7 @@ private:
std::unique_ptr<DiscIO::Volume>& GetLoadingVolume() { return m_loading_volume; }; std::unique_ptr<DiscIO::Volume>& GetLoadingVolume() { return m_loading_volume; };
void ActivateDeactivateAchievement(AchievementId id, bool enabled, bool unofficial, bool encore); void ActivateDeactivateAchievement(AchievementId id, bool enabled, bool unofficial, bool encore);
void GenerateRichPresence(); void GenerateRichPresence(const Core::CPUThreadGuard& guard);
ResponseType AwardAchievement(AchievementId achievement_id); ResponseType AwardAchievement(AchievementId achievement_id);
ResponseType SubmitLeaderboard(AchievementId leaderboard_id, int value); ResponseType SubmitLeaderboard(AchievementId leaderboard_id, int value);

View File

@ -788,14 +788,14 @@ static std::string GenerateScreenshotName()
void SaveScreenShot() 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) void SaveScreenShot(std::string_view name)
{ {
Core::RunAsCPUThread([&name] { const Core::CPUThreadGuard guard(Core::System::GetInstance());
g_frame_dumper->SaveScreenshot(fmt::format("{}{}.png", GenerateScreenshotFolderPath(), name)); g_frame_dumper->SaveScreenshot(fmt::format("{}{}.png", GenerateScreenshotFolderPath(), name));
});
} }
static bool PauseAndLock(Core::System& system, bool do_lock, bool unpause_on_unlock) 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; return was_unpaused;
} }
void RunAsCPUThread(std::function<void()> 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<void()> function, bool wait_for_completion) void RunOnCPUThread(std::function<void()> function, bool wait_for_completion)
{ {
// If the CPU thread is not running, assume there is no active CPU thread we can race against. // If the CPU thread is not running, assume there is no active CPU thread we can race against.

View File

@ -94,13 +94,10 @@ enum class ConsoleType : u32
ReservedTDEVSystem = 0x20000007, ReservedTDEVSystem = 0x20000007,
}; };
// Run a function as the CPU thread. This is an RAII alternative to the RunAsCPUThread function. // 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
// If constructed from the Host thread, the CPU thread is paused and the current thread temporarily // the CPU thread, nothing special happens. This should only be constructed on the CPU thread or the
// becomes the CPU thread. // host thread.
// If constructed from the CPU thread, nothing special happens.
//
// This should only be constructed from the CPU thread or the host thread.
// //
// Some functions use a parameter of this type to indicate that the function should only be called // 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 // 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 FrameUpdateOnCPUThread();
void OnFrameEnd(Core::System& system); 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<void()> function);
// Run a function on the CPU thread, asynchronously. // Run a function on the CPU thread, asynchronously.
// This is only valid to call from the host thread, since it uses PauseAndLock() internally. // This is only valid to call from the host thread, since it uses PauseAndLock() internally.
void RunOnCPUThread(std::function<void()> function, bool wait_for_completion); void RunOnCPUThread(std::function<void()> function, bool wait_for_completion);

View File

@ -50,7 +50,8 @@ void OnSourceChanged(unsigned int index, WiimoteSource source)
WiimoteReal::HandleWiimoteSourceChange(index); WiimoteReal::HandleWiimoteSourceChange(index);
Core::RunAsCPUThread([index] { WiimoteCommon::UpdateSource(index); }); const Core::CPUThreadGuard guard(Core::System::GetInstance());
WiimoteCommon::UpdateSource(index);
} }
void RefreshConfig() void RefreshConfig()

View File

@ -947,10 +947,11 @@ static bool TryToConnectWiimoteToSlot(std::unique_ptr<Wiimote>& wm, unsigned int
led_report.leds = u8(1 << (i % WIIMOTE_BALANCE_BOARD)); led_report.leds = u8(1 << (i % WIIMOTE_BALANCE_BOARD));
wm->QueueReport(led_report); wm->QueueReport(led_report);
Core::RunAsCPUThread([i, &wm] { {
const Core::CPUThreadGuard guard(Core::System::GetInstance());
g_wiimotes[i] = std::move(wm); g_wiimotes[i] = std::move(wm);
WiimoteCommon::UpdateSource(i); WiimoteCommon::UpdateSource(i);
}); }
NOTICE_LOG_FMT(WIIMOTE, "Connected real wiimote to slot {}.", i + 1); NOTICE_LOG_FMT(WIIMOTE, "Connected real wiimote to slot {}.", i + 1);
@ -967,12 +968,11 @@ static void TryToConnectBalanceBoard(std::unique_ptr<Wiimote> wm)
static void HandleWiimoteDisconnect(int index) static void HandleWiimoteDisconnect(int index)
{ {
Core::RunAsCPUThread([index] { const Core::CPUThreadGuard guard(Core::System::GetInstance());
// The Wii Remote object must exist through the call to UpdateSource // The Wii Remote object must exist through the call to UpdateSource
// to prevent WiimoteDevice from having a dangling HIDWiimote pointer. // to prevent WiimoteDevice from having a dangling HIDWiimote pointer.
const auto temp_real_wiimote = std::move(g_wiimotes[index]); const auto temp_real_wiimote = std::move(g_wiimotes[index]);
WiimoteCommon::UpdateSource(index); WiimoteCommon::UpdateSource(index);
});
} }
// This is called from the GUI thread // This is called from the GUI thread
@ -1004,10 +1004,11 @@ void HandleWiimoteSourceChange(unsigned int index)
{ {
std::lock_guard wm_lk(g_wiimotes_mutex); 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])) if (auto removed_wiimote = std::move(g_wiimotes[index]))
AddWiimoteToPool(std::move(removed_wiimote)); AddWiimoteToPool(std::move(removed_wiimote));
}); }
g_controller_interface.PlatformPopulateDevices([] { ProcessWiimotePool(); }); g_controller_interface.PlatformPopulateDevices([] { ProcessWiimotePool(); });
} }

View File

@ -160,22 +160,21 @@ void JitInterface::GetProfileResults(Profiler::ProfileStats* prof_stats) const
prof_stats->timecost_sum = 0; prof_stats->timecost_sum = 0;
prof_stats->block_stats.clear(); prof_stats->block_stats.clear();
Core::RunAsCPUThread([this, &prof_stats] { const Core::CPUThreadGuard guard(m_system);
QueryPerformanceFrequency((LARGE_INTEGER*)&prof_stats->countsPerSec); QueryPerformanceFrequency((LARGE_INTEGER*)&prof_stats->countsPerSec);
m_jit->GetBlockCache()->RunOnBlocks([&prof_stats](const JitBlock& block) { m_jit->GetBlockCache()->RunOnBlocks([&prof_stats](const JitBlock& block) {
const auto& data = block.profile_data; const auto& data = block.profile_data;
u64 cost = data.downcountCounter; u64 cost = data.downcountCounter;
u64 timecost = data.ticCounter; u64 timecost = data.ticCounter;
// Todo: tweak. // Todo: tweak.
if (data.runCount >= 1) if (data.runCount >= 1)
prof_stats->block_stats.emplace_back(block.effectiveAddress, cost, timecost, data.runCount, prof_stats->block_stats.emplace_back(block.effectiveAddress, cost, timecost, data.runCount,
block.codeSize); block.codeSize);
prof_stats->cost_sum += cost; prof_stats->cost_sum += cost;
prof_stats->timecost_sum += timecost; prof_stats->timecost_sum += timecost;
});
sort(prof_stats->block_stats.begin(), prof_stats->block_stats.end());
}); });
sort(prof_stats->block_stats.begin(), prof_stats->block_stats.end());
} }
std::variant<JitInterface::GetHostCodeError, JitInterface::GetHostCodeResult> std::variant<JitInterface::GetHostCodeError, JitInterface::GetHostCodeResult>

View File

@ -112,9 +112,9 @@ static void RunWithGPUThreadInactive(std::function<void()> f)
} }
else else
{ {
// If we reach here, we can call Core::PauseAndLock (which we do using RunAsCPUThread). // If we reach here, we can call Core::PauseAndLock (which we do using a CPUThreadGuard).
const Core::CPUThreadGuard guard(Core::System::GetInstance());
Core::RunAsCPUThread(std::move(f)); f();
} }
} }

View File

@ -52,7 +52,7 @@ static bool QtMsgAlertHandler(const char* caption, const char* text, bool yes_no
std::optional<bool> r = RunOnObject(QApplication::instance(), [&] { std::optional<bool> r = RunOnObject(QApplication::instance(), [&] {
// If we were called from the CPU/GPU thread, set us as the CPU/GPU thread. // 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. // 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.) // can get called automatically when a dialog steals the focus.)
Common::ScopeGuard cpu_scope_guard(&Core::UndeclareAsCPUThread); Common::ScopeGuard cpu_scope_guard(&Core::UndeclareAsCPUThread);

View File

@ -1932,12 +1932,13 @@ void MainWindow::OnStopRecording()
void MainWindow::OnExportRecording() void MainWindow::OnExportRecording()
{ {
Core::RunAsCPUThread([this] { auto& system = Core::System::GetInstance();
QString dtm_file = DolphinFileDialog::getSaveFileName( const Core::CPUThreadGuard guard(system);
this, tr("Save Recording File As"), QString(), tr("Dolphin TAS Movies (*.dtm)"));
if (!dtm_file.isEmpty()) QString dtm_file = DolphinFileDialog::getSaveFileName(
Core::System::GetInstance().GetMovie().SaveRecording(dtm_file.toStdString()); 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() void MainWindow::OnActivateChat()
@ -1990,13 +1991,12 @@ void MainWindow::ShowTASInput()
void MainWindow::OnConnectWiiRemote(int id) void MainWindow::OnConnectWiiRemote(int id)
{ {
Core::RunAsCPUThread([&] { const Core::CPUThreadGuard guard(Core::System::GetInstance());
if (const auto bt = WiiUtils::GetBluetoothEmuDevice()) if (const auto bt = WiiUtils::GetBluetoothEmuDevice())
{ {
const auto wm = bt->AccessWiimoteByIndex(id); const auto wm = bt->AccessWiimoteByIndex(id);
wm->Activate(!wm->IsConnected()); wm->Activate(!wm->IsConnected());
} }
});
} }
#ifdef USE_RETRO_ACHIEVEMENTS #ifdef USE_RETRO_ACHIEVEMENTS