Fixed conflicts

This commit is contained in:
Nekotekina 2014-02-01 01:56:44 +04:00
commit 6553909dc5
25 changed files with 367 additions and 291 deletions

View File

@ -1,97 +1,149 @@
#include "stdafx.h"
#include "Thread.h"
ThreadBase* GetCurrentNamedThread()
static DWORD g_tls_this_thread = 0xFFFFFFFF;
struct __init_tls
{
ThreadExec* thr = (ThreadExec*)::wxThread::This();
return thr ? thr->m_parent : nullptr;
//NamedThreadBase m_main_thr;
__init_tls()
{
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);
}
ThreadBase::ThreadBase(bool detached, const std::string& name)
: m_detached(detached)
, m_name(name)
, m_executor(nullptr)
~__init_tls()
{
::TlsFree(g_tls_this_thread);
}
} _init_tls;
NamedThreadBase* GetCurrentNamedThread()
{
return (NamedThreadBase*)::TlsGetValue(g_tls_this_thread);
}
void ThreadBase::Start()
{
if(m_executor) return;
m_executor = new ThreadExec(m_detached, this);
}
void ThreadBase::Resume()
{
if(m_executor)
{
m_executor->Resume();
}
}
void ThreadBase::Pause()
{
if(m_executor)
{
m_executor->Pause();
}
}
void ThreadBase::Stop(bool wait)
{
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);
}
}
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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> lock(m_main_mutex);
return m_alive;
}
bool ThreadBase::TestDestroy() const
{
return m_destroy;
}
thread::thread(const std::string& name, std::function<void()> func) : m_name(name)
{
start(func);
}
thread::thread(const std::string& name) : m_name(name)
{
}
thread::thread()
{
}
void thread::start(std::function<void()> 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();
}

View File

@ -3,84 +3,68 @@
#include <functional>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
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<bool> m_destroy;
std::atomic<bool> 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<std::mutex> lock(m_wait_for_exit);
}
}
ExitCode Entry()
{
//std::lock_guard<std::mutex> 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<void()> func);
thread(const std::string& name);
thread();
void start(std::function<void()> func);
void detach();
void join();
bool joinable() const;
};
template<typename T> class MTPacketBuffer
{

View File

@ -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,31 +15,25 @@ 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
{
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,6 +273,8 @@ void CPUThread::Exec()
#ifndef QT_UI
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
#endif
if(IsRunning())
ThreadBase::Start();
}
@ -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<u64>& 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());
}

View File

@ -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

View File

@ -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;

View File

@ -21,7 +21,7 @@ RawSPUThread::~RawSPUThread()
}
}
Close();
//Close();
}
bool RawSPUThread::Read8(const u64 addr, u8* value)

View File

@ -78,7 +78,7 @@ void SPUThread::DoRun()
break;
}
Pause();
//Pause();
//Emu.Pause();
}

View File

@ -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();
}

View File

@ -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<path.Length();p++)
for(uint p=1; path[p] != '\0'; p++)
{
for(; path[p] != '\0'; p++)
if(path[p] == '\\') break;

View File

@ -6,17 +6,18 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return;
const std::string mask = GetMask().c_str();
std::string cond = "";
std::string cond;
if(!src0.exec_if_gr || !src0.exec_if_lt || !src0.exec_if_eq)
{
static const char f[4] = {'x', 'y', 'z', 'w'};
std::string swizzle = "";
std::string swizzle;
swizzle += f[src0.cond_swizzle_x];
swizzle += f[src0.cond_swizzle_y];
swizzle += f[src0.cond_swizzle_z];
swizzle += f[src0.cond_swizzle_w];
swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
if(src0.exec_if_gr && src0.exec_if_eq)
{
@ -43,10 +44,7 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
cond = "equal";
}
cond = std::string("if(all(" + cond + "(" + AddCond(dst.no_dest) + "." + swizzle +", vec4(0, 0, 0, 0)))) ");
//ConLog.Error("cond! [eq: %d gr: %d lt: %d] (%s)", src0.exec_if_eq, src0.exec_if_gr, src0.exec_if_lt, cond);
//Emu.Pause();
//return;
cond = "if(all(" + cond + "(" + AddCond(dst.no_dest) + swizzle + ", vec4(0.0)))) ";
}
if(src1.scale)
@ -72,16 +70,28 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
code = "clamp(" + code + ", 0.0, 1.0)";
}
code = cond + (dst.set_cond ? m_parr.AddParam(PARAM_NONE , "vec4", std::string(dst.fp16 ? "hc" : "rc") + std::to_string(src0.cond_reg_index))
: AddReg(dst.dest_reg, dst.fp16)) + mask
+ " = " + code + (append_mask ? mask : "");
std::string dest;
if(dst.no_dest)
{
if(dst.set_cond)
{
dest = m_parr.AddParam(PARAM_NONE , "vec4", std::string(dst.fp16 ? "hc" : "rc") + std::to_string(src0.cond_reg_index));
}
}
else
{
dest = AddReg(dst.dest_reg, dst.fp16);
}
code = cond + (dest.length() ? dest + mask + " = " : "") + code + (append_mask ? mask : "");
main += "\t" + code + ";\n";
}
std::string GLFragmentDecompilerThread::GetMask()
{
std::string ret = "";
std::string ret;
static const char dst_mask[4] =
{
@ -98,17 +108,16 @@ std::string GLFragmentDecompilerThread::GetMask()
std::string GLFragmentDecompilerThread::AddReg(u32 index, int fp16)
{
/*
if(HasReg(index, fp16))
if(index >= 2 && index <= 4)
{
return wxString::Format((fp16 ? "h%u" : "r%u"), index);
return m_parr.AddParam(PARAM_OUT, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index),
(fp16) ? -1 : (index - 1));
}
*/
//ConLog.Warning("%c%d: %d %d", (fp16 ? 'h' : 'r'), index, dst.tex_num, src2.use_index_reg);
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));
//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));
}
bool GLFragmentDecompilerThread::HasReg(u32 index, int fp16)
@ -219,6 +228,15 @@ std::string GLFragmentDecompilerThread::BuildCode()
p += m_parr.params[i].Format();
}
//return "#version 330\n\
\n\
out vec3 color;\n\
in vec4 tc1;\n\
\n\
void main()\n\
{\n\
color = tc1.rgb;\n\
}";
return std::string("#version 330\n"
"\n"
+ p + "\n"

View File

@ -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);

