mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 12:12:50 +01:00
Clean thread pool at exit.
Execute TLS destructors. Test atomic wait list.
This commit is contained in:
parent
16cc88dd0e
commit
a4458e2c8c
@ -2035,9 +2035,11 @@ u64 thread_base::finalize(u64 _self) noexcept
|
|||||||
g_tls_wait_fail = 0;
|
g_tls_wait_fail = 0;
|
||||||
g_tls_access_violation_recovered = false;
|
g_tls_access_violation_recovered = false;
|
||||||
|
|
||||||
|
const auto fake_self = reinterpret_cast<thread_base*>(_self);
|
||||||
|
|
||||||
atomic_wait_engine::set_wait_callback(nullptr);
|
atomic_wait_engine::set_wait_callback(nullptr);
|
||||||
g_tls_log_prefix = []() -> std::string { return {}; };
|
g_tls_log_prefix = []() -> std::string { return {}; };
|
||||||
thread_ctrl::g_tls_this_thread = nullptr;
|
thread_ctrl::g_tls_this_thread = fake_self;
|
||||||
|
|
||||||
if (!_self)
|
if (!_self)
|
||||||
{
|
{
|
||||||
@ -2047,6 +2049,43 @@ u64 thread_base::finalize(u64 _self) noexcept
|
|||||||
// Try to add self to thread pool
|
// Try to add self to thread pool
|
||||||
set_name("..pool");
|
set_name("..pool");
|
||||||
|
|
||||||
|
static constexpr u64 s_stop_bit = 0x8000'0000'0000'0000ull;
|
||||||
|
|
||||||
|
static atomic_t<u64> s_pool_ctr = []
|
||||||
|
{
|
||||||
|
std::atexit([]
|
||||||
|
{
|
||||||
|
s_pool_ctr |= s_stop_bit;
|
||||||
|
|
||||||
|
while (u64 remains = s_pool_ctr & ~s_stop_bit)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < std::size(s_thread_pool); i++)
|
||||||
|
{
|
||||||
|
if (thread_base** ptls = s_thread_pool[i].exchange(nullptr))
|
||||||
|
{
|
||||||
|
// Extract thread handle
|
||||||
|
const u64 _self = reinterpret_cast<u64>(*ptls);
|
||||||
|
|
||||||
|
// Wake up a thread and make sure it's joined
|
||||||
|
s_thread_pool[i].notify_all();
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
const HANDLE handle = reinterpret_cast<HANDLE>(_self);
|
||||||
|
WaitForSingleObject(handle, INFINITE);
|
||||||
|
CloseHandle(handle);
|
||||||
|
#else
|
||||||
|
pthread_join(reinterpret_cast<pthread_t>(_self), nullptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}();
|
||||||
|
|
||||||
|
s_pool_ctr++;
|
||||||
|
|
||||||
u32 pos = -1;
|
u32 pos = -1;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
@ -2075,9 +2114,18 @@ u64 thread_base::finalize(u64 _self) noexcept
|
|||||||
const auto tls = &thread_ctrl::g_tls_this_thread;
|
const auto tls = &thread_ctrl::g_tls_this_thread;
|
||||||
s_thread_pool[pos] = tls;
|
s_thread_pool[pos] = tls;
|
||||||
|
|
||||||
while (s_thread_pool[pos] == tls || !atomic_storage<thread_base*>::load(*tls))
|
atomic_wait::list<2> list{};
|
||||||
|
list.set<0>(s_pool_ctr, 0, s_stop_bit);
|
||||||
|
list.set<1>(s_thread_pool[pos], tls);
|
||||||
|
|
||||||
|
while (s_thread_pool[pos] == tls || atomic_storage<thread_base*>::load(*tls) == fake_self)
|
||||||
{
|
{
|
||||||
s_thread_pool[pos].wait(tls);
|
list.wait();
|
||||||
|
|
||||||
|
if (s_pool_ctr & s_stop_bit)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free thread pool slot
|
// Free thread pool slot
|
||||||
@ -2088,6 +2136,11 @@ u64 thread_base::finalize(u64 _self) noexcept
|
|||||||
|
|
||||||
s_thread_bits.notify_one();
|
s_thread_bits.notify_one();
|
||||||
|
|
||||||
|
if (--s_pool_ctr & s_stop_bit)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Restore thread id
|
// Restore thread id
|
||||||
const auto _this = atomic_storage<thread_base*>::load(*tls);
|
const auto _this = atomic_storage<thread_base*>::load(*tls);
|
||||||
const auto entry = _this->m_thread.exchange(_self);
|
const auto entry = _this->m_thread.exchange(_self);
|
||||||
@ -2218,7 +2271,9 @@ thread_base::~thread_base()
|
|||||||
if ((m_sync & 3) == 2)
|
if ((m_sync & 3) == 2)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
CloseHandle(reinterpret_cast<HANDLE>(m_thread.load()));
|
const HANDLE handle0 = reinterpret_cast<HANDLE>(m_thread.load());
|
||||||
|
WaitForSingleObject(handle0, INFINITE);
|
||||||
|
CloseHandle(handle0);
|
||||||
#else
|
#else
|
||||||
pthread_join(reinterpret_cast<pthread_t>(m_thread.load()), nullptr);
|
pthread_join(reinterpret_cast<pthread_t>(m_thread.load()), nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user