diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 00a723503e..eab5e860d4 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1,97 +1,149 @@ #include "stdafx.h" #include "Thread.h" -ThreadBase* GetCurrentNamedThread() -{ - ThreadExec* thr = (ThreadExec*)::wxThread::This(); - return thr ? thr->m_parent : nullptr; -} +static DWORD g_tls_this_thread = 0xFFFFFFFF; -ThreadBase::ThreadBase(bool detached, const std::string& name) - : m_detached(detached) - , m_name(name) - , m_executor(nullptr) +struct __init_tls { -} + //NamedThreadBase m_main_thr; -void ThreadBase::Start() -{ - if(m_executor) return; - - m_executor = new ThreadExec(m_detached, this); -} - -void ThreadBase::Resume() -{ - if(m_executor) + __init_tls() { - m_executor->Resume(); + g_tls_this_thread = ::TlsAlloc(); + //m_main_thr.SetThreadName("Main Thread"); + //::TlsSetValue(g_tls_this_thread, &m_main_thr); + ::TlsSetValue(g_tls_this_thread, nullptr); } -} -void ThreadBase::Pause() -{ - if(m_executor) + ~__init_tls() { - m_executor->Pause(); + ::TlsFree(g_tls_this_thread); } -} +} _init_tls; -void ThreadBase::Stop(bool wait) +NamedThreadBase* GetCurrentNamedThread() { - if(!m_executor) return; - ThreadExec* exec = m_executor; - m_executor = nullptr; - - if(!m_detached) - { - if(wait) - { - exec->Wait(); - } - - exec->Stop(false); - delete exec; - } - else - { - exec->Stop(wait); - } + return (NamedThreadBase*)::TlsGetValue(g_tls_this_thread); } -bool ThreadBase::Wait() const -{ - return m_executor != nullptr && m_executor->Wait() != (wxThread::ExitCode)-1; -} - -bool ThreadBase::IsRunning() const -{ - return m_executor != nullptr && m_executor->IsRunning(); -} - -bool ThreadBase::IsPaused() const -{ - return m_executor != nullptr && m_executor->IsPaused(); -} - -bool ThreadBase::IsAlive() const -{ - return m_executor != nullptr; -} - -bool ThreadBase::TestDestroy() const -{ - if(!m_executor || !m_executor->m_parent) return true; - - return m_executor->TestDestroy(); -} - -std::string ThreadBase::GetThreadName() const +std::string NamedThreadBase::GetThreadName() const { return m_name; } -void ThreadBase::SetThreadName(const std::string& name) +void NamedThreadBase::SetThreadName(const std::string& name) { m_name = name; +} + +ThreadBase::ThreadBase(const std::string& name) + : NamedThreadBase(name) + , m_executor(nullptr) + , m_destroy(false) + , m_alive(false) +{ +} + +ThreadBase::~ThreadBase() +{ + if(IsAlive()) + Stop(false); +} + +void ThreadBase::Start() +{ + if(m_executor) Stop(); + + std::lock_guard lock(m_main_mutex); + + m_destroy = false; + m_alive = true; + + m_executor = new std::thread( + [this]() + { + ::TlsSetValue(g_tls_this_thread, this); + + Task(); + + m_alive = false; + }); +} + +void ThreadBase::Stop(bool wait) +{ + std::lock_guard lock(m_main_mutex); + + m_destroy = true; + + if(!m_executor) + return; + + if(wait && m_executor->joinable() && m_alive) + { + m_executor->join(); + } + else + { + m_executor->detach(); + } + + delete m_executor; + m_executor = nullptr; +} + +bool ThreadBase::Join() const +{ + std::lock_guard lock(m_main_mutex); + if(m_executor->joinable() && m_alive && m_executor != nullptr) + { + m_executor->join(); + return true; + } + + return false; +} + +bool ThreadBase::IsAlive() const +{ + std::lock_guard lock(m_main_mutex); + return m_alive; +} + +bool ThreadBase::TestDestroy() const +{ + return m_destroy; +} + +thread::thread(const std::string& name, std::function func) : m_name(name) +{ + start(func); +} + +thread::thread(const std::string& name) : m_name(name) +{ +} + +thread::thread() +{ +} + +void thread::start(std::function func) +{ + m_thr = std::thread([this, func]() { NamedThreadBase info(m_name); ::TlsSetValue(g_tls_this_thread, &info); func(); }); +} + +void thread::detach() +{ + m_thr.detach(); +} + +void thread::join() +{ + m_thr.join(); +} + +bool thread::joinable() const +{ + return m_thr.joinable(); } \ No newline at end of file diff --git a/Utilities/Thread.h b/Utilities/Thread.h index ee7559ec29..f8967bbc3a 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -3,84 +3,68 @@ #include #include #include +#include #include class ThreadExec; -class ThreadBase +class NamedThreadBase { -protected: std::string m_name; - bool m_detached; public: - std::mutex m_main_mutex; + NamedThreadBase(const std::string& name) : m_name(name) + { + } -protected: - ThreadBase(bool detached = true, const std::string& name = "Unknown ThreadBase"); + NamedThreadBase() + { + } -public: - ThreadExec* m_executor; - - virtual void Task()=0; - - virtual void Start(); - virtual void Resume(); - virtual void Pause(); - virtual void Stop(bool wait = true); - - virtual bool Wait() const; - virtual bool IsRunning() const; - virtual bool IsPaused() const; - virtual bool IsAlive() const; - virtual bool TestDestroy() const; virtual std::string GetThreadName() const; virtual void SetThreadName(const std::string& name); }; -ThreadBase* GetCurrentNamedThread(); +NamedThreadBase* GetCurrentNamedThread(); -class ThreadExec : public wxThread +class ThreadBase : public NamedThreadBase { - std::mutex m_wait_for_exit; - volatile bool m_alive; +protected: + std::atomic m_destroy; + std::atomic m_alive; + std::thread* m_executor; + + mutable std::mutex m_main_mutex; + + ThreadBase(const std::string& name); + ~ThreadBase(); public: - ThreadBase* m_parent; + void Start(); + void Stop(bool wait = true); - ThreadExec(bool detached, ThreadBase* parent) - : wxThread(detached ? wxTHREAD_DETACHED : wxTHREAD_JOINABLE) - , m_parent(parent) - , m_alive(true) - { - Create(); - Run(); - } + bool Join() const; + bool IsAlive() const; + bool TestDestroy() const; - void Stop(bool wait = true) - { - if(!m_alive) return; - - m_parent = nullptr; - - if(wait) - { - Delete(); - //std::lock_guard lock(m_wait_for_exit); - } - } - - ExitCode Entry() - { - //std::lock_guard lock(m_wait_for_exit); - m_parent->Task(); - m_alive = false; - if(m_parent) m_parent->m_executor = nullptr; - return (ExitCode)0; - } + virtual void Task() = 0; }; -//ThreadBase* GetCurrentThread(); +class thread +{ + std::string m_name; + std::thread m_thr; + +public: + thread(const std::string& name, std::function func); + thread(const std::string& name); + thread(); + + void start(std::function func); + void detach(); + void join(); + bool joinable() const; +}; template class MTPacketBuffer { diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index a0a1cdfed1..1a7ff1b011 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -7,7 +7,7 @@ CPUThread* GetCurrentCPUThread() } CPUThread::CPUThread(CPUThreadType type) - : ThreadBase(true, "CPUThread") + : ThreadBase("CPUThread") , m_type(type) , m_stack_size(0) , m_stack_addr(0) @@ -15,30 +15,24 @@ CPUThread::CPUThread(CPUThreadType type) , m_prio(0) , m_sync_wait(false) , m_wait_thread_id(-1) - , m_free_data(false) , m_dec(nullptr) , m_is_step(false) , m_is_branch(false) + , m_status(Stopped) { } CPUThread::~CPUThread() { - Close(); } void CPUThread::Close() { - if(IsAlive()) - { - m_free_data = true; - ThreadBase::Stop(false); - } - else - { - delete m_dec; - m_dec = nullptr; - } + ThreadBase::Stop(); + DoStop(); + + delete m_dec; + m_dec = nullptr; } void CPUThread::Reset() @@ -77,7 +71,7 @@ void CPUThread::SetId(const u32 id) void CPUThread::SetName(const std::string& name) { - m_name = name; + NamedThreadBase::SetThreadName(name); } void CPUThread::Wait(bool wait) @@ -189,12 +183,10 @@ wxArrayString CPUThread::ErrorToString(const u32 error) void CPUThread::Run() { - if(IsRunning()) Stop(); - if(IsPaused()) - { - Resume(); - return; - } + if(!IsStopped()) + Stop(); + + Reset(); #ifndef QT_UI wxGetApp().SendDbgCommand(DID_START_THREAD, this); @@ -244,7 +236,7 @@ void CPUThread::Pause() DoPause(); Emu.CheckStatus(); - ThreadBase::Stop(false); + ThreadBase::Stop(); #ifndef QT_UI wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, this); #endif @@ -259,9 +251,15 @@ void CPUThread::Stop() #endif m_status = Stopped; - ThreadBase::Stop(false); - Reset(); - DoStop(); + + if(CPUThread* thr = GetCurrentCPUThread()) + { + if(thr->GetId() != GetId()) + ThreadBase::Stop(); + } + else + ThreadBase::Stop(); + Emu.CheckStatus(); #ifndef QT_UI @@ -275,7 +273,9 @@ void CPUThread::Exec() #ifndef QT_UI wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this); #endif - ThreadBase::Start(); + + if(IsRunning()) + ThreadBase::Start(); } void CPUThread::ExecOnce() @@ -285,7 +285,7 @@ void CPUThread::ExecOnce() wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this); #endif ThreadBase::Start(); - if(!ThreadBase::Wait()) while(m_is_step) Sleep(1); + ThreadBase::Stop(); #ifndef QT_UI wxGetApp().SendDbgCommand(DID_PAUSE_THREAD, this); wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, this); @@ -294,7 +294,7 @@ void CPUThread::ExecOnce() void CPUThread::Task() { - //ConLog.Write("%s enter", CPUThread::GetFName()); + ConLog.Write("%s enter", CPUThread::GetFName()); const Array& bp = Emu.GetBreakPoints(); @@ -354,15 +354,7 @@ void CPUThread::Task() catch(int exitcode) { ConLog.Success("Exit Code: %d", exitcode); - return; } - //ConLog.Write("%s leave", CPUThread::GetFName()); - - if(m_free_data) - { - delete m_dec; - m_dec = nullptr; - free(this); - } + ConLog.Write("%s leave", CPUThread::GetFName()); } diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index 08ec842593..54a5ae6a8c 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -32,7 +32,6 @@ protected: CPUThreadType m_type; bool m_joinable; bool m_joining; - bool m_free_data; bool m_is_step; u64 m_stack_addr; @@ -68,7 +67,7 @@ public: u32 GetExitStatus() const { return m_exit_status; } u64 GetPrio() const { return m_prio; } - std::string GetName() const { return m_name; } + std::string GetName() const { return NamedThreadBase::GetThreadName(); } wxString GetFName() const { return diff --git a/rpcs3/Emu/CPU/CPUThreadManager.cpp b/rpcs3/Emu/CPU/CPUThreadManager.cpp index 612c71ea5c..3dd17d02d1 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.cpp +++ b/rpcs3/Emu/CPU/CPUThreadManager.cpp @@ -64,16 +64,7 @@ void CPUThreadManager::RemoveThread(const u32 id) #ifndef QT_UI wxGetApp().SendDbgCommand(DID_REMOVE_THREAD, thr); #endif - if(thr->IsAlive()) - { - //thr->Close(); - } - else - { - //thr->Close(); - //delete thr; - } - + thr->Close(); m_threads.RemoveFAt(i); break; diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 27a97f63b5..a6ed302a33 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -21,7 +21,7 @@ RawSPUThread::~RawSPUThread() } } - Close(); + //Close(); } bool RawSPUThread::Read8(const u64 addr, u8* value) diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 76732b7f58..60e3cf9238 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -78,7 +78,7 @@ void SPUThread::DoRun() break; } - Pause(); + //Pause(); //Emu.Pause(); } diff --git a/rpcs3/Emu/DbgConsole.cpp b/rpcs3/Emu/DbgConsole.cpp index 263368600b..560ce4b353 100644 --- a/rpcs3/Emu/DbgConsole.cpp +++ b/rpcs3/Emu/DbgConsole.cpp @@ -6,8 +6,8 @@ BEGIN_EVENT_TABLE(DbgConsole, FrameBase) END_EVENT_TABLE() DbgConsole::DbgConsole() - : FrameBase(NULL, wxID_ANY, "DbgConsole", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxDEFAULT_FRAME_STYLE, true) - , ThreadBase(false, "DbgConsole thread") + : FrameBase(nullptr, wxID_ANY, "DbgConsole", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxDEFAULT_FRAME_STYLE, true) + , ThreadBase("DbgConsole thread") { m_console = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(500, 500), wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2); @@ -39,8 +39,14 @@ void DbgConsole::Clear() void DbgConsole::Task() { - while(m_dbg_buffer.HasNewPacket() && !TestDestroy()) + while(!TestDestroy()) { + if(!m_dbg_buffer.HasNewPacket()) + { + Sleep(1); + continue; + } + DbgPacket packet = m_dbg_buffer.Pop(); m_console->SetDefaultStyle(packet.m_ch == 1 ? *m_color_red : *m_color_white); m_console->SetInsertionPointEnd(); @@ -52,7 +58,7 @@ void DbgConsole::Task() void DbgConsole::OnQuit(wxCloseEvent& event) { - ThreadBase::Stop(); + ThreadBase::Stop(false); Hide(); //event.Skip(); } \ No newline at end of file diff --git a/rpcs3/Emu/FS/vfsLocalFile.cpp b/rpcs3/Emu/FS/vfsLocalFile.cpp index b41bd99392..06d9a1d3ba 100644 --- a/rpcs3/Emu/FS/vfsLocalFile.cpp +++ b/rpcs3/Emu/FS/vfsLocalFile.cpp @@ -54,7 +54,7 @@ bool vfsLocalFile::Open(const wxString& path, vfsOpenMode mode) bool vfsLocalFile::Create(const wxString& path) { ConLog.Warning("vfsLocalFile::Create('%s')", path.c_str()); - for(uint p=1;p= 2 && index <= 4) - { - return m_parr.AddParam(PARAM_OUT, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index), - (fp16) ? -1 : (index - 1)); - } + if(index >= 2 && index <= 4) + { + return m_parr.AddParam(PARAM_OUT, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index), + (fp16) ? -1 : (index - 1)); + } - return m_parr.AddParam(PARAM_NONE, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index), "vec4(0.0)"); + return m_parr.AddParam(PARAM_NONE, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index), "vec4(0.0, 0.0, 0.0, 0.0)"); //return m_parr.AddParam((index >= 2 && index <= 4) ? PARAM_OUT : PARAM_NONE, "vec4", // std::string(fp16 ? "h" : "r") + std::to_string(index), (fp16 || !index) ? -1 : ((index >= 2 && index <= 4) ? (index - 1) : -1)); diff --git a/rpcs3/Emu/GS/GL/GLFragmentProgram.h b/rpcs3/Emu/GS/GL/GLFragmentProgram.h index 46860b0c25..3748652509 100644 --- a/rpcs3/Emu/GS/GL/GLFragmentProgram.h +++ b/rpcs3/Emu/GS/GL/GLFragmentProgram.h @@ -109,7 +109,7 @@ struct GLFragmentDecompilerThread : public ThreadBase u32 m_ctrl; GLFragmentDecompilerThread(std::string& shader, GLParamArray& parr, u32 addr, u32& size, u32 ctrl) - : ThreadBase(false, "Fragment Shader Decompiler Thread") + : ThreadBase("Fragment Shader Decompiler Thread") , m_shader(shader) , m_parr(parr) , m_addr(addr) @@ -155,7 +155,7 @@ struct GLShaderProgram { if(m_decompiler_thread && m_decompiler_thread->IsAlive()) { - m_decompiler_thread->Wait(); + m_decompiler_thread->Join(); } } void Decompile(RSXShaderProgram& prog); diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index 2e2695e828..addaf0fa99 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -109,7 +109,7 @@ extern CellGcmContextData current_context; void GLGSRender::Close() { - if(IsAlive()) Stop(); + Stop(); if(m_frame->IsShown()) m_frame->Hide(); m_ctrl = nullptr; diff --git a/rpcs3/Emu/GS/GL/GLVertexProgram.cpp b/rpcs3/Emu/GS/GL/GLVertexProgram.cpp index 96232ebd02..8060882778 100644 --- a/rpcs3/Emu/GS/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/GS/GL/GLVertexProgram.cpp @@ -151,7 +151,7 @@ wxString GLVertexDecompilerThread::GetSRC(const u32 n, bool isSca) return ret; } -void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask, bool set_dst) +void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask, bool set_dst, bool set_cond) { if(d0.cond == 0) return; enum @@ -161,28 +161,42 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask gt = 0x4, }; + static const char* cond_string_table[(lt | gt | eq) + 1] = + { + "error", + "lessThan", + "equal", + "lessThanEqual", + "greaterThan", + "notEqual", + "greaterThanEqual", + "error" + }; + wxString cond; - if(d0.cond != (lt | gt | eq)) + if((set_cond || d0.cond_test_enable) && d0.cond != (lt | gt | eq)) { - if((d0.cond & (lt | gt)) == (lt | gt)) - { - cond = "!="; - } - else - { - if(d0.cond & lt) cond = "<"; - else if(d0.cond & gt) cond = ">"; - else if(d0.cond & eq) cond = "="; + static const char f[4] = {'x', 'y', 'z', 'w'}; - if(d0.cond & eq) cond += "="; - } + std::string swizzle; + swizzle += f[d0.mask_x]; + swizzle += f[d0.mask_y]; + swizzle += f[d0.mask_z]; + swizzle += f[d0.mask_w]; - //ConLog.Error("cond! %d (%d %s %d %d)", d0.cond, d0.dst_tmp, cond, d1.input_src, d1.const_src); - cond = wxString::Format("if(rc %s 0) ", cond.mb_str()); + swizzle = swizzle == "xyzw" ? "" : "." + swizzle; + + cond = wxString::Format("if(all(%s(rc%s, vec4(0.0)%s))) ", cond_string_table[d0.cond], swizzle.c_str(), swizzle.c_str()); } - wxString value = src_mask ? code + GetMask(is_sca) : code; + wxString mask = GetMask(is_sca); + wxString value = src_mask ? code + mask : code; + + if(is_sca && d0.vec_result) + { + value = "vec4(" + value + ")" + mask; + } if(d0.staturate) { @@ -194,26 +208,28 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask wxString dest; if(d0.cond_update_enable_0) { - dest = m_parr.AddParam(PARAM_NONE, "float", "rc"); + dest = m_parr.AddParam(PARAM_NONE, "vec4", "rc", "vec4(0.0)") + mask; } else if(d3.dst == 5 || d3.dst == 6) { - int num = d3.dst == 5 ? 0 : 3; - if(d3.vec_writemask_x) { - ConLog.Error("Bad clip mask."); + dest = m_parr.AddParam(PARAM_OUT, "vec4", "fogc") + mask; } + else + { + int num = d3.dst == 5 ? 0 : 3; - //if(d3.vec_writemask_y) num += 0; - if(d3.vec_writemask_z) num += 1; - else if(d3.vec_writemask_w) num += 2; + //if(d3.vec_writemask_y) num += 0; + if(d3.vec_writemask_z) num += 1; + else if(d3.vec_writemask_w) num += 2; - dest = wxString::Format(GetDST(is_sca), num); + dest = wxString::Format(GetDST(is_sca) + "/*" + mask + "*/", num); + } } else { - dest = GetDST(is_sca) + GetMask(is_sca); + dest = GetDST(is_sca) + mask; } code = cond + dest + " = " + value; @@ -223,7 +239,7 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask code = cond + value; } - m_body.Add(code + wxString::Format(";//%d %d %d %d", d0.cond_reg_sel_1, d0.cond_test_enable, d0.cond_update_enable_0, d0.cond_update_enable_1)); + m_body.Add(code + ";"); } wxString GLVertexDecompilerThread::GetFunc() @@ -249,9 +265,9 @@ void GLVertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask, b AddCode(false, code, src_mask, set_dst); } -void GLVertexDecompilerThread::AddScaCode(const wxString& code, bool set_dst) +void GLVertexDecompilerThread::AddScaCode(const wxString& code, bool set_dst, bool set_cond) { - AddCode(true, code, false, set_dst); + AddCode(true, code, false, set_dst, set_cond); } wxString GLVertexDecompilerThread::BuildFuncBody(const FuncInfo& func) @@ -296,7 +312,7 @@ wxString GLVertexDecompilerThread::BuildCode() wxString fp = wxEmptyString; - for(int i=m_funcs.GetCount() - 1; i>=0; --i) + for(int i=m_funcs.GetCount() - 1; i>0; --i) { fp += wxString::Format("void %s();\n", m_funcs[i].name.mb_str()); } @@ -322,6 +338,8 @@ wxString GLVertexDecompilerThread::BuildCode() void GLVertexDecompilerThread::Task() { + m_parr.params.Clear(); + for(u32 i=0;;) { d0.HEX = m_data[i++]; @@ -339,17 +357,17 @@ void GLVertexDecompilerThread::Task() { case 0x00: break; // NOP case 0x01: AddScaCode(GetSRC(2, true)); break; // MOV - case 0x02: AddScaCode("1 / (" + GetSRC(2, true) + ")"); break; // RCP - case 0x03: AddScaCode("clamp(1 / (" + GetSRC(2, true) + "), 5.42101e-20, 1.884467e19)"); break; // RCC + case 0x02: AddScaCode("1.0 / " + GetSRC(2, true)); break; // RCP + case 0x03: AddScaCode("clamp(1.0 / " + GetSRC(2, true) + ", 5.42101e-20, 1.884467e19)"); break; // RCC case 0x04: AddScaCode("inversesqrt(" + GetSRC(2, true) + ")"); break; // RSQ case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG //case 0x07: break; // LIT - case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; return; }", false); break; // BRA - case 0x09: AddScaCode("{ " + GetFunc() + "; return; }", false); break; // BRI : works differently (BRI o[1].x(TR) L0;) - case 0x0a: AddScaCode("/*CAL*/ " + GetFunc(), false); break; // CAL : works same as BRI - case 0x0b: AddScaCode("/*CLI*/ " + GetFunc(), false); break; // CLI : works same as BRI - case 0x0c: AddScaCode("return", false); break; // RET : works like BRI but shorter (RET o[1].x(TR);) + case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; return; }", false, true); break; // BRA + case 0x09: AddScaCode("{ " + GetFunc() + "; return; }", false, true); break; // BRI : works differently (BRI o[1].x(TR) L0;) + case 0x0a: AddScaCode("/*CAL*/ " + GetFunc(), false, true); break; // CAL : works same as BRI + case 0x0b: AddScaCode("/*CLI*/ " + GetFunc(), false, true); break; // CLI : works same as BRI + case 0x0c: AddScaCode("return", false, true); break; // RET : works like BRI but shorter (RET o[1].x(TR);) case 0x0d: AddScaCode("log2(" + GetSRC(2, true) + ")"); break; // LG2 case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2 case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN diff --git a/rpcs3/Emu/GS/GL/GLVertexProgram.h b/rpcs3/Emu/GS/GL/GLVertexProgram.h index af5855d932..fde1ab1079 100644 --- a/rpcs3/Emu/GS/GL/GLVertexProgram.h +++ b/rpcs3/Emu/GS/GL/GLVertexProgram.h @@ -143,7 +143,7 @@ struct GLVertexDecompilerThread : public ThreadBase GLParamArray& m_parr; GLVertexDecompilerThread(Array& data, wxString& shader, GLParamArray& parr) - : ThreadBase(false, "Vertex Shader Decompiler Thread") + : ThreadBase("Vertex Shader Decompiler Thread") , m_data(data) , m_shader(shader) , m_parr(parr) @@ -160,9 +160,9 @@ struct GLVertexDecompilerThread : public ThreadBase wxString GetDST(bool is_sca = false); wxString GetSRC(const u32 n, bool is_sca = false); wxString GetFunc(); - void AddCode(bool is_sca, wxString code, bool src_mask = true, bool set_dst = true); + void AddCode(bool is_sca, wxString code, bool src_mask = true, bool set_dst = true, bool set_cond = true); void AddVecCode(const wxString& code, bool src_mask = true, bool set_dst = true); - void AddScaCode(const wxString& code, bool set_dst = true); + void AddScaCode(const wxString& code, bool set_dst = true, bool set_cond = true); wxString BuildFuncBody(const FuncInfo& func); wxString BuildCode(); @@ -182,9 +182,9 @@ struct GLVertexProgram void Wait() { - if(m_decompiler_thread && m_decompiler_thread->IsRunning()) + if(m_decompiler_thread && m_decompiler_thread->IsAlive()) { - m_decompiler_thread->Wait(); + m_decompiler_thread->Join(); } } diff --git a/rpcs3/Emu/GS/Null/NullGSRender.h b/rpcs3/Emu/GS/Null/NullGSRender.h index f2f2be04fb..cb9717a2dd 100644 --- a/rpcs3/Emu/GS/Null/NullGSRender.h +++ b/rpcs3/Emu/GS/Null/NullGSRender.h @@ -9,17 +9,17 @@ struct NullGSFrame : public GSFrame } void Draw() - { - wxClientDC dc(this); - Draw(&dc); - } + { + wxClientDC dc(this); + Draw(&dc); + } private: virtual void OnPaint(wxPaintEvent& event) - { - wxPaintDC dc(this); - Draw(&dc); - } + { + wxPaintDC dc(this); + Draw(&dc); + } virtual void OnSize(wxSizeEvent& event) { GSFrame::OnSize(event); @@ -77,7 +77,7 @@ private: virtual void Close() { - if(IsAlive()) Stop(); + Stop(); if(m_frame->IsShown()) m_frame->Hide(); } diff --git a/rpcs3/Emu/GS/RSXThread.h b/rpcs3/Emu/GS/RSXThread.h index 649f9d4ec1..5083e7b8ed 100644 --- a/rpcs3/Emu/GS/RSXThread.h +++ b/rpcs3/Emu/GS/RSXThread.h @@ -519,7 +519,7 @@ public: protected: RSXThread() - : ThreadBase(false, "RSXThread") + : ThreadBase("RSXThread") , m_ctrl(nullptr) , m_flip_status(0) , m_flip_mode(CELL_GCM_DISPLAY_VSYNC) diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index f8ebb5e112..053c0cf38d 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -691,12 +691,17 @@ struct _func_arg template struct _func_arg> { - __forceinline static u64 get_value(const mem_base_t& arg) + __forceinline static u64 get_value(const mem_base_t arg) { return arg.GetAddr(); } }; +template struct _func_arg> : public _func_arg> {}; +template<> struct _func_arg> : public _func_arg> {}; +template struct _func_arg> : public _func_arg> {}; +template struct _func_arg> : public _func_arg> {}; + template struct _func_arg> { diff --git a/rpcs3/Emu/SysCalls/Callback.cpp b/rpcs3/Emu/SysCalls/Callback.cpp index af7013fd8e..017341218d 100644 --- a/rpcs3/Emu/SysCalls/Callback.cpp +++ b/rpcs3/Emu/SysCalls/Callback.cpp @@ -53,23 +53,29 @@ void Callback::Branch(bool wait) { m_has_data = false; - CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); + CPUThread& thr = Emu.GetCallbackThread(); - new_thread.SetEntry(m_addr); - new_thread.SetPrio(1001); - new_thread.SetStackSize(0x10000); - new_thread.SetName(m_name); + while(Emu.IsRunning() && thr.IsAlive()) + Sleep(1); - new_thread.SetArg(0, a1); - new_thread.SetArg(1, a2); - new_thread.SetArg(2, a3); - new_thread.SetArg(3, a4); - new_thread.Run(); + thr.Stop(); + thr.Reset(); - new_thread.Exec(); + thr.SetEntry(m_addr); + thr.SetPrio(1001); + thr.SetStackSize(0x10000); + thr.SetName(m_name); + + thr.SetArg(0, a1); + thr.SetArg(1, a2); + thr.SetArg(2, a3); + thr.SetArg(3, a4); + thr.Run(); + + thr.Exec(); if(wait) - GetCurrentPPCThread()->Wait(new_thread); + GetCurrentPPCThread()->Wait(thr); } void Callback::SetName(const std::string& name) diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index c3bf7214fb..a6fa5a6830 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -193,11 +193,8 @@ int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, mem_func_ptr_t& GetBreakPoints() { return m_break_points; } Array& GetMarkedPoints() { return m_marked_points; } + CPUThread& GetCallbackThread() { return *m_ppu_callback_thr; } void AddModuleInit(ModuleInitializer* m) { diff --git a/rpcs3/Gui/ConLog.cpp b/rpcs3/Gui/ConLog.cpp index 34d6e1a6b9..884e0f4925 100644 --- a/rpcs3/Gui/ConLog.cpp +++ b/rpcs3/Gui/ConLog.cpp @@ -114,13 +114,16 @@ LogWriter::LogWriter() void LogWriter::WriteToLog(std::string prefix, std::string value, std::string colour/*, wxColour bgcolour*/) { - if(ThreadBase* thr = GetCurrentNamedThread()) + if(!prefix.empty()) { - prefix = (prefix.empty() ? "" : prefix + " : ") + thr->GetThreadName(); + if(NamedThreadBase* thr = GetCurrentNamedThread()) + { + prefix += " : " + thr->GetThreadName(); + } } if(m_logfile.IsOpened()) - m_logfile.Write((prefix.empty() ? wxString(wxEmptyString) : std::string("[" + prefix + "]: ") + value + "\n").c_str()); + m_logfile.Write((prefix.empty() ? "" : std::string("[" + prefix + "]: ") + value + "\n").c_str()); if(!ConLogFrame) return; @@ -221,7 +224,7 @@ END_EVENT_TABLE() LogFrame::LogFrame(wxWindow* parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(600, 500)) - , ThreadBase(false, "LogThread") + , ThreadBase("LogThread") , m_log(*new wxListView(this)) { m_log.InsertColumn(0, wxEmptyString); @@ -243,8 +246,8 @@ LogFrame::~LogFrame() bool LogFrame::Close(bool force) { - Stop(); - ConLogFrame = NULL; + Stop(false); + ConLogFrame = nullptr; return wxWindowBase::Close(force); } @@ -286,7 +289,7 @@ void LogFrame::Task() void LogFrame::OnQuit(wxCloseEvent& event) { - Stop(); - ConLogFrame = NULL; + Stop(false); + ConLogFrame = nullptr; event.Skip(); } diff --git a/rpcs3/Gui/DisAsmFrame.cpp b/rpcs3/Gui/DisAsmFrame.cpp index 6a3ba288ec..8967ef2111 100644 --- a/rpcs3/Gui/DisAsmFrame.cpp +++ b/rpcs3/Gui/DisAsmFrame.cpp @@ -121,7 +121,7 @@ class DumperThread : public ThreadBase wxArrayString** arr; public: - DumperThread() : ThreadBase(true, "DumperThread") + DumperThread() : ThreadBase("DumperThread") { } @@ -200,7 +200,7 @@ struct WaitDumperThread : public ThreadBase wxArrayString** arr; WaitDumperThread(bool* _done, u8 _cores, wxString _patch, MTProgressDialog& _prog_dial, wxArrayString** _arr) - : ThreadBase() + : ThreadBase("WaitDumperThread") , done(_done) , cores(_cores) , patch(_patch)