From bdbbde4d367cfba45bc347e9955855562647f5b6 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 26 Dec 2014 01:49:55 +0300 Subject: [PATCH] squeue_t fixed --- Utilities/Thread.cpp | 59 +++++++++++++++++++++++--------------------- Utilities/Thread.h | 55 +++++++++++++++++++++++++++-------------- 2 files changed, 68 insertions(+), 46 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 6d6fdfa9c9..c5cfc6fe21 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -257,48 +257,51 @@ bool waiter_map_t::is_stopped(u64 signal_id) void waiter_map_t::waiter_reg_t::init() { - if (thread) return; + if (!thread) + { + thread = GetCurrentNamedThread(); - thread = GetCurrentNamedThread(); + std::lock_guard lock(map.m_mutex); - std::lock_guard lock(map.m_mutex); - - // add waiter - map.m_waiters.push_back({ signal_id, thread }); + // add waiter + map.m_waiters.push_back({ signal_id, thread }); + } } waiter_map_t::waiter_reg_t::~waiter_reg_t() { - if (!thread) return; - - std::lock_guard lock(map.m_mutex); - - // remove waiter - for (s64 i = map.m_waiters.size() - 1; i >= 0; i--) + if (thread) { - if (map.m_waiters[i].signal_id == signal_id && map.m_waiters[i].thread == thread) - { - map.m_waiters.erase(map.m_waiters.begin() + i); - return; - } - } + std::lock_guard lock(map.m_mutex); - LOG_ERROR(HLE, "%s(): waiter not found (signal_id=0x%llx, map='%s')", __FUNCTION__, signal_id, map.m_name.c_str()); - Emu.Pause(); + // remove waiter + for (s64 i = map.m_waiters.size() - 1; i >= 0; i--) + { + if (map.m_waiters[i].signal_id == signal_id && map.m_waiters[i].thread == thread) + { + map.m_waiters.erase(map.m_waiters.begin() + i); + return; + } + } + + LOG_ERROR(HLE, "%s(): waiter not found (signal_id=0x%llx, map='%s')", __FUNCTION__, signal_id, map.m_name.c_str()); + Emu.Pause(); + } } void waiter_map_t::notify(u64 signal_id) { - if (!m_waiters.size()) return; - - std::lock_guard lock(m_mutex); - - // find waiter and signal - for (auto& v : m_waiters) + if (m_waiters.size()) { - if (v.signal_id == signal_id) + std::lock_guard lock(m_mutex); + + // find waiter and signal + for (auto& v : m_waiters) { - v.thread->Notify(); + if (v.signal_id == signal_id) + { + v.thread->Notify(); + } } } } diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 30ed0b0186..92b57231c5 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -174,6 +174,13 @@ class squeue_t T m_data[sq_size]; + enum squeue_sync_var_result : u32 + { + SQSVR_OK = 0, + SQSVR_LOCKED = 1, + SQSVR_FAILED = 2, + }; + public: squeue_t() { @@ -194,22 +201,26 @@ public: { u32 pos = 0; - while (!m_sync.atomic_op_sync(true, [&pos](squeue_sync_var_t& sync) -> bool + while (u32 res = m_sync.atomic_op_sync(SQSVR_OK, [&pos](squeue_sync_var_t& sync) -> u32 { assert(sync.count <= sq_size); assert(sync.position < sq_size); - if (sync.write_lock || sync.count == sq_size) + if (sync.write_lock) { - return false; + return SQSVR_LOCKED; + } + if (sync.count == sq_size) + { + return SQSVR_FAILED; } sync.write_lock = 1; pos = sync.position + sync.count; - return true; + return SQSVR_OK; })) { - if (squeue_test_exit(do_exit)) + if (res == SQSVR_FAILED && squeue_test_exit(do_exit)) { return false; } @@ -245,22 +256,26 @@ public: { u32 pos = 0; - while (!m_sync.atomic_op_sync(true, [&pos](squeue_sync_var_t& sync) -> bool + while (u32 res = m_sync.atomic_op_sync(SQSVR_OK, [&pos](squeue_sync_var_t& sync) -> u32 { assert(sync.count <= sq_size); assert(sync.position < sq_size); - if (sync.read_lock || !sync.count) + if (sync.read_lock) { - return false; + return SQSVR_LOCKED; + } + if (!sync.count) + { + return SQSVR_FAILED; } sync.read_lock = 1; pos = sync.position; - return true; + return SQSVR_OK; })) { - if (squeue_test_exit(do_exit)) + if (res == SQSVR_FAILED && squeue_test_exit(do_exit)) { return false; } @@ -299,19 +314,19 @@ public: void clear() { - while (!m_sync.atomic_op_sync(true, [](squeue_sync_var_t& sync) -> bool + while (m_sync.atomic_op_sync(SQSVR_OK, [](squeue_sync_var_t& sync) -> u32 { assert(sync.count <= sq_size); assert(sync.position < sq_size); if (sync.read_lock || sync.write_lock) { - return false; + return SQSVR_LOCKED; } sync.read_lock = 1; sync.write_lock = 1; - return true; + return SQSVR_OK; })) { std::unique_lock rcv_lock(m_rcv_mutex); @@ -328,22 +343,26 @@ public: assert(start_pos < sq_size); u32 pos = 0; - while (!m_sync.atomic_op_sync(true, [&pos, start_pos](squeue_sync_var_t& sync) -> bool + while (u32 res = m_sync.atomic_op_sync(SQSVR_OK, [&pos, start_pos](squeue_sync_var_t& sync) -> u32 { assert(sync.count <= sq_size); assert(sync.position < sq_size); - if (sync.read_lock || sync.count <= start_pos) + if (sync.read_lock) { - return false; + return SQSVR_LOCKED; + } + if (sync.count <= start_pos) + { + return SQSVR_FAILED; } sync.read_lock = 1; pos = sync.position + start_pos; - return true; + return SQSVR_OK; })) { - if (squeue_test_exit(do_exit)) + if (res == SQSVR_FAILED && squeue_test_exit(do_exit)) { return false; }