mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-08 16:01:42 +12:00
Optimize emulation stopping for when cellSysutilCheckCallback is not called
This commit is contained in:
parent
f5beaabded
commit
0f499e36fb
2 changed files with 35 additions and 3 deletions
|
@ -49,6 +49,7 @@ struct sysutil_cb_manager
|
||||||
lf_queue<std::function<s32(ppu_thread&)>> registered;
|
lf_queue<std::function<s32(ppu_thread&)>> registered;
|
||||||
|
|
||||||
atomic_t<bool> draw_cb_started{};
|
atomic_t<bool> draw_cb_started{};
|
||||||
|
atomic_t<u64> read_counter{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void sysutil_register_cb(std::function<s32(ppu_thread&)>&& cb)
|
extern void sysutil_register_cb(std::function<s32(ppu_thread&)>&& cb)
|
||||||
|
@ -100,6 +101,16 @@ extern s32 sysutil_send_system_cmd(u64 status, u64 param)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern u64 get_sysutil_cb_manager_read_count()
|
||||||
|
{
|
||||||
|
if (auto cbm = g_fxo->try_get<sysutil_cb_manager>())
|
||||||
|
{
|
||||||
|
return cbm->read_counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void fmt_class_string<CellSysutilLang>::format(std::string& out, u64 arg)
|
void fmt_class_string<CellSysutilLang>::format(std::string& out, u64 arg)
|
||||||
{
|
{
|
||||||
|
@ -428,8 +439,12 @@ error_code cellSysutilCheckCallback(ppu_thread& ppu)
|
||||||
|
|
||||||
auto& cbm = g_fxo->get<sysutil_cb_manager>();
|
auto& cbm = g_fxo->get<sysutil_cb_manager>();
|
||||||
|
|
||||||
|
bool read = false;
|
||||||
|
|
||||||
for (auto&& func : cbm.registered.pop_all())
|
for (auto&& func : cbm.registered.pop_all())
|
||||||
{
|
{
|
||||||
|
read = true;
|
||||||
|
|
||||||
if (s32 res = func(ppu))
|
if (s32 res = func(ppu))
|
||||||
{
|
{
|
||||||
// Currently impossible
|
// Currently impossible
|
||||||
|
@ -442,6 +457,11 @@ error_code cellSysutilCheckCallback(ppu_thread& ppu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (read)
|
||||||
|
{
|
||||||
|
cbm.read_counter++;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1769,6 +1769,8 @@ void Emulator::Resume()
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 sysutil_send_system_cmd(u64 status, u64 param);
|
s32 sysutil_send_system_cmd(u64 status, u64 param);
|
||||||
|
u64 get_sysutil_cb_manager_read_count();
|
||||||
|
|
||||||
void process_qt_events();
|
void process_qt_events();
|
||||||
|
|
||||||
void Emulator::GracefulShutdown(bool allow_autoexit, bool async_op)
|
void Emulator::GracefulShutdown(bool allow_autoexit, bool async_op)
|
||||||
|
@ -1785,6 +1787,8 @@ void Emulator::GracefulShutdown(bool allow_autoexit, bool async_op)
|
||||||
Resume();
|
Resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const u64 read_counter = get_sysutil_cb_manager_read_count();
|
||||||
|
|
||||||
if (old_state == system_state::frozen || !sysutil_send_system_cmd(0x0101 /* CELL_SYSUTIL_REQUEST_EXITGAME */, 0))
|
if (old_state == system_state::frozen || !sysutil_send_system_cmd(0x0101 /* CELL_SYSUTIL_REQUEST_EXITGAME */, 0))
|
||||||
{
|
{
|
||||||
// The callback has been rudely ignored, we have no other option but to force termination
|
// The callback has been rudely ignored, we have no other option but to force termination
|
||||||
|
@ -1792,21 +1796,29 @@ void Emulator::GracefulShutdown(bool allow_autoexit, bool async_op)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto perform_kill = [allow_autoexit, this, info = ProcureCurrentEmulationCourseInformation()]()
|
auto perform_kill = [read_counter, allow_autoexit, this, info = ProcureCurrentEmulationCourseInformation()]()
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < 100; i++)
|
bool read_sysutil_signal = false;
|
||||||
|
|
||||||
|
for (u32 i = 100; i < 140; i++)
|
||||||
{
|
{
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
Resume(); // TODO: Prevent pausing by other threads while in this loop
|
Resume(); // TODO: Prevent pausing by other threads while in this loop
|
||||||
process_qt_events(); // Is nullified when performed on non-main thread
|
process_qt_events(); // Is nullified when performed on non-main thread
|
||||||
|
|
||||||
|
if (!read_sysutil_signal && read_counter != get_sysutil_cb_manager_read_count())
|
||||||
|
{
|
||||||
|
i -= 100; // Grant 5 seconds (if signal is not read force kill after two second)
|
||||||
|
read_sysutil_signal = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (static_cast<u64>(info) != m_stop_ctr)
|
if (static_cast<u64>(info) != m_stop_ctr)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// An inevitable attempt to terminate the *current* emulation course will be issued after 5s
|
// An inevitable attempt to terminate the *current* emulation course will be issued after 7s
|
||||||
CallFromMainThread([allow_autoexit, this]()
|
CallFromMainThread([allow_autoexit, this]()
|
||||||
{
|
{
|
||||||
Kill(allow_autoexit);
|
Kill(allow_autoexit);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue