mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
Remove global condition waiter registry that deadlocks exception delivery
Co-authored-by: Bipin <bipinkrish4@gmail.com>
This commit is contained in:
+7
-45
@@ -8,7 +8,6 @@
|
|||||||
#include <chrono> // IWYU pragma: keep
|
#include <chrono> // IWYU pragma: keep
|
||||||
#include <condition_variable> // IWYU pragma: keep
|
#include <condition_variable> // IWYU pragma: keep
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS && KYTY_COMPILER == KYTY_COMPILER_CLANG
|
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS && KYTY_COMPILER == KYTY_COMPILER_CLANG
|
||||||
#define KYTY_WIN_CS
|
#define KYTY_WIN_CS
|
||||||
@@ -197,38 +196,8 @@ struct CondVarPrivate {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::recursive_mutex g_cond_waiters_mutex;
|
|
||||||
static std::vector<std::pair<int, CondVarPrivate*>> g_cond_waiters;
|
|
||||||
static wait_poll_func_t g_cond_wait_poll_callback = nullptr;
|
static wait_poll_func_t g_cond_wait_poll_callback = nullptr;
|
||||||
|
|
||||||
static void WakeCondVar(CondVarPrivate* cond_var) {
|
|
||||||
#ifdef KYTY_WIN_CS
|
|
||||||
static auto func = ResolveWakeAllConditionVariable();
|
|
||||||
EXIT_NOT_IMPLEMENTED(func == nullptr);
|
|
||||||
func(&cond_var->m_cv);
|
|
||||||
#else
|
|
||||||
cond_var->m_cv.notify_all();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void RegisterCondWaiter(CondVarPrivate* cond_var) {
|
|
||||||
std::lock_guard lock(g_cond_waiters_mutex);
|
|
||||||
g_cond_waiters.emplace_back(Thread::GetThreadIdUnique(), cond_var);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UnregisterCondWaiter(CondVarPrivate* cond_var) {
|
|
||||||
const auto thread_id = Thread::GetThreadIdUnique();
|
|
||||||
std::lock_guard lock(g_cond_waiters_mutex);
|
|
||||||
|
|
||||||
const auto it = std::find_if(g_cond_waiters.begin(), g_cond_waiters.end(),
|
|
||||||
[thread_id, cond_var](const auto& waiter) {
|
|
||||||
return waiter.first == thread_id && waiter.second == cond_var;
|
|
||||||
});
|
|
||||||
if (it != g_cond_waiters.end()) {
|
|
||||||
g_cond_waiters.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ThreadPrivate {
|
struct ThreadPrivate {
|
||||||
ThreadPrivate(thread_func_t f, void* a): func(f), arg(a), m_thread(&Run, this) {}
|
ThreadPrivate(thread_func_t f, void* a): func(f), arg(a), m_thread(&Run, this) {}
|
||||||
|
|
||||||
@@ -365,7 +334,6 @@ CondVar::~CondVar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CondVar::Wait(Mutex* mutex) {
|
void CondVar::Wait(Mutex* mutex) {
|
||||||
RegisterCondWaiter(m_cond_var.get());
|
|
||||||
#ifndef KYTY_WIN_CS
|
#ifndef KYTY_WIN_CS
|
||||||
std::unique_lock<std::recursive_mutex> cpp_lock(mutex->m_mutex->m_mutex, std::adopt_lock_t());
|
std::unique_lock<std::recursive_mutex> cpp_lock(mutex->m_mutex->m_mutex, std::adopt_lock_t());
|
||||||
#endif
|
#endif
|
||||||
@@ -406,7 +374,6 @@ void CondVar::Wait(Mutex* mutex) {
|
|||||||
}
|
}
|
||||||
cpp_lock.release();
|
cpp_lock.release();
|
||||||
#endif
|
#endif
|
||||||
UnregisterCondWaiter(m_cond_var.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CondVar::SetWaitPollCallback(wait_poll_func_t callback) {
|
void CondVar::SetWaitPollCallback(wait_poll_func_t callback) {
|
||||||
@@ -415,7 +382,6 @@ void CondVar::SetWaitPollCallback(wait_poll_func_t callback) {
|
|||||||
|
|
||||||
bool CondVar::WaitFor(Mutex* mutex, uint32_t micros) {
|
bool CondVar::WaitFor(Mutex* mutex, uint32_t micros) {
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
RegisterCondWaiter(m_cond_var.get());
|
|
||||||
#ifndef KYTY_WIN_CS
|
#ifndef KYTY_WIN_CS
|
||||||
std::unique_lock<std::recursive_mutex> cpp_lock(mutex->m_mutex->m_mutex, std::adopt_lock_t());
|
std::unique_lock<std::recursive_mutex> cpp_lock(mutex->m_mutex->m_mutex, std::adopt_lock_t());
|
||||||
#endif
|
#endif
|
||||||
@@ -430,7 +396,6 @@ bool CondVar::WaitFor(Mutex* mutex, uint32_t micros) {
|
|||||||
std::cv_status::no_timeout);
|
std::cv_status::no_timeout);
|
||||||
cpp_lock.release();
|
cpp_lock.release();
|
||||||
#endif
|
#endif
|
||||||
UnregisterCondWaiter(m_cond_var.get());
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,16 +410,13 @@ void CondVar::Signal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CondVar::SignalAll() {
|
void CondVar::SignalAll() {
|
||||||
WakeCondVar(m_cond_var.get());
|
#ifdef KYTY_WIN_CS
|
||||||
}
|
static auto func = ResolveWakeAllConditionVariable();
|
||||||
|
EXIT_NOT_IMPLEMENTED(func == nullptr);
|
||||||
void CondVar::SignalThread(int thread_id) {
|
func(&m_cond_var->m_cv);
|
||||||
std::lock_guard lock(g_cond_waiters_mutex);
|
#else
|
||||||
for (const auto& waiter: g_cond_waiters) {
|
m_cond_var->m_cv.notify_all();
|
||||||
if (waiter.first == thread_id) {
|
#endif
|
||||||
WakeCondVar(waiter.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Thread::GetThreadIdUnique() {
|
int Thread::GetThreadIdUnique() {
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ public:
|
|||||||
void Signal();
|
void Signal();
|
||||||
void SignalAll();
|
void SignalAll();
|
||||||
|
|
||||||
static void SignalThread(int thread_id);
|
|
||||||
static void SetWaitPollCallback(wait_poll_func_t callback);
|
static void SetWaitPollCallback(wait_poll_func_t callback);
|
||||||
|
|
||||||
KYTY_CLASS_NO_COPY(CondVar);
|
KYTY_CLASS_NO_COPY(CondVar);
|
||||||
|
|||||||
@@ -3093,10 +3093,6 @@ Pthread PthreadSwapSelfForSignal(Pthread thread) {
|
|||||||
return previous;
|
return previous;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PthreadGetUniqueId(Pthread thread) {
|
|
||||||
return thread != nullptr ? thread->unique_id : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t PthreadGetHostThreadId(Pthread thread) {
|
uint64_t PthreadGetHostThreadId(Pthread thread) {
|
||||||
return thread != nullptr ? thread->host_thread_id : 0;
|
return thread != nullptr ? thread->host_thread_id : 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ int KYTY_SYSV_ABI PthreadRename(Pthread thread, const char* name);
|
|||||||
void KYTY_SYSV_ABI PthreadYield();
|
void KYTY_SYSV_ABI PthreadYield();
|
||||||
int KYTY_SYSV_ABI PthreadGetthreadid();
|
int KYTY_SYSV_ABI PthreadGetthreadid();
|
||||||
int KYTY_SYSV_ABI PthreadGetaffinity(Pthread thread, KernelCpumask* mask);
|
int KYTY_SYSV_ABI PthreadGetaffinity(Pthread thread, KernelCpumask* mask);
|
||||||
int PthreadGetUniqueId(Pthread thread);
|
|
||||||
uint64_t PthreadGetHostThreadId(Pthread thread);
|
uint64_t PthreadGetHostThreadId(Pthread thread);
|
||||||
void PthreadWakeForSignal(Pthread thread);
|
void PthreadWakeForSignal(Pthread thread);
|
||||||
void PthreadQueuePendingSignal(Pthread thread, int signum);
|
void PthreadQueuePendingSignal(Pthread thread, int signum);
|
||||||
|
|||||||
@@ -1168,7 +1168,6 @@ static int KYTY_SYSV_ABI KernelRaiseException(Pthread thread, int signum) {
|
|||||||
return KERNEL_ERROR_EINVAL;
|
return KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::CondVar::SignalThread(PthreadGetUniqueId(thread));
|
|
||||||
PthreadWakeForSignal(thread);
|
PthreadWakeForSignal(thread);
|
||||||
CloseHandle(target_thread);
|
CloseHandle(target_thread);
|
||||||
return OK;
|
return OK;
|
||||||
@@ -1193,7 +1192,6 @@ static int KYTY_SYSV_ABI KernelRaiseException(Pthread thread, int signum) {
|
|||||||
return KERNEL_ERROR_EINVAL;
|
return KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::CondVar::SignalThread(PthreadGetUniqueId(thread));
|
|
||||||
PthreadWakeForSignal(thread);
|
PthreadWakeForSignal(thread);
|
||||||
WaitForSignalDispatch(thread, signum);
|
WaitForSignalDispatch(thread, signum);
|
||||||
return OK;
|
return OK;
|
||||||
|
|||||||
Reference in New Issue
Block a user