Implement cpu_thread::stop_all()

This commit is contained in:
Nekotekina 2019-08-20 19:07:03 +03:00
parent 8517ccfdfa
commit 2882220cbd
3 changed files with 36 additions and 17 deletions

View File

@ -8,6 +8,8 @@
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/SPUThread.h"
#include <thread>
DECLARE(cpu_thread::g_threads_created){0};
DECLARE(cpu_thread::g_threads_deleted){0};
@ -132,7 +134,7 @@ void cpu_thread::operator()()
g_cpu_suspend_lock.lock_unlock();
// Check thread status
while (!(state & (cpu_flag::exit + cpu_flag::dbg_global_stop)))
while (!(state & (cpu_flag::exit + cpu_flag::dbg_global_stop)) && !Emu.IsStopped())
{
// Check stop status
if (!(state & cpu_flag::stop))
@ -389,3 +391,32 @@ cpu_thread::suspend_all::~suspend_all()
m_this->check_state();
}
}
void cpu_thread::stop_all() noexcept
{
if (g_tls_current_cpu_thread)
{
// Report unsupported but unnecessary case
LOG_FATAL(GENERAL, "cpu_thread::stop_all() has been called from a CPU thread.");
return;
}
else
{
::vip_lock lock(g_cpu_suspend_lock);
for_all_cpu([](cpu_thread* cpu)
{
cpu->state += cpu_flag::dbg_global_stop;
cpu->notify();
});
}
LOG_NOTICE(GENERAL, "All CPU threads have been signaled.");
while (g_cpu_array_sema)
{
std::this_thread::sleep_for(10ms);
}
LOG_NOTICE(GENERAL, "All CPU threads have been stopped.");
}

View File

@ -113,6 +113,9 @@ public:
suspend_all& operator=(const suspend_all&) = delete;
~suspend_all();
};
// Stop all threads with cpu_flag::dbg_global_stop
static void stop_all() noexcept;
};
inline cpu_thread* get_current_cpu_thread() noexcept

View File

@ -1711,22 +1711,7 @@ void Emulator::Stop(bool restart)
GetCallbacks().on_stop();
#ifdef WITH_GDB_DEBUGGER
//fxm for some reason doesn't call on_stop
fxm::get<GDBDebugServer>()->on_stop();
fxm::remove<GDBDebugServer>();
#endif
auto on_select = [&](u32, cpu_thread& cpu)
{
cpu.state += cpu_flag::dbg_global_stop;
cpu.notify();
};
idm::select<named_thread<ppu_thread>>(on_select);
idm::select<named_thread<spu_thread>>(on_select);
LOG_NOTICE(GENERAL, "All threads signaled...");
cpu_thread::stop_all();
while (g_thread_count)
{