mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-16 03:38:38 +12:00
ThreadBase rewritten (wip)
This commit is contained in:
parent
b7a320fbbd
commit
3aefa2b4e1
85 changed files with 1960 additions and 2183 deletions
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "Utilities/Thread.h"
|
||||
|
||||
enum CPUThreadType : unsigned char
|
||||
enum CPUThreadType
|
||||
{
|
||||
CPU_THREAD_PPU,
|
||||
CPU_THREAD_SPU,
|
||||
|
@ -9,80 +10,85 @@ enum CPUThreadType : unsigned char
|
|||
CPU_THREAD_ARMv7,
|
||||
};
|
||||
|
||||
enum CPUThreadStatus
|
||||
{
|
||||
CPUThread_Ready,
|
||||
CPUThread_Running,
|
||||
CPUThread_Paused,
|
||||
CPUThread_Stopped,
|
||||
CPUThread_Sleeping,
|
||||
CPUThread_Break,
|
||||
CPUThread_Step,
|
||||
};
|
||||
|
||||
// CPU Thread Events
|
||||
// CPU Thread State Flags
|
||||
enum : u64
|
||||
{
|
||||
CPU_EVENT_STOP = (1ull << 0),
|
||||
CPU_STATE_STOP = (1ull << 0), // basic execution state (stopped by default), removed by Exec()
|
||||
CPU_STATE_PAUSE = (1ull << 1), // paused by debugger (manually or after step execution)
|
||||
CPU_STATE_SLEEP = (1ull << 2),
|
||||
CPU_STATE_STEP = (1ull << 3),
|
||||
CPU_STATE_DEAD = (1ull << 4),
|
||||
};
|
||||
|
||||
// "HLE return" exception event
|
||||
class CPUThreadReturn{};
|
||||
|
||||
// CPUThread::Stop exception event
|
||||
class CPUThreadStop{};
|
||||
|
||||
// CPUThread::Exit exception event
|
||||
class CPUThreadExit{};
|
||||
|
||||
class CPUDecoder;
|
||||
|
||||
class CPUThread : public ThreadBase
|
||||
class CPUThread : protected thread_t
|
||||
{
|
||||
protected:
|
||||
std::atomic<u64> m_events; // flags
|
||||
atomic<u64> m_state; // thread state flags
|
||||
|
||||
u32 m_status;
|
||||
u32 m_id;
|
||||
u64 m_prio;
|
||||
CPUThreadType m_type;
|
||||
bool m_joinable;
|
||||
bool m_joining;
|
||||
bool m_is_step;
|
||||
std::unique_ptr<CPUDecoder> m_dec;
|
||||
|
||||
u32 m_stack_addr;
|
||||
u32 m_stack_size;
|
||||
|
||||
u64 m_exit_status;
|
||||
|
||||
CPUDecoder* m_dec;
|
||||
|
||||
bool m_trace_call_stack;
|
||||
|
||||
virtual void DumpInformation() override;
|
||||
const u32 m_id;
|
||||
const CPUThreadType m_type;
|
||||
const std::string m_name; // changing m_name would be terribly thread-unsafe in current implementation
|
||||
|
||||
public:
|
||||
void AddEvent(const u64 event) { m_events |= event; }
|
||||
using thread_t::mutex;
|
||||
using thread_t::cv;
|
||||
|
||||
protected:
|
||||
CPUThread(CPUThreadType type, const std::string& name, std::function<std::string()> thread_name);
|
||||
|
||||
public:
|
||||
virtual ~CPUThread() override;
|
||||
|
||||
u32 GetId() const { return m_id; }
|
||||
CPUThreadType GetType() const { return m_type; }
|
||||
std::string GetName() const { return m_name; }
|
||||
|
||||
bool IsActive() const { return (m_state.load() & CPU_STATE_DEAD) == 0; }
|
||||
bool IsStopped() const { return (m_state.load() & CPU_STATE_STOP) != 0; }
|
||||
virtual bool IsPaused() const;
|
||||
|
||||
virtual void DumpInformation() const;
|
||||
virtual u32 GetPC() const = 0;
|
||||
virtual u32 GetOffset() const = 0;
|
||||
virtual void DoRun() = 0;
|
||||
virtual void Task() = 0;
|
||||
|
||||
virtual void InitRegs() = 0;
|
||||
|
||||
virtual void InitStack() = 0;
|
||||
virtual void CloseStack() = 0;
|
||||
|
||||
u32 GetStackAddr() const { return m_stack_addr; }
|
||||
u32 GetStackSize() const { return m_stack_size; }
|
||||
void Run();
|
||||
void Pause();
|
||||
void Resume();
|
||||
void Stop();
|
||||
void Exec();
|
||||
void Exit();
|
||||
void Step(); // set STEP status, don't use
|
||||
void Sleep(); // flip SLEEP status, don't use
|
||||
void Awake(); // flip SLEEP status, don't use
|
||||
bool CheckStatus(); // process m_state flags, returns true if must return from Task()
|
||||
|
||||
void SetStackAddr(u32 stack_addr) { m_stack_addr = stack_addr; }
|
||||
void SetStackSize(u32 stack_size) { m_stack_size = stack_size; }
|
||||
|
||||
void SetId(const u32 id);
|
||||
void SetName(const std::string& name);
|
||||
void SetPrio(const u64 prio) { m_prio = prio; }
|
||||
void SetExitStatus(const u64 status) { m_exit_status = status; }
|
||||
|
||||
u64 GetPrio() const { return m_prio; }
|
||||
u64 GetExitStatus() const { return m_exit_status; }
|
||||
|
||||
std::string GetName() const { return NamedThreadBase::GetThreadName(); }
|
||||
std::string GetFName() const
|
||||
{
|
||||
return fmt::format("%s[0x%x] Thread (%s)", GetTypeString(), m_id, GetName());
|
||||
return fmt::format("%s[0x%x] Thread (%s)", GetTypeString(), m_id, m_name);
|
||||
}
|
||||
|
||||
static std::string CPUThreadTypeToString(CPUThreadType type)
|
||||
static const char* CPUThreadTypeToString(CPUThreadType type)
|
||||
{
|
||||
switch(type)
|
||||
switch (type)
|
||||
{
|
||||
case CPU_THREAD_PPU: return "PPU";
|
||||
case CPU_THREAD_SPU: return "SPU";
|
||||
|
@ -93,82 +99,38 @@ public:
|
|||
return "Unknown";
|
||||
}
|
||||
|
||||
std::string ThreadStatusToString()
|
||||
const char* ThreadStatusToString()
|
||||
{
|
||||
switch (ThreadStatus())
|
||||
{
|
||||
case CPUThread_Ready: return "Ready";
|
||||
case CPUThread_Running: return "Running";
|
||||
case CPUThread_Paused: return "Paused";
|
||||
case CPUThread_Stopped: return "Stopped";
|
||||
case CPUThread_Sleeping: return "Sleeping";
|
||||
case CPUThread_Break: return "Break";
|
||||
case CPUThread_Step: return "Step";
|
||||
// TODO
|
||||
|
||||
default: return "Unknown status";
|
||||
}
|
||||
//switch (ThreadStatus())
|
||||
//{
|
||||
//case CPUThread_Ready: return "Ready";
|
||||
//case CPUThread_Running: return "Running";
|
||||
//case CPUThread_Paused: return "Paused";
|
||||
//case CPUThread_Stopped: return "Stopped";
|
||||
//case CPUThread_Sleeping: return "Sleeping";
|
||||
//case CPUThread_Break: return "Break";
|
||||
//case CPUThread_Step: return "Step";
|
||||
//}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
std::string GetTypeString() const { return CPUThreadTypeToString(m_type); }
|
||||
|
||||
virtual std::string GetThreadName() const
|
||||
const char* GetTypeString() const
|
||||
{
|
||||
return fmt::format("%s[0x%08x]", GetFName(), PC);
|
||||
return CPUThreadTypeToString(m_type);
|
||||
}
|
||||
|
||||
CPUDecoder * GetDecoder() { return m_dec; };
|
||||
CPUDecoder* GetDecoder()
|
||||
{
|
||||
return m_dec.get();
|
||||
};
|
||||
|
||||
public:
|
||||
u32 entry;
|
||||
u32 PC;
|
||||
u32 nPC;
|
||||
u32 index;
|
||||
u32 offset;
|
||||
bool m_is_branch;
|
||||
bool m_trace_enabled;
|
||||
u64 m_last_syscall;
|
||||
|
||||
protected:
|
||||
CPUThread(CPUThreadType type);
|
||||
|
||||
public:
|
||||
virtual ~CPUThread();
|
||||
|
||||
int ThreadStatus();
|
||||
|
||||
void NextPc(u32 instr_size);
|
||||
void SetBranch(const u32 pc, bool record_branch = false);
|
||||
void SetPc(const u32 pc);
|
||||
void SetEntry(const u32 entry);
|
||||
|
||||
bool IsRunning() const;
|
||||
bool IsPaused() const;
|
||||
bool IsStopped() const;
|
||||
|
||||
bool IsJoinable() const { return m_joinable; }
|
||||
bool IsJoining() const { return m_joining; }
|
||||
void SetJoinable(bool joinable) { m_joinable = joinable; }
|
||||
void SetJoining(bool joining) { m_joining = joining; }
|
||||
|
||||
u32 GetId() const { return m_id; }
|
||||
CPUThreadType GetType() const { return m_type; }
|
||||
|
||||
void SetCallStackTracing(bool trace_call_stack) { m_trace_call_stack = trace_call_stack; }
|
||||
|
||||
void Reset();
|
||||
void Close();
|
||||
void Run();
|
||||
void Pause();
|
||||
void Resume();
|
||||
void Stop();
|
||||
|
||||
virtual std::string RegsToString() = 0;
|
||||
virtual std::string ReadRegString(const std::string& reg) = 0;
|
||||
virtual std::string RegsToString() const = 0;
|
||||
virtual std::string ReadRegString(const std::string& reg) const = 0;
|
||||
virtual bool WriteRegString(const std::string& reg, std::string value) = 0;
|
||||
|
||||
virtual void Exec();
|
||||
void ExecOnce();
|
||||
|
||||
struct CallStackItem
|
||||
{
|
||||
u32 pc;
|
||||
|
@ -207,7 +169,7 @@ public:
|
|||
CallStackItem new_item;
|
||||
|
||||
new_item.branch_pc = pc;
|
||||
new_item.pc = PC;
|
||||
new_item.pc = GetPC();
|
||||
|
||||
m_call_stack.push_back(new_item);
|
||||
}
|
||||
|
@ -216,17 +178,6 @@ public:
|
|||
{
|
||||
return pc + 4;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void DoReset()=0;
|
||||
virtual void DoRun()=0;
|
||||
virtual void DoPause()=0;
|
||||
virtual void DoResume()=0;
|
||||
virtual void DoStop()=0;
|
||||
|
||||
protected:
|
||||
virtual void Step() {}
|
||||
virtual void Task();
|
||||
};
|
||||
|
||||
class cpu_thread
|
||||
|
@ -235,32 +186,32 @@ protected:
|
|||
std::shared_ptr<CPUThread> thread;
|
||||
|
||||
public:
|
||||
u32 get_entry() const
|
||||
{
|
||||
return thread->entry;
|
||||
}
|
||||
//u32 get_entry() const
|
||||
//{
|
||||
// return thread->entry;
|
||||
//}
|
||||
|
||||
virtual cpu_thread& args(std::initializer_list<std::string> values) = 0;
|
||||
|
||||
virtual cpu_thread& run() = 0;
|
||||
|
||||
u64 join()
|
||||
{
|
||||
if (!joinable())
|
||||
throw "thread must be joinable for join";
|
||||
//u64 join()
|
||||
//{
|
||||
// if (!joinable())
|
||||
// throw "thread must be joinable for join";
|
||||
|
||||
thread->SetJoinable(false);
|
||||
// thread->SetJoinable(false);
|
||||
|
||||
while (thread->IsRunning())
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
// while (thread->IsRunning())
|
||||
// std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
|
||||
return thread->GetExitStatus();
|
||||
}
|
||||
// return thread->GetExitStatus();
|
||||
//}
|
||||
|
||||
bool joinable() const
|
||||
{
|
||||
return thread->IsJoinable();
|
||||
}
|
||||
//bool joinable() const
|
||||
//{
|
||||
// return thread->IsJoinable();
|
||||
//}
|
||||
|
||||
u32 get_id() const
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue