void cpu_thread::on_task() { state -= cpu_flag::exit; g_tls_current_cpu_thread = this; // Check thread status while (!test(state, cpu_flag::exit + cpu_flag::dbg_global_stop)) { // Check stop status if (!test(state & cpu_flag::stop)) { try { cpu_task(); } catch (cpu_flag _s) { state += _s; } catch (const std::exception&) { LOG_NOTICE(GENERAL, "\n%s", dump()); throw; } state -= cpu_flag::ret; continue; } thread_ctrl::wait(); } }
void cpu_thread::on_task() { state -= cpu_flag::exit; g_tls_current_cpu_thread = this; Emu.SendDbgCommand(DID_CREATE_THREAD, this); std::unique_lock<named_thread> lock(*this); // Check thread status while (!test(state & cpu_flag::exit)) { CHECK_EMU_STATUS; // check stop status if (!test(state & cpu_flag::stop)) { if (lock) lock.unlock(); try { cpu_task(); } catch (cpu_flag _s) { state += _s; } catch (const std::exception&) { LOG_NOTICE(GENERAL, "\n%s", dump()); throw; } state -= cpu_flag::ret; continue; } if (!lock) { lock.lock(); continue; } thread_ctrl::wait(); } }
void PPUThread::fast_call(u32 addr, u32 rtoc) { auto old_PC = pc; auto old_stack = GPR[1]; auto old_rtoc = GPR[2]; auto old_LR = LR; auto old_task = std::move(custom_task); pc = addr; GPR[2] = rtoc; LR = Emu.GetCPUThreadStop(); custom_task = nullptr; try { cpu_task(); } catch (cpu_state _s) { state += _s; if (_s != cpu_state::ret) throw; } state -= cpu_state::ret; pc = old_PC; if (GPR[1] != old_stack) // GPR[1] shouldn't change { throw EXCEPTION("Stack inconsistency (addr=0x%x, rtoc=0x%x, SP=0x%llx, old=0x%llx)", addr, rtoc, GPR[1], old_stack); } GPR[2] = old_rtoc; LR = old_LR; custom_task = std::move(old_task); //if (custom_task) //{ // state += cpu_state::interrupt; // handle_interrupt(); //} }
void ARMv7Thread::fast_call(u32 addr) { if (!is_current()) { throw EXCEPTION("Called from the wrong thread"); } auto old_PC = PC; auto old_stack = SP; auto old_LR = LR; auto old_task = std::move(custom_task); PC = addr; LR = Emu.GetCPUThreadStop(); custom_task = nullptr; try { cpu_task(); } catch (CPUThreadReturn) { } m_state &= ~CPU_STATE_RETURN; PC = old_PC; if (SP != old_stack) // SP shouldn't change { throw EXCEPTION("Stack inconsistency (addr=0x%x, SP=0x%x, old=0x%x)", addr, SP, old_stack); } LR = old_LR; custom_task = std::move(old_task); }