mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
Fix Emulator::IsPaused() to allow measurements during module compilation
Also fix a potential deadlock in access violation handler for non-cpu_thread
This commit is contained in:
parent
4c0832e6e6
commit
9677a3a9ea
@ -1703,23 +1703,58 @@ bool handle_access_violation(u32 addr, bool is_writing, ucontext_t* context) noe
|
|||||||
cpu->state += cpu_flag::wait;
|
cpu->state += cpu_flag::wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
Emu.Pause(true);
|
|
||||||
|
|
||||||
if (!g_tls_access_violation_recovered)
|
|
||||||
{
|
|
||||||
vm_log.notice("\n%s", dump_useful_thread_info());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: a thread may access violate more than once after hack_alloc recovery
|
// Note: a thread may access violate more than once after hack_alloc recovery
|
||||||
// Do not log any further access violations in this case.
|
// Do not log any further access violations in this case.
|
||||||
if (!g_tls_access_violation_recovered)
|
if (!g_tls_access_violation_recovered)
|
||||||
{
|
{
|
||||||
|
vm_log.notice("\n%s", dump_useful_thread_info());
|
||||||
vm_log.fatal("Access violation %s location 0x%x (%s)", is_writing ? "writing" : (cpu && cpu->get_class() == thread_class::ppu && cpu->get_pc() == addr ? "executing" : "reading"), addr, (is_writing && vm::check_addr(addr)) ? "read-only memory" : "unmapped memory");
|
vm_log.fatal("Access violation %s location 0x%x (%s)", is_writing ? "writing" : (cpu && cpu->get_class() == thread_class::ppu && cpu->get_pc() == addr ? "executing" : "reading"), addr, (is_writing && vm::check_addr(addr)) ? "read-only memory" : "unmapped memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (Emu.IsPausedOrReady())
|
||||||
|
{
|
||||||
|
if (cpu)
|
||||||
|
{
|
||||||
|
auto state = +cpu->state;
|
||||||
|
|
||||||
|
if (::is_paused(state) && !::is_stopped(state))
|
||||||
|
{
|
||||||
|
thread_ctrl::wait_on(cpu->state, state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Temporary until Emulator updates state
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thread_ctrl::wait_for(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Emu.Pause(true);
|
||||||
|
|
||||||
while (Emu.IsPaused())
|
while (Emu.IsPaused())
|
||||||
{
|
{
|
||||||
thread_ctrl::wait();
|
if (cpu)
|
||||||
|
{
|
||||||
|
auto state = +cpu->state;
|
||||||
|
|
||||||
|
if (::is_paused(state) && !::is_stopped(state))
|
||||||
|
{
|
||||||
|
thread_ctrl::wait_on(cpu->state, state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Temporary until Emulator updates state
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thread_ctrl::wait_for(1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Emu.IsStopped() && !hack_alloc())
|
if (Emu.IsStopped() && !hack_alloc())
|
||||||
|
@ -704,7 +704,7 @@ void cell_audio_thread::operator()()
|
|||||||
|
|
||||||
thread_ctrl::scoped_priority high_prio(+1);
|
thread_ctrl::scoped_priority high_prio(+1);
|
||||||
|
|
||||||
while (Emu.IsPaused())
|
while (Emu.IsPausedOrReady())
|
||||||
{
|
{
|
||||||
thread_ctrl::wait_for(5000);
|
thread_ctrl::wait_for(5000);
|
||||||
}
|
}
|
||||||
|
@ -1640,14 +1640,14 @@ void camera_context::operator()()
|
|||||||
while (thread_ctrl::state() != thread_state::aborting && !Emu.IsStopped())
|
while (thread_ctrl::state() != thread_state::aborting && !Emu.IsStopped())
|
||||||
{
|
{
|
||||||
// send ATTACH event
|
// send ATTACH event
|
||||||
if (init && is_attached_dirty && !Emu.IsPaused())
|
if (init && is_attached_dirty && !Emu.IsPausedOrReady())
|
||||||
{
|
{
|
||||||
send_attach_state(is_attached);
|
send_attach_state(is_attached);
|
||||||
}
|
}
|
||||||
|
|
||||||
const s32 fps = info.framerate;
|
const s32 fps = info.framerate;
|
||||||
|
|
||||||
if (!init || !fps || Emu.IsPaused() || g_cfg.io.camera == camera_handler::null)
|
if (!init || !fps || Emu.IsPausedOrReady() || g_cfg.io.camera == camera_handler::null)
|
||||||
{
|
{
|
||||||
thread_ctrl::wait_for(1000); // hack
|
thread_ctrl::wait_for(1000); // hack
|
||||||
continue;
|
continue;
|
||||||
|
@ -825,7 +825,7 @@ void rsxaudio_data_thread::extract_audio_data()
|
|||||||
return rsxaudio_obj_ptr;
|
return rsxaudio_obj_ptr;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (Emu.IsPaused() || !rsxaudio_obj)
|
if (Emu.IsPausedOrReady() || !rsxaudio_obj)
|
||||||
{
|
{
|
||||||
advance_all_timers();
|
advance_all_timers();
|
||||||
return;
|
return;
|
||||||
@ -1533,7 +1533,7 @@ void rsxaudio_backend_thread::operator()()
|
|||||||
backend_failed = false;
|
backend_failed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Emu.IsPaused() || !use_aux_ringbuf) // Don't pause if thread is in direct mode
|
if (!Emu.IsPausedOrReady() || !use_aux_ringbuf) // Don't pause if thread is in direct mode
|
||||||
{
|
{
|
||||||
if (!backend_playing())
|
if (!backend_playing())
|
||||||
{
|
{
|
||||||
|
@ -135,7 +135,7 @@ void lv2_timer_thread::operator()()
|
|||||||
|
|
||||||
sleep_time = umax;
|
sleep_time = umax;
|
||||||
|
|
||||||
if (Emu.IsPaused())
|
if (Emu.IsPausedOrReady())
|
||||||
{
|
{
|
||||||
sleep_time = 10000;
|
sleep_time = 10000;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1968,7 +1968,7 @@ void vuart_av_thread::operator()()
|
|||||||
{
|
{
|
||||||
while (thread_ctrl::state() != thread_state::aborting)
|
while (thread_ctrl::state() != thread_state::aborting)
|
||||||
{
|
{
|
||||||
if (Emu.IsPaused())
|
if (Emu.IsPausedOrReady())
|
||||||
{
|
{
|
||||||
thread_ctrl::wait_for(5000);
|
thread_ctrl::wait_for(5000);
|
||||||
continue;
|
continue;
|
||||||
|
@ -830,7 +830,7 @@ bool gdb_thread::cmd_vcont(gdb_cmd& cmd)
|
|||||||
{
|
{
|
||||||
Emu.Run(true);
|
Emu.Run(true);
|
||||||
}
|
}
|
||||||
if (Emu.IsPaused())
|
else if (Emu.IsPaused())
|
||||||
{
|
{
|
||||||
Emu.Resume();
|
Emu.Resume();
|
||||||
}
|
}
|
||||||
|
@ -426,7 +426,8 @@ public:
|
|||||||
static void CleanUp();
|
static void CleanUp();
|
||||||
|
|
||||||
bool IsRunning() const { return m_state == system_state::running; }
|
bool IsRunning() const { return m_state == system_state::running; }
|
||||||
bool IsPaused() const { return m_state >= system_state::paused; } // ready/starting are also considered paused by this function
|
bool IsPaused() const { system_state state = m_state; return state >= system_state::paused && state <= system_state::frozen; }
|
||||||
|
bool IsPausedOrReady() const { return m_state >= system_state::paused; }
|
||||||
bool IsStopped(bool test_fully = false) const { return test_fully ? m_state == system_state::stopped : m_state <= system_state::stopping; }
|
bool IsStopped(bool test_fully = false) const { return test_fully ? m_state == system_state::stopped : m_state <= system_state::stopping; }
|
||||||
bool IsReady() const { return m_state == system_state::ready; }
|
bool IsReady() const { return m_state == system_state::ready; }
|
||||||
bool IsStarting() const { return m_state == system_state::starting; }
|
bool IsStarting() const { return m_state == system_state::starting; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user