void Emulator::Resume() { // Get pause start time const u64 time = m_pause_start_time.exchange(0); // Try to increment summary pause time if (time) { m_pause_amend_time += get_system_time() - time; } // Try to resume if (!m_status.compare_and_swap_test(Paused, Running)) { return; } if (!time) { LOG_ERROR(GENERAL, "Emulator::Resume() error: concurrent access"); } SendDbgCommand(DID_RESUME_EMU); for (auto& thread : get_all_cpu_threads()) { thread->state -= cpu_state::dbg_global_pause; thread->safe_notify(); } rpcs3::on_resume()(); SendDbgCommand(DID_RESUMED_EMU); }
void Emulator::Run() { if (!IsReady()) { Load(); if(!IsReady()) return; } if (IsRunning()) Stop(); if (IsPaused()) { Resume(); return; } rpcs3::on_run()(); SendDbgCommand(DID_START_EMU); m_pause_start_time = 0; m_pause_amend_time = 0; m_status = Running; for (auto& thread : get_all_cpu_threads()) { thread->state -= cpu_state::stop; thread->safe_notify(); } SendDbgCommand(DID_STARTED_EMU); }
bool Emulator::Pause() { const u64 start = get_system_time(); // Try to pause if (!m_status.compare_and_swap_test(Running, Paused)) { return false; } rpcs3::on_pause()(); // Update pause start time if (m_pause_start_time.exchange(start)) { LOG_ERROR(GENERAL, "Emulator::Pause() error: concurrent access"); } SendDbgCommand(DID_PAUSE_EMU); for (auto& thread : get_all_cpu_threads()) { thread->state += cpu_state::dbg_global_pause; } SendDbgCommand(DID_PAUSED_EMU); return true; }
void Emulator::Stop() { if (m_status.exchange(Stopped) == Stopped) { return; } LOG_NOTICE(GENERAL, "Stopping emulator..."); rpcs3::on_stop()(); SendDbgCommand(DID_STOP_EMU); { LV2_LOCK; for (auto& thread : get_all_cpu_threads()) { thread->state += cpu_state::dbg_global_stop; thread->safe_notify(); } } LOG_NOTICE(GENERAL, "All threads signaled..."); while (g_thread_count) { m_cb.process_events(); std::this_thread::sleep_for(10ms); } LOG_NOTICE(GENERAL, "All threads stopped..."); idm::clear(); fxm::clear(); LOG_NOTICE(GENERAL, "Objects cleared..."); GetCallbackManager().Clear(); RSXIOMem.Clear(); vm::close(); SendDbgCommand(DID_STOPPED_EMU); if (g_cfg_autoexit) { GetCallbacks().exit(); } else { Init(); } }
void InterpreterDisAsmFrame::UpdateUnitList() { m_choice_units->Freeze(); m_choice_units->Clear(); for (auto& t : get_all_cpu_threads()) { m_choice_units->Append(t->get_name(), t.get()); } m_choice_units->Thaw(); }