View File

@ -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;

View File

@ -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];
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());
}
//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());
}
wxString mask = GetMask(is_sca);
wxString value = src_mask ? code + mask : code;
wxString value = src_mask ? code + GetMask(is_sca) : 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;
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

View File

@ -143,7 +143,7 @@ struct GLVertexDecompilerThread : public ThreadBase
GLParamArray& m_parr;
GLVertexDecompilerThread(Array<u32>& 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();
}
}

View File

@ -77,7 +77,7 @@ private:
virtual void Close()
{
if(IsAlive()) Stop();
Stop();
if(m_frame->IsShown()) m_frame->Hide();
}

View File

@ -265,7 +265,6 @@ public:
u32 m_report_main_addr;
u32 m_local_mem_addr, m_main_mem_addr;
Array<MemInfo> m_main_mem_info;
public:
uint m_draw_mode;
@ -520,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)
@ -637,7 +636,7 @@ protected:
switch(location)
{
case CELL_GCM_LOCATION_LOCAL: return m_local_mem_addr + offset;
case CELL_GCM_LOCATION_MAIN: return m_main_mem_addr + offset;
case CELL_GCM_LOCATION_MAIN: return Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + offset);
}
ConLog.Error("GetAddress(offset=0x%x, location=0x%x)", location);

View File

@ -691,12 +691,17 @@ struct _func_arg
template<typename T>
struct _func_arg<mem_base_t<T>>
{
__forceinline static u64 get_value(const mem_base_t<T>& arg)
__forceinline static u64 get_value(const mem_base_t<T> arg)
{
return arg.GetAddr();
}
};
template<typename T> struct _func_arg<mem_ptr_t<T>> : public _func_arg<mem_base_t<T>> {};
template<> struct _func_arg<mem_ptr_t<void>> : public _func_arg<mem_base_t<u8>> {};
template<typename T> struct _func_arg<mem_list_ptr_t<T>> : public _func_arg<mem_base_t<T>> {};
template<typename T> struct _func_arg<mem_t<T>> : public _func_arg<mem_base_t<T>> {};
template<typename T>
struct _func_arg<be_t<T>>
{

View File

@ -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)

View File

@ -107,7 +107,6 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
render.m_tiles_addr = Memory.Alloc(sizeof(CellGcmTileInfo) * 15, sizeof(CellGcmTileInfo));
render.m_gcm_buffers_count = 0;
render.m_gcm_current_buffer = 0;
render.m_main_mem_info.Clear();
render.m_main_mem_addr = 0;
render.Init(ctx_begin, ctx_size, gcm_info.control_addr, local_addr);
@ -725,7 +724,6 @@ int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset)
}
Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress;
Emu.GetGSManager().GetRender().m_main_mem_info.AddCpy(MemInfo(ea, size));
return CELL_OK;
}

View File

@ -193,11 +193,8 @@ int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, mem_func_ptr_t<void
//get a unique id for the callback (may be used by cellFsAioCancel)
const u32 xid = g_FsAioReadID++;
//read data in another thread (doesn't work correctly):
//std::thread t(fsAioRead, fd, aio, xid, func);
//t.detach();
//read data immediately (actually it should be read in special thread):
fsAioRead(fd, aio, xid, func);
thread t("fsAioRead", std::bind(fsAioRead, fd, aio, xid, func));
t.detach();
aio_id = xid;

View File

@ -23,9 +23,11 @@ void sys_ppu_thread_exit(int errorcode)
PPUThread& thr = GetCurrentPPUThread();
thr.SetExitStatus(errorcode);
Emu.GetCPU().RemoveThread(thr.GetId());
thr.Stop();
throw errorcode;
//Emu.GetCPU().RemoveThread(thr.GetId());
//throw errorcode;
}
int sys_ppu_thread_yield()

View File

@ -27,6 +27,7 @@ Emulator::Emulator()
, m_mode(DisAsm)
, m_dbg_console(nullptr)
, m_rsx_callback(0)
, m_ppu_callback_thr(0)
{
}
@ -310,6 +311,8 @@ void Emulator::Load()
case MACHINE_PPC64:
{
m_ppu_callback_thr = &GetCPU().AddThread(CPU_THREAD_PPU);
thread.SetEntry(l.GetEntry());
Memory.StackMem.Alloc(0x1000);
thread.InitStack();

View File

@ -88,6 +88,8 @@ class Emulator
GSManager m_gs_manager;
AudioManager m_audio_manager;
CallbackManager m_callback_manager;
CPUThread* m_ppu_callback_thr;
VFS m_vfs;
EmuInfo m_info;
@ -125,6 +127,7 @@ public:
VFS& GetVFS() { return m_vfs; }
Array<u64>& GetBreakPoints() { return m_break_points; }
Array<u64>& GetMarkedPoints() { return m_marked_points; }
CPUThread& GetCallbackThread() { return *m_ppu_callback_thr; }
void AddModuleInit(ModuleInitializer* m)
{

View File

@ -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();
}

View File

@ -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)