mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-17 19:21:04 +00:00
Remove cancerous lf_value<>
Replace thread names (generic, PPU, SPU) with new shared pointers. Devirtualize cpu_thread::get_name (used in single case).
This commit is contained in:
parent
bf4bdf73b7
commit
65eeee0f4c
@ -1742,9 +1742,11 @@ void thread_base::initialize(bool(*wait_cb)(const void*))
|
|||||||
|
|
||||||
g_tls_log_prefix = []
|
g_tls_log_prefix = []
|
||||||
{
|
{
|
||||||
return thread_ctrl::g_tls_this_thread->m_name.get();
|
return thread_ctrl::get_name_cached();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string name = thread_ctrl::get_name_cached();
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
struct THREADNAME_INFO
|
struct THREADNAME_INFO
|
||||||
{
|
{
|
||||||
@ -1755,11 +1757,11 @@ void thread_base::initialize(bool(*wait_cb)(const void*))
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Set thread name for VS debugger
|
// Set thread name for VS debugger
|
||||||
if (IsDebuggerPresent())
|
if (IsDebuggerPresent()) [&]() NEVER_INLINE
|
||||||
{
|
{
|
||||||
THREADNAME_INFO info;
|
THREADNAME_INFO info;
|
||||||
info.dwType = 0x1000;
|
info.dwType = 0x1000;
|
||||||
info.szName = m_name.get().c_str();
|
info.szName = name.c_str();
|
||||||
info.dwThreadID = -1;
|
info.dwThreadID = -1;
|
||||||
info.dwFlags = 0;
|
info.dwFlags = 0;
|
||||||
|
|
||||||
@ -1770,17 +1772,19 @@ void thread_base::initialize(bool(*wait_cb)(const void*))
|
|||||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
pthread_setname_np(m_name.get().substr(0, 15).c_str());
|
name.resize(std::min<std::size_t>(15, name.size()));
|
||||||
|
pthread_setname_np(name.c_str());
|
||||||
#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||||
pthread_set_name_np(pthread_self(), m_name.get().c_str());
|
pthread_set_name_np(pthread_self(), name.c_str());
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
pthread_setname_np(pthread_self(), "%s", const_cast<char*>(m_name.get().c_str()));
|
pthread_setname_np(pthread_self(), "%s", name.data());
|
||||||
#elif !defined(_WIN32)
|
#elif !defined(_WIN32)
|
||||||
pthread_setname_np(pthread_self(), m_name.get().substr(0, 15).c_str());
|
name.resize(std::min<std::size_t>(15, name.size()));
|
||||||
|
pthread_setname_np(pthread_self(), name.c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@ -1842,7 +1846,7 @@ bool thread_base::finalize(int) noexcept
|
|||||||
|
|
||||||
g_tls_log_prefix = []
|
g_tls_log_prefix = []
|
||||||
{
|
{
|
||||||
return thread_ctrl::g_tls_this_thread->m_name.get();
|
return thread_ctrl::get_name_cached();
|
||||||
};
|
};
|
||||||
|
|
||||||
sig_log.notice("Thread time: %fs (%fGc); Faults: %u [rsx:%u, spu:%u]; [soft:%u hard:%u]; Switches:[vol:%u unvol:%u]",
|
sig_log.notice("Thread time: %fs (%fGc); Faults: %u [rsx:%u, spu:%u]; [soft:%u hard:%u]; Switches:[vol:%u unvol:%u]",
|
||||||
@ -1934,8 +1938,27 @@ void thread_ctrl::_wait_for(u64 usec, bool alert /* true */)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string thread_ctrl::get_name_cached()
|
||||||
|
{
|
||||||
|
auto _this = thread_ctrl::g_tls_this_thread;
|
||||||
|
|
||||||
|
if (!_this)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static thread_local stx::shared_cptr<std::string> name_cache;
|
||||||
|
|
||||||
|
if (!_this->m_tname.is_equal(name_cache)) [[unlikely]]
|
||||||
|
{
|
||||||
|
name_cache = _this->m_tname.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *name_cache;
|
||||||
|
}
|
||||||
|
|
||||||
thread_base::thread_base(std::string_view name)
|
thread_base::thread_base(std::string_view name)
|
||||||
: m_name(name)
|
: m_tname(stx::shared_cptr<std::string>::make(name))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "util/atomic.hpp"
|
#include "util/atomic.hpp"
|
||||||
|
#include "util/shared_cptr.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -128,7 +129,7 @@ class thread_base
|
|||||||
atomic_t<const void*> m_state_notifier{nullptr};
|
atomic_t<const void*> m_state_notifier{nullptr};
|
||||||
|
|
||||||
// Thread name
|
// Thread name
|
||||||
lf_value<std::string> m_name;
|
stx::atomic_cptr<std::string> m_tname;
|
||||||
|
|
||||||
//
|
//
|
||||||
atomic_t<u64> m_cycles = 0;
|
atomic_t<u64> m_cycles = 0;
|
||||||
@ -186,31 +187,34 @@ class thread_ctrl final
|
|||||||
|
|
||||||
friend class thread_base;
|
friend class thread_base;
|
||||||
|
|
||||||
|
// Optimized get_name() for logging
|
||||||
|
static std::string get_name_cached();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Get current thread name
|
// Get current thread name
|
||||||
static std::string_view get_name()
|
static std::string get_name()
|
||||||
{
|
{
|
||||||
return g_tls_this_thread->m_name.get();
|
return *g_tls_this_thread->m_tname.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get thread name
|
// Get thread name
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static std::string_view get_name(const named_thread<T>& thread)
|
static std::string get_name(const named_thread<T>& thread)
|
||||||
{
|
{
|
||||||
return static_cast<const thread_base&>(thread).m_name.get();
|
return *static_cast<const thread_base&>(thread).m_tname.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set current thread name (not recommended)
|
// Set current thread name (not recommended)
|
||||||
static void set_name(std::string_view name)
|
static void set_name(std::string_view name)
|
||||||
{
|
{
|
||||||
g_tls_this_thread->m_name.assign(name);
|
g_tls_this_thread->m_tname.store(stx::shared_cptr<std::string>::make(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set thread name (not recommended)
|
// Set thread name (not recommended)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void set_name(named_thread<T>& thread, std::string_view name)
|
static void set_name(named_thread<T>& thread, std::string_view name)
|
||||||
{
|
{
|
||||||
static_cast<thread_base&>(thread).m_name.assign(name);
|
static_cast<thread_base&>(thread).m_tname.store(stx::shared_cptr<std::string>::make(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -488,79 +488,3 @@ public:
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Assignable lock-free thread-safe value of any type (memory-inefficient)
|
|
||||||
template <typename T>
|
|
||||||
class lf_value final
|
|
||||||
{
|
|
||||||
atomic_t<lf_value*> m_head;
|
|
||||||
|
|
||||||
T m_data;
|
|
||||||
|
|
||||||
public:
|
|
||||||
template <typename... Args>
|
|
||||||
explicit constexpr lf_value(Args&&... args)
|
|
||||||
: m_head(this)
|
|
||||||
, m_data(std::forward<Args>(args)...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~lf_value()
|
|
||||||
{
|
|
||||||
// All values are kept in the queue until the end
|
|
||||||
for (lf_value* ptr = m_head.load(); ptr != this;)
|
|
||||||
{
|
|
||||||
delete std::exchange(ptr, std::exchange(ptr->m_head.raw(), ptr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get current head, allows to inspect old values
|
|
||||||
[[nodiscard]] const lf_value* head() const
|
|
||||||
{
|
|
||||||
return m_head.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inspect the initial (oldest) value
|
|
||||||
[[nodiscard]] const T& first() const
|
|
||||||
{
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const T& get() const
|
|
||||||
{
|
|
||||||
return m_head.load()->m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] operator const T&() const
|
|
||||||
{
|
|
||||||
return m_head.load()->m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct new value in-place
|
|
||||||
template <typename... Args>
|
|
||||||
const T& assign(Args&&... args)
|
|
||||||
{
|
|
||||||
lf_value* val = new lf_value(std::forward<Args>(args)...);
|
|
||||||
lf_value* old = m_head.load();
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
val->m_head = old;
|
|
||||||
}
|
|
||||||
while (!m_head.compare_exchange(old, val));
|
|
||||||
|
|
||||||
return val->m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy-assign new value
|
|
||||||
const T& operator =(const T& value)
|
|
||||||
{
|
|
||||||
return assign(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move-assign new value
|
|
||||||
const T& operator =(T&& value)
|
|
||||||
{
|
|
||||||
return assign(std::move(value));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
@ -512,7 +512,7 @@ void cpu_thread::notify()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Invalid cpu_thread type");
|
fmt::throw_exception("Invalid cpu_thread type" HERE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,7 +529,24 @@ void cpu_thread::abort()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Invalid cpu_thread type");
|
fmt::throw_exception("Invalid cpu_thread type" HERE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string cpu_thread::get_name() const
|
||||||
|
{
|
||||||
|
// Downcast to correct type
|
||||||
|
if (id_type() == 1)
|
||||||
|
{
|
||||||
|
return thread_ctrl::get_name(*static_cast<const named_thread<ppu_thread>*>(this));
|
||||||
|
}
|
||||||
|
else if (id_type() == 2)
|
||||||
|
{
|
||||||
|
return thread_ctrl::get_name(*static_cast<const named_thread<spu_thread>*>(this));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fmt::throw_exception("Invalid cpu_thread type" HERE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check thread type
|
// Check thread type
|
||||||
u32 id_type()
|
u32 id_type() const
|
||||||
{
|
{
|
||||||
return id >> 24;
|
return id >> 24;
|
||||||
}
|
}
|
||||||
@ -88,8 +88,8 @@ public:
|
|||||||
// Thread stats for external observation
|
// Thread stats for external observation
|
||||||
static atomic_t<u64> g_threads_created, g_threads_deleted;
|
static atomic_t<u64> g_threads_created, g_threads_deleted;
|
||||||
|
|
||||||
// Get thread name
|
// Get thread name (as assigned to named_thread)
|
||||||
virtual std::string get_name() const = 0;
|
std::string get_name() const;
|
||||||
|
|
||||||
// Get CPU state dump
|
// Get CPU state dump
|
||||||
virtual std::string dump() const;
|
virtual std::string dump() const;
|
||||||
|
@ -430,11 +430,6 @@ void ppu_thread::on_cleanup(named_thread<ppu_thread>* _this)
|
|||||||
idm::remove<named_thread<ppu_thread>>(_this->id);
|
idm::remove<named_thread<ppu_thread>>(_this->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ppu_thread::get_name() const
|
|
||||||
{
|
|
||||||
return fmt::format("PPU[0x%x] Thread (%s)", id, ppu_name.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ppu_thread::dump() const
|
std::string ppu_thread::dump() const
|
||||||
{
|
{
|
||||||
std::string ret = cpu_thread::dump();
|
std::string ret = cpu_thread::dump();
|
||||||
@ -718,7 +713,7 @@ ppu_thread::ppu_thread(const ppu_thread_params& param, std::string_view name, u3
|
|||||||
, stack_addr(param.stack_addr)
|
, stack_addr(param.stack_addr)
|
||||||
, joiner(-!!detached)
|
, joiner(-!!detached)
|
||||||
, start_time(get_guest_system_time())
|
, start_time(get_guest_system_time())
|
||||||
, ppu_name(name)
|
, ppu_tname(stx::shared_cptr<std::string>::make(name))
|
||||||
{
|
{
|
||||||
gpr[1] = stack_addr + stack_size - 0x70;
|
gpr[1] = stack_addr + stack_size - 0x70;
|
||||||
|
|
||||||
@ -830,7 +825,15 @@ void ppu_thread::fast_call(u32 addr, u32 rtoc)
|
|||||||
g_tls_log_prefix = []
|
g_tls_log_prefix = []
|
||||||
{
|
{
|
||||||
const auto _this = static_cast<ppu_thread*>(get_current_cpu_thread());
|
const auto _this = static_cast<ppu_thread*>(get_current_cpu_thread());
|
||||||
return fmt::format("%s [0x%08x]", thread_ctrl::get_name(), _this->cia);
|
|
||||||
|
static thread_local stx::shared_cptr<std::string> name_cache;
|
||||||
|
|
||||||
|
if (!_this->ppu_tname.is_equal(name_cache)) [[unlikely]]
|
||||||
|
{
|
||||||
|
name_cache = _this->ppu_tname.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt::format("PPU[0x%x] Thread (%s) [0x%08x]", _this->id, *name_cache.get(), _this->cia);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto at_ret = [&]()
|
auto at_ret = [&]()
|
||||||
|
@ -46,7 +46,6 @@ public:
|
|||||||
|
|
||||||
static void on_cleanup(named_thread<ppu_thread>*);
|
static void on_cleanup(named_thread<ppu_thread>*);
|
||||||
|
|
||||||
virtual std::string get_name() const override;
|
|
||||||
virtual std::string dump() const override;
|
virtual std::string dump() const override;
|
||||||
virtual void cpu_task() override final;
|
virtual void cpu_task() override final;
|
||||||
virtual void cpu_sleep() override;
|
virtual void cpu_sleep() override;
|
||||||
@ -186,7 +185,8 @@ public:
|
|||||||
const char* current_function{}; // Current function name for diagnosis, optimized for speed.
|
const char* current_function{}; // Current function name for diagnosis, optimized for speed.
|
||||||
const char* last_function{}; // Sticky copy of current_function, is not cleared on function return
|
const char* last_function{}; // Sticky copy of current_function, is not cleared on function return
|
||||||
|
|
||||||
lf_value<std::string> ppu_name; // Thread name
|
// Thread name
|
||||||
|
stx::atomic_cptr<std::string> ppu_tname;
|
||||||
|
|
||||||
be_t<u64>* get_stack_arg(s32 i, u64 align = alignof(u64));
|
be_t<u64>* get_stack_arg(s32 i, u64 align = alignof(u64));
|
||||||
void exec_task();
|
void exec_task();
|
||||||
|
@ -1008,11 +1008,6 @@ spu_imm_table_t::spu_imm_table_t()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string spu_thread::get_name() const
|
|
||||||
{
|
|
||||||
return fmt::format("%sSPU[0x%07x] Thread (%s)", offset >= RAW_SPU_BASE_ADDR ? "Raw" : "", lv2_id, spu_name.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string spu_thread::dump() const
|
std::string spu_thread::dump() const
|
||||||
{
|
{
|
||||||
std::string ret = cpu_thread::dump();
|
std::string ret = cpu_thread::dump();
|
||||||
@ -1163,7 +1158,15 @@ void spu_thread::cpu_task()
|
|||||||
g_tls_log_prefix = []
|
g_tls_log_prefix = []
|
||||||
{
|
{
|
||||||
const auto cpu = static_cast<spu_thread*>(get_current_cpu_thread());
|
const auto cpu = static_cast<spu_thread*>(get_current_cpu_thread());
|
||||||
return fmt::format("%s [0x%05x]", thread_ctrl::get_name(), cpu->pc);
|
|
||||||
|
static thread_local stx::shared_cptr<std::string> name_cache;
|
||||||
|
|
||||||
|
if (!cpu->spu_tname.is_equal(name_cache)) [[unlikely]]
|
||||||
|
{
|
||||||
|
name_cache = cpu->spu_tname.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt::format("%sSPU[0x%07x] Thread (%s) [0x%05x]", cpu->offset >= RAW_SPU_BASE_ADDR ? "Raw" : "", cpu->lv2_id, *name_cache.get(), cpu->pc);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (jit)
|
if (jit)
|
||||||
@ -1237,7 +1240,7 @@ spu_thread::spu_thread(vm::addr_t ls, lv2_spu_group* group, u32 index, std::stri
|
|||||||
, offset(ls)
|
, offset(ls)
|
||||||
, group(group)
|
, group(group)
|
||||||
, lv2_id(lv2_id)
|
, lv2_id(lv2_id)
|
||||||
, spu_name(name)
|
, spu_tname(stx::shared_cptr<std::string>::make(name))
|
||||||
{
|
{
|
||||||
if (g_cfg.core.spu_decoder == spu_decoder_type::asmjit)
|
if (g_cfg.core.spu_decoder == spu_decoder_type::asmjit)
|
||||||
{
|
{
|
||||||
|
@ -498,7 +498,6 @@ public:
|
|||||||
class spu_thread : public cpu_thread
|
class spu_thread : public cpu_thread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual std::string get_name() const override;
|
|
||||||
virtual std::string dump() const override;
|
virtual std::string dump() const override;
|
||||||
virtual void cpu_task() override final;
|
virtual void cpu_task() override final;
|
||||||
virtual void cpu_mem() override;
|
virtual void cpu_mem() override;
|
||||||
@ -588,7 +587,7 @@ public:
|
|||||||
u32 npc; // SPU Next Program Counter register
|
u32 npc; // SPU Next Program Counter register
|
||||||
};
|
};
|
||||||
|
|
||||||
atomic_t<status_npc_sync_var> status_npc;
|
atomic_t<status_npc_sync_var> status_npc;
|
||||||
|
|
||||||
std::array<spu_int_ctrl_t, 3> int_ctrl; // SPU Class 0, 1, 2 Interrupt Management
|
std::array<spu_int_ctrl_t, 3> int_ctrl; // SPU Class 0, 1, 2 Interrupt Management
|
||||||
|
|
||||||
@ -602,7 +601,8 @@ private:
|
|||||||
public:
|
public:
|
||||||
const u32 lv2_id; // The actual id that is used by syscalls
|
const u32 lv2_id; // The actual id that is used by syscalls
|
||||||
|
|
||||||
lf_value<std::string> spu_name; // Thread name
|
// Thread name
|
||||||
|
stx::atomic_cptr<std::string> spu_tname;
|
||||||
|
|
||||||
std::unique_ptr<class spu_recompiler_base> jit; // Recompiler instance
|
std::unique_ptr<class spu_recompiler_base> jit; // Recompiler instance
|
||||||
|
|
||||||
|
@ -385,7 +385,7 @@ error_code sys_ppu_thread_start(ppu_thread& ppu, u32 thread_id)
|
|||||||
thread_ctrl::notify(*thread);
|
thread_ctrl::notify(*thread);
|
||||||
|
|
||||||
// Dirty hack for sound: confirm the creation of _mxr000 event queue
|
// Dirty hack for sound: confirm the creation of _mxr000 event queue
|
||||||
if (thread->ppu_name.get() == "_cellsurMixerMain"sv)
|
if (*thread->ppu_tname.load() == "_cellsurMixerMain"sv)
|
||||||
{
|
{
|
||||||
lv2_obj::sleep(ppu);
|
lv2_obj::sleep(ppu);
|
||||||
|
|
||||||
@ -432,9 +432,12 @@ error_code sys_ppu_thread_rename(u32 thread_id, vm::cptr<char> name)
|
|||||||
constexpr u32 max_size = 27; // max size including null terminator
|
constexpr u32 max_size = 27; // max size including null terminator
|
||||||
const auto pname = name.get_ptr();
|
const auto pname = name.get_ptr();
|
||||||
|
|
||||||
|
// Make valid name
|
||||||
|
auto _name = stx::shared_cptr<std::string>::make(pname, std::find(pname, pname + max_size, '\0'));
|
||||||
|
|
||||||
// thread_ctrl name is not changed (TODO)
|
// thread_ctrl name is not changed (TODO)
|
||||||
const std::string res = thread->ppu_name.assign(pname, std::find(pname, pname + max_size, '\0'));
|
sys_ppu_thread.warning(u8"sys_ppu_thread_rename(): Thread renamed to “%s”", *_name);
|
||||||
sys_ppu_thread.warning(u8"sys_ppu_thread_rename(): Thread renamed to “%s”", res);
|
thread->ppu_tname.store(std::move(_name));
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ void kernel_explorer::Update()
|
|||||||
idm::select<named_thread<ppu_thread>>([&](u32 id, ppu_thread& ppu)
|
idm::select<named_thread<ppu_thread>>([&](u32 id, ppu_thread& ppu)
|
||||||
{
|
{
|
||||||
lv2_types.back().count++;
|
lv2_types.back().count++;
|
||||||
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("PPU Thread: ID = 0x%08x '%s'", id, ppu.ppu_name.get())));
|
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("PPU Thread: ID = 0x%08x '%s'", id, *ppu.ppu_tname.load())));
|
||||||
});
|
});
|
||||||
|
|
||||||
lv2_types.emplace_back(l_addTreeChild(root, "SPU Threads"));
|
lv2_types.emplace_back(l_addTreeChild(root, "SPU Threads"));
|
||||||
@ -279,7 +279,7 @@ void kernel_explorer::Update()
|
|||||||
idm::select<named_thread<spu_thread>>([&](u32 /*id*/, spu_thread& spu)
|
idm::select<named_thread<spu_thread>>([&](u32 /*id*/, spu_thread& spu)
|
||||||
{
|
{
|
||||||
lv2_types.back().count++;
|
lv2_types.back().count++;
|
||||||
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("SPU Thread: ID = 0x%08x '%s'", spu.lv2_id, spu.spu_name.get())));
|
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("SPU Thread: ID = 0x%08x '%s'", spu.lv2_id, *spu.spu_tname.load())));
|
||||||
});
|
});
|
||||||
|
|
||||||
lv2_types.emplace_back(l_addTreeChild(root, "SPU Thread Groups"));
|
lv2_types.emplace_back(l_addTreeChild(root, "SPU Thread Groups"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user