1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-21 18:22:33 +01:00

Improve get_current_cpu_thread()

This commit is contained in:
Eladash 2021-05-20 07:00:22 +03:00
parent 04cac6cd33
commit 638f20c80f
8 changed files with 58 additions and 25 deletions

View File

@ -1449,19 +1449,17 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
u64 data1 = addr;
u64 data2 = 0;
if (cpu->id_type() == 1)
if (cpu->try_get<ppu_thread>())
{
data2 = (SYS_MEMORY_PAGE_FAULT_TYPE_PPU_THREAD << 32) | cpu->id;
}
else if (cpu->id_type() == 2)
else if (auto spu = cpu->try_get<spu_thread>())
{
const auto& spu = static_cast<spu_thread&>(*cpu);
const u64 type = spu.get_type() == spu_type::threaded ?
const u64 type = spu->get_type() == spu_type::threaded ?
SYS_MEMORY_PAGE_FAULT_TYPE_SPU_THREAD :
SYS_MEMORY_PAGE_FAULT_TYPE_RAW_SPU;
data2 = (type << 32) | spu.lv2_id;
data2 = (type << 32) | spu->lv2_id;
}
u64 data3;

View File

@ -5,6 +5,10 @@
#include <vector>
template <typename Derived, typename Base>
concept derived_from = std::is_base_of_v<Base, Derived> &&
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
// Thread state flags
enum class cpu_flag : u32
{
@ -107,6 +111,30 @@ public:
return id >> 24;
}
template <derived_from<cpu_thread> T>
T* try_get()
{
if constexpr (std::is_same_v<std::remove_const_t<T>, cpu_thread>)
{
return this;
}
else
{
if (id_type() == (T::id_base >> 24))
{
return static_cast<T*>(this);
}
return nullptr;
}
}
template <derived_from<cpu_thread> T>
const T* try_get() const
{
return const_cast<cpu_thread*>(this)->try_get<const T>();
}
u32 get_pc() const;
u32* get_pc2(); // Last PC before stepping for the debugger (may be null)
@ -244,15 +272,25 @@ public:
// Send signal to the profiler(s) to flush results
static void flush_profilers() noexcept;
template <derived_from<cpu_thread> T = cpu_thread>
static inline T* get_current() noexcept
{
if (const auto cpu = g_tls_this_thread)
{
return cpu->try_get<T>();
}
return nullptr;
}
private:
static thread_local cpu_thread* g_tls_this_thread;
friend cpu_thread* get_current_cpu_thread() noexcept;
};
inline cpu_thread* get_current_cpu_thread() noexcept
template <derived_from<cpu_thread> T = cpu_thread>
inline T* get_current_cpu_thread() noexcept
{
return cpu_thread::g_tls_this_thread;
return cpu_thread::get_current<T>();
}
class ppu_thread;

View File

@ -1273,7 +1273,7 @@ void ppu_thread::fast_call(u32 addr, u32 rtoc)
u32 ppu_thread::stack_push(u32 size, u32 align_v)
{
if (auto cpu = get_current_cpu_thread()) if (cpu->id_type() == 1)
if (auto cpu = get_current_cpu_thread<ppu_thread>())
{
ppu_thread& context = static_cast<ppu_thread&>(*cpu);
@ -1299,7 +1299,7 @@ u32 ppu_thread::stack_push(u32 size, u32 align_v)
void ppu_thread::stack_pop_verbose(u32 addr, u32 size) noexcept
{
if (auto cpu = get_current_cpu_thread()) if (cpu->id_type() == 1)
if (auto cpu = get_current_cpu_thread<ppu_thread>())
{
ppu_thread& context = static_cast<ppu_thread&>(*cpu);

View File

@ -2041,10 +2041,10 @@ void spu_thread::do_dma_transfer(spu_thread* _this, const spu_mfc_cmd& args, u8*
continue;
}
const auto cpu = static_cast<spu_thread*>(get_current_cpu_thread());
const auto cpu = get_current_cpu_thread<spu_thread>();
alignas(64) u8 temp[128];
u8* dst0 = cpu && cpu->id_type() != 1 && (eal & -128) == cpu->raddr ? temp : dst;
u8* dst0 = cpu && (eal & -128) == cpu->raddr ? temp : dst;
if (dst0 == +temp && time0 != cpu->rtime)
{

View File

@ -1143,7 +1143,7 @@ void lv2_obj::sleep_unlocked(cpu_thread& thread, u64 timeout)
{
const u64 start_time = get_guest_system_time();
if (auto ppu = static_cast<ppu_thread*>(thread.id_type() == 1 ? &thread : nullptr))
if (auto ppu = thread.try_get<ppu_thread>())
{
ppu_log.trace("sleep() - waiting (%zu)", g_pending.size());

View File

@ -565,8 +565,8 @@ bool gdb_thread::cmd_read_register(gdb_cmd& cmd)
return send_cmd_ack("E02");
}
auto th = selected_thread.lock();
if (th->id_type() == 1) {
auto ppu = static_cast<named_thread<ppu_thread>*>(th.get());
if (auto ppu = th->try_get<named_thread<ppu_thread>>())
{
u32 rid = hex_to_u32(cmd.data);
std::string result = get_reg(ppu, rid);
if (result.empty()) {

View File

@ -658,6 +658,8 @@ namespace rsx
std::string dump_regs() const override;
void cpu_wait(bs_t<cpu_flag> old) override;
static constexpr u32 id_base = 0x5555'5555; // See get_current_cpu_thread()
// Performance approximation counters
struct
{

View File

@ -1666,16 +1666,11 @@ s32 error_code::error_report(s32 result, const char* fmt, const fmt_type_info* s
logs::channel* channel = &sys_log;
const char* func = "Unknown function";
if (auto thread = get_current_cpu_thread())
if (auto ppu = get_current_cpu_thread<ppu_thread>())
{
if (thread->id_type() == 1)
if (ppu->current_function)
{
auto& ppu = static_cast<ppu_thread&>(*thread);
if (ppu.current_function)
{
func = ppu.current_function;
}
func = ppu->current_function;
}
}