From a45f86a4a28b9804e8e9e6f28d48a24ae22c931b Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 9 Sep 2019 01:29:18 +0300 Subject: [PATCH] Remove `notifier` class Poorly implemented condition variable. --- Utilities/cond.cpp | 94 ------------------------------- Utilities/cond.h | 67 ---------------------- Utilities/typemap.h | 12 ---- rpcs3/Emu/Memory/vm.cpp | 4 +- rpcs3/Emu/Memory/vm_reservation.h | 3 - 5 files changed, 2 insertions(+), 178 deletions(-) diff --git a/Utilities/cond.cpp b/Utilities/cond.cpp index 6b1e47c1c5..8c70be1b3f 100644 --- a/Utilities/cond.cpp +++ b/Utilities/cond.cpp @@ -54,100 +54,6 @@ void cond_variable::imp_wake(u32 _count) noexcept })); } -bool notifier::imp_try_lock(u32 count) -{ - return m_counter.atomic_op([&](u32& value) - { - if ((value % (max_readers + 1)) + count <= max_readers) - { - value += count; - return true; - } - - return false; - }); -} - -void notifier::imp_unlock(u32 count) -{ - const u32 counter = m_counter.sub_fetch(count); - - if (UNLIKELY(counter % (max_readers + 1))) - { - return; - } - - if (counter) - { - const u32 _old = m_counter.atomic_op([](u32& value) -> u32 - { - if (value % (max_readers + 1)) - { - return 0; - } - - return std::exchange(value, 0) / (max_readers + 1); - }); - - const u32 wc = m_cond.m_value; - - if (_old && wc) - { - m_cond.imp_wake(_old > wc ? wc : _old); - } - } -} - -u32 notifier::imp_notify(u32 count) -{ - return m_counter.atomic_op([&](u32& value) -> u32 - { - if (const u32 add = value % (max_readers + 1)) - { - // Mutex is locked - const u32 result = add > count ? count : add; - value += result * (max_readers + 1); - return result; - } - else - { - // Mutex is unlocked - value = 0; - return count; - } - }); -} - -bool notifier::wait(u64 usec_timeout) -{ - const u32 _old = m_cond.m_value.fetch_add(1); - - if (max_readers < m_counter.fetch_op([](u32& value) - { - if (value > max_readers) - { - value -= max_readers; - } - - value -= 1; - })) - { - // Return without waiting - m_cond.imp_wait(_old, 0); - return true; - } - - const bool res = m_cond.imp_wait(_old, usec_timeout); - - while (!try_lock_shared()) - { - // TODO - busy_wait(); - } - - return res; -} - bool unique_cond::imp_wait(u64 _timeout) noexcept { // State transition: c_sig -> c_lock \ c_lock -> c_wait diff --git a/Utilities/cond.h b/Utilities/cond.h index 1b483e79fc..02c9143e14 100644 --- a/Utilities/cond.h +++ b/Utilities/cond.h @@ -11,8 +11,6 @@ class cond_variable // Internal waiter counter atomic_t m_value{0}; - friend class notifier; - protected: // Internal waiting function bool imp_wait(u32 _old, u64 _timeout) noexcept; @@ -64,71 +62,6 @@ public: static constexpr u64 max_timeout = u64{UINT32_MAX} / 1000 * 1000000; }; -// Pair of a fake shared mutex (only limited shared locking) and a condition variable. Obsolete. -class notifier -{ - atomic_t m_counter{0}; - cond_variable m_cond; - - bool imp_try_lock(u32 count); - - void imp_unlock(u32 count); - - u32 imp_notify(u32 count); - -public: - constexpr notifier() = default; - - bool try_lock() - { - return imp_try_lock(max_readers); - } - - void unlock() - { - imp_unlock(max_readers); - } - - bool try_lock_shared() - { - return imp_try_lock(1); - } - - void unlock_shared() - { - imp_unlock(1); - } - - bool wait(u64 usec_timeout = -1); - - void notify_all() - { - if (m_counter) - { - imp_notify(-1); - } - - // Notify after imaginary "exclusive" lock+unlock - m_cond.notify_all(); - } - - void notify_one() - { - // TODO - if (m_counter) - { - if (imp_notify(1)) - { - return; - } - } - - m_cond.notify_one(); - } - - static constexpr u32 max_readers = 0x7f; -}; - // Condition variable fused with a pseudo-mutex which is never supposed to be locked concurrently. class unique_cond { diff --git a/Utilities/typemap.h b/Utilities/typemap.h index c0b4ec41a7..f32c5bcefc 100644 --- a/Utilities/typemap.h +++ b/Utilities/typemap.h @@ -283,9 +283,6 @@ namespace utils // Increased on each destructor call atomic_t m_destroy_count{0}; - // Waitable object for the semaphore, signaled on decrease - ::notifier m_free_notifier; - // Aligned size of the storage for each object uint m_ssize = 0; @@ -340,9 +337,6 @@ namespace utils // Return semaphore m_head->m_sema--; } - - // Signal free ID availability - m_head->m_free_notifier.notify_all(); } } @@ -1048,11 +1042,5 @@ namespace utils { return get_head()->m_destroy_count; } - - template - std::shared_lock<::notifier> get_free_notifier() const - { - return std::shared_lock(get_head()->m_free_notifier, std::try_to_lock); - } }; } // namespace utils diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index d49ba517bd..314a2d580c 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -17,7 +17,7 @@ #include #include -static_assert(sizeof(notifier) == 8, "Unexpected size of notifier"); +static_assert(sizeof(shared_cond) == 8, "Unexpected size of shared_cond"); namespace vm { @@ -1060,7 +1060,7 @@ namespace vm } lock.upgrade(); - + // Allocation on arbitrary address if (location != any && location < g_locations.size()) { diff --git a/rpcs3/Emu/Memory/vm_reservation.h b/rpcs3/Emu/Memory/vm_reservation.h index a727bed5cb..e3ee7ea6b1 100644 --- a/rpcs3/Emu/Memory/vm_reservation.h +++ b/rpcs3/Emu/Memory/vm_reservation.h @@ -4,11 +4,8 @@ #include "Utilities/cond.h" #include "util/atomic.hpp" -class notifier; - namespace vm { - // Get reservation status for further atomic update: last update timestamp inline atomic_t& reservation_acquire(u32 addr, u32 size) {