mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-04-04 22:18:53 +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
11 changed files with 99 additions and 122 deletions
|
|
@ -1742,9 +1742,11 @@ void thread_base::initialize(bool(*wait_cb)(const void*))
|
|||
|
||||
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
|
||||
struct THREADNAME_INFO
|
||||
{
|
||||
|
|
@ -1755,11 +1757,11 @@ void thread_base::initialize(bool(*wait_cb)(const void*))
|
|||
};
|
||||
|
||||
// Set thread name for VS debugger
|
||||
if (IsDebuggerPresent())
|
||||
if (IsDebuggerPresent()) [&]() NEVER_INLINE
|
||||
{
|
||||
THREADNAME_INFO info;
|
||||
info.dwType = 0x1000;
|
||||
info.szName = m_name.get().c_str();
|
||||
info.szName = name.c_str();
|
||||
info.dwThreadID = -1;
|
||||
info.dwFlags = 0;
|
||||
|
||||
|
|
@ -1770,17 +1772,19 @@ void thread_base::initialize(bool(*wait_cb)(const void*))
|
|||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
}
|
||||
}();
|
||||
#endif
|
||||
|
||||
#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__)
|
||||
pthread_set_name_np(pthread_self(), m_name.get().c_str());
|
||||
pthread_set_name_np(pthread_self(), name.c_str());
|
||||
#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)
|
||||
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
|
||||
|
||||
#ifdef __linux__
|
||||
|
|
@ -1842,7 +1846,7 @@ bool thread_base::finalize(int) noexcept
|
|||
|
||||
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]",
|
||||
|
|
@ -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)
|
||||
: m_name(name)
|
||||
: m_tname(stx::shared_cptr<std::string>::make(name))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "types.h"
|
||||
#include "util/atomic.hpp"
|
||||
#include "util/shared_cptr.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
|
@ -128,7 +129,7 @@ class thread_base
|
|||
atomic_t<const void*> m_state_notifier{nullptr};
|
||||
|
||||
// Thread name
|
||||
lf_value<std::string> m_name;
|
||||
stx::atomic_cptr<std::string> m_tname;
|
||||
|
||||
//
|
||||
atomic_t<u64> m_cycles = 0;
|
||||
|
|
@ -186,31 +187,34 @@ class thread_ctrl final
|
|||
|
||||
friend class thread_base;
|
||||
|
||||
// Optimized get_name() for logging
|
||||
static std::string get_name_cached();
|
||||
|
||||
public:
|
||||
// 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
|
||||
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)
|
||||
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)
|
||||
template <typename T>
|
||||
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>
|
||||
|
|
|
|||
|
|
@ -488,79 +488,3 @@ public:
|
|||
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));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue