diff --git a/Utilities/Log.cpp b/Utilities/Log.cpp index ee76f7d307..322277ee8c 100644 --- a/Utilities/Log.cpp +++ b/Utilities/Log.cpp @@ -75,7 +75,7 @@ namespace logs #endif uchar* m_fptr{}; z_stream m_zs{}; - semaphore<> m_m; + shared_mutex m_m; alignas(128) atomic_t m_buf{0}; // MSB (40 bit): push begin, LSB (24 bis): push size alignas(128) atomic_t m_out{0}; // Amount of bytes written to file @@ -183,7 +183,7 @@ namespace logs channel SPU("SPU"); // Channel registry mutex - semaphore<> g_mutex; + shared_mutex g_mutex; // Must be set to true in main() atomic_t g_init{false}; diff --git a/Utilities/asm.h b/Utilities/asm.h index 835b70bb60..f1c81e37bb 100644 --- a/Utilities/asm.h +++ b/Utilities/asm.h @@ -44,6 +44,20 @@ namespace utils #endif } + inline u8 popcnt16(u16 arg) + { + const u32 a1 = arg & 0x5555; + const u32 a2 = (arg >> 1) & 0x5555; + const u32 a3 = a1 + a2; + const u32 b1 = a3 & 0x3333; + const u32 b2 = (a3 >> 2) & 0x3333; + const u32 b3 = b1 + b2; + const u32 c1 = b3 & 0x0f0f; + const u32 c2 = (b3 >> 4) & 0x0f0f; + const u32 c3 = c1 + c2; + return static_cast(c3 + (c3 >> 8)); + } + // Rotate helpers #if defined(__GNUG__) diff --git a/Utilities/cond.cpp b/Utilities/cond.cpp index a502210ff0..f15d30cdac 100644 --- a/Utilities/cond.cpp +++ b/Utilities/cond.cpp @@ -9,110 +9,47 @@ bool cond_variable::imp_wait(u32 _old, u64 _timeout) noexcept { - verify(HERE), _old != -1; // Very unlikely: it requires 2^32 distinct threads to wait simultaneously - const bool is_inf = _timeout > max_timeout; + verify("cond_variable overflow" HERE), (_old & 0xffff) == 0; // Very unlikely: it requires 65535 distinct threads to wait simultaneously + + return balanced_wait_until(m_value, _timeout, [&](u32& value, auto... ret) -> int + { + if (value >> 16) + { + // Success + value -= 0x10001; + return +1; + } + + if constexpr (sizeof...(ret)) + { + // Retire + value -= 1; + return -1; + } + + return 0; + }); #ifdef _WIN32 - LARGE_INTEGER timeout; - timeout.QuadPart = _timeout * -10; - - if (HRESULT rc = _timeout ? NtWaitForKeyedEvent(nullptr, &m_value, false, is_inf ? nullptr : &timeout) : WAIT_TIMEOUT) + if (_old >= 0x10000 && !OptWaitOnAddress && m_value) { - verify(HERE), rc == WAIT_TIMEOUT; - - // Retire - while (!m_value.try_dec()) - { - timeout.QuadPart = 0; - - if (HRESULT rc2 = NtWaitForKeyedEvent(nullptr, &m_value, false, &timeout)) - { - verify(HERE), rc2 == WAIT_TIMEOUT; - SwitchToThread(); - continue; - } - - return true; - } - - return false; - } - - return true; -#else - timespec timeout; - timeout.tv_sec = _timeout / 1000000; - timeout.tv_nsec = (_timeout % 1000000) * 1000; - - for (u32 value = _old + 1;; value = m_value) - { - const int err = futex(&m_value, FUTEX_WAIT_PRIVATE, value, is_inf ? nullptr : &timeout) == 0 - ? 0 - : errno; - - // Normal or timeout wakeup - if (!err || (!is_inf && err == ETIMEDOUT)) - { - // Cleanup (remove waiter) - verify(HERE), m_value--; - return !err; - } - - // Not a wakeup - verify(HERE), err == EAGAIN; + // Workaround possibly stolen signal + imp_wake(1); } #endif } void cond_variable::imp_wake(u32 _count) noexcept { -#ifdef _WIN32 - // Try to subtract required amount of waiters - const u32 count = m_value.atomic_op([=](u32& value) + balanced_awaken(m_value, m_value.atomic_op([&](u32& value) -> u32 { - if (value > _count) - { - value -= _count; - return _count; - } + // Subtract already signaled number from total amount of waiters + const u32 can_sig = (value & 0xffff) - (value >> 16); + const u32 num_sig = std::min(can_sig, _count); - return std::exchange(value, 0); - }); - - for (u32 i = count; i > 0; i--) - { - NtReleaseKeyedEvent(nullptr, &m_value, false, nullptr); - } -#else - for (u32 i = _count; i > 0; std::this_thread::yield()) - { - const u32 value = m_value; - - // Constrain remaining amount with imaginary waiter count - if (i > value) - { - i = value; - } - - if (!value || i == 0) - { - // Nothing to do - return; - } - - if (const int res = futex(&m_value, FUTEX_WAKE_PRIVATE, i > INT_MAX ? INT_MAX : i)) - { - verify(HERE), res >= 0 && (u32)res <= i; - i -= res; - } - - if (!m_value || i == 0) - { - // Escape - return; - } - } -#endif + value += num_sig << 16; + return num_sig; + })); } bool notifier::imp_try_lock(u32 count) @@ -209,62 +146,29 @@ bool notifier::wait(u64 usec_timeout) return res; } -bool cond_one::imp_wait(u32 _old, u64 _timeout) noexcept +bool cond_one::imp_wait(u64 _timeout) noexcept { - verify(HERE), _old == c_lock; + // State transition: c_sig -> c_lock \ c_lock -> c_wait + const u32 _old = m_value.fetch_sub(1); + if (LIKELY(_old == c_sig)) + return true; - const bool is_inf = _timeout > cond_variable::max_timeout; - -#ifdef _WIN32 - LARGE_INTEGER timeout; - timeout.QuadPart = _timeout * -10; - - if (HRESULT rc = _timeout ? NtWaitForKeyedEvent(nullptr, &m_value, false, is_inf ? nullptr : &timeout) : WAIT_TIMEOUT) + return balanced_wait_until(m_value, _timeout, [&](u32& value, auto... ret) -> int { - verify(HERE), rc == WAIT_TIMEOUT; - - // Retire - const bool signaled = m_value.exchange(c_lock) == c_sig; - while (signaled) + if (value == c_sig) { - timeout.QuadPart = 0; - - if (HRESULT rc2 = NtWaitForKeyedEvent(nullptr, &m_value, false, &timeout)) - { - verify(HERE), rc2 == WAIT_TIMEOUT; - SwitchToThread(); - continue; - } - - return true; + value = c_lock; + return +1; } - return false; - } -#else - timespec timeout; - timeout.tv_sec = _timeout / 1000000; - timeout.tv_nsec = (_timeout % 1000000) * 1000; - - for (u32 value = _old - 1; value != c_sig; value = m_value) - { - const int err = futex(&m_value, FUTEX_WAIT_PRIVATE, value, is_inf ? nullptr : &timeout) == 0 - ? 0 - : errno; - - // Normal or timeout wakeup - if (!err || (!is_inf && err == ETIMEDOUT)) + if constexpr (sizeof...(ret)) { - return m_value.exchange(c_lock) == c_sig; + value = c_lock; + return -1; } - // Not a wakeup - verify(HERE), err == EAGAIN; - } -#endif - - verify(HERE), m_value.exchange(c_lock) == c_sig; - return true; + return 0; + }); } void cond_one::imp_notify() noexcept @@ -287,79 +191,54 @@ void cond_one::imp_notify() noexcept return; } -#ifdef _WIN32 - NtReleaseKeyedEvent(nullptr, &m_value, false, nullptr); -#else - futex(&m_value, FUTEX_WAKE_PRIVATE, 1); -#endif + balanced_awaken(m_value, 1); } -bool cond_x16::imp_wait(u32 _new, u32 slot, u64 _timeout) noexcept +bool cond_x16::imp_wait(u32 slot, u64 _timeout) noexcept { const u32 wait_bit = c_wait << slot; const u32 lock_bit = c_lock << slot; - const bool is_inf = _timeout > cond_variable::max_timeout; - -#ifdef _WIN32 - LARGE_INTEGER timeout; - timeout.QuadPart = _timeout * -10; - - if (HRESULT rc = _timeout ? NtWaitForKeyedEvent(nullptr, &m_cvx16, false, is_inf ? nullptr : &timeout) : WAIT_TIMEOUT) + // Change state from c_lock to c_wait + const u32 old_ = m_cvx16.fetch_op([=](u32& cvx16) { - verify(HERE), rc == WAIT_TIMEOUT; - - // Retire - const bool signaled = this->retire(slot); - - while (signaled) + if (cvx16 & wait_bit) { - timeout.QuadPart = 0; + // c_sig -> c_lock + cvx16 &= ~wait_bit; + } + else + { + cvx16 |= wait_bit; + cvx16 &= ~lock_bit; + } + }); - if (HRESULT rc2 = NtWaitForKeyedEvent(nullptr, &m_cvx16, false, &timeout)) - { - verify(HERE), rc2 == WAIT_TIMEOUT; - SwitchToThread(); - continue; - } + if (old_ & wait_bit) + { + // Already signaled, return without waiting + return true; + } - return true; + return balanced_wait_until(m_cvx16, _timeout, [&](u32& cvx16, auto... ret) -> int + { + if (cvx16 & lock_bit) + { + // c_sig -> c_lock + cvx16 &= ~wait_bit; + return +1; } - return false; - } - - if (!this->retire(slot)) - { - // Stolen notification: restore balance - NtReleaseKeyedEvent(nullptr, &m_cvx16, false, nullptr); - } -#else - timespec timeout; - timeout.tv_sec = _timeout / 1000000; - timeout.tv_nsec = (_timeout % 1000000) * 1000; - - for (u32 value = _new; ((value >> slot) & c_sig) != c_sig; value = m_cvx16) - { - const int err = futex(&m_cvx16, FUTEX_WAIT_PRIVATE, value, is_inf ? nullptr : &timeout) == 0 - ? 0 - : errno; - - // Normal or timeout wakeup - if (!err || (!is_inf && err == ETIMEDOUT)) + if constexpr (sizeof...(ret)) { - return this->retire(slot); + // Retire + cvx16 |= lock_bit; + cvx16 &= ~wait_bit; + return -1; } - // Not a wakeup - verify(HERE), err == EAGAIN; - } - - // Convert c_sig to c_lock - m_cvx16 &= ~wait_bit; -#endif - - return true; + return 0; + }); } void cond_x16::imp_notify() noexcept @@ -386,13 +265,5 @@ void cond_x16::imp_notify() noexcept return; } -#ifdef _WIN32 - for (u32 i = 0; i < 16; i++) - { - if ((wait_mask >> i) & 1) - NtReleaseKeyedEvent(nullptr, &m_cvx16, false, nullptr); - } -#else - futex(&m_cvx16, FUTEX_WAKE_PRIVATE, INT_MAX); -#endif + balanced_awaken(m_cvx16, utils::popcnt16(wait_mask)); } diff --git a/Utilities/cond.h b/Utilities/cond.h index b17442dc1a..6e43a95922 100644 --- a/Utilities/cond.h +++ b/Utilities/cond.h @@ -57,7 +57,7 @@ public: { if (m_value) { - imp_wake(-1); + imp_wake(65535); } } @@ -140,7 +140,7 @@ class cond_one atomic_t m_value{0}; - bool imp_wait(u32 _old, u64 _timeout) noexcept; + bool imp_wait(u64 _timeout) noexcept; void imp_notify() noexcept; public: @@ -162,13 +162,7 @@ public: { AUDIT(lock.owns_lock()); AUDIT(lock.mutex() == this); - - // State transition: c_sig -> c_lock, c_lock -> c_wait - const u32 _old = m_value.fetch_sub(1); - if (LIKELY(_old == c_sig)) - return true; - - return imp_wait(_old, usec_timeout); + return imp_wait(usec_timeout); } void notify() noexcept @@ -244,28 +238,9 @@ class cond_x16 } }; - bool imp_wait(u32 _new, u32 slot, u64 _timeout) noexcept; + bool imp_wait(u32 slot, u64 _timeout) noexcept; void imp_notify() noexcept; - bool retire(u32 slot) noexcept - { - const u32 wait_bit = c_wait << slot; - const u32 lock_bit = c_lock << slot; - - return m_cvx16.atomic_op([=](u32& cvx16) - { - if (cvx16 & lock_bit) - { - cvx16 &= ~wait_bit; - return true; - } - - cvx16 |= lock_bit; - cvx16 &= ~wait_bit; - return false; - }); - } - public: constexpr cond_x16() = default; @@ -277,33 +252,7 @@ public: bool wait(lock_x16 const& lock, u64 usec_timeout = -1) noexcept { AUDIT(lock.m_this == this); - - const u32 wait_bit = c_wait << lock.m_slot; - const u32 lock_bit = c_lock << lock.m_slot; - - // Change state from c_lock to c_wait - const u32 new_ = m_cvx16.atomic_op([=](u32& cvx16) - { - if (cvx16 & wait_bit) - { - cvx16 &= ~wait_bit; - } - else - { - cvx16 |= wait_bit; - cvx16 &= ~lock_bit; - } - - return cvx16; - }); - - if (new_ & lock_bit) - { - // Already signaled, return without waiting - return true; - } - - return imp_wait(new_, lock.m_slot, usec_timeout); + return imp_wait(lock.m_slot, usec_timeout); } void notify_all() noexcept diff --git a/Utilities/mutex.cpp b/Utilities/mutex.cpp index 59b50d87bf..3ac8a1688b 100644 --- a/Utilities/mutex.cpp +++ b/Utilities/mutex.cpp @@ -44,42 +44,24 @@ void shared_mutex::imp_unlock_shared(u32 old) void shared_mutex::imp_wait() { -#ifdef _WIN32 - NtWaitForKeyedEvent(nullptr, &m_value, false, nullptr); -#else - while (true) + while (!balanced_wait_until(m_value, -1, [&](u32& value, auto...) { - // Load new value, try to acquire c_sig - auto [value, ok] = m_value.fetch_op([](u32& value) + if (value >= c_sig) { - if (value >= c_sig) - { - value -= c_sig; - return true; - } - - return false; - }); - - if (ok) - { - return; + value -= c_sig; + return true; } - futex(&m_value, FUTEX_WAIT_BITSET_PRIVATE, value, nullptr, c_sig); + return false; + })) + { } -#endif } void shared_mutex::imp_signal() { -#ifdef _WIN32 - NtReleaseKeyedEvent(nullptr, &m_value, false, nullptr); -#else m_value += c_sig; - futex(&m_value, FUTEX_WAKE_BITSET_PRIVATE, 1, nullptr, c_sig); - //futex(&m_value, FUTEX_WAKE_BITSET_PRIVATE, c_one, nullptr, c_sig - 1); -#endif + balanced_awaken(m_value, 1); } void shared_mutex::imp_lock(u32 val) @@ -166,29 +148,6 @@ void shared_mutex::imp_lock_unlock() busy_wait(1500); } -#ifndef _WIN32 - while (false) - { - const u32 val = m_value; - - if (val % c_one == 0 && (val / c_one < _max || val >= c_sig)) - { - return; - } - - if (val <= c_one) - { - // Can't expect a signal - break; - } - - _max = val / c_one; - - // Monitor all bits except c_sig - futex(&m_value, FUTEX_WAIT_BITSET_PRIVATE, val, nullptr, c_sig - 1); - } -#endif - // Lock and unlock if (!m_value.fetch_add(c_one)) { diff --git a/Utilities/sync.h b/Utilities/sync.h index d82aa833ee..6f9c1eeb71 100644 --- a/Utilities/sync.h +++ b/Utilities/sync.h @@ -72,12 +72,12 @@ inline int futex(volatile void* uaddr, int futex_op, uint val, const timespec* t switch (futex_op) { - case FUTEX_WAIT: + case FUTEX_WAIT_PRIVATE: { mask = -1; [[fallthrough]]; } - case FUTEX_WAIT_BITSET: + case FUTEX_WAIT_BITSET_PRIVATE: { if (*reinterpret_cast(uaddr) != val) { @@ -115,12 +115,12 @@ inline int futex(volatile void* uaddr, int futex_op, uint val, const timespec* t return res; } - case FUTEX_WAKE: + case FUTEX_WAKE_PRIVATE: { mask = -1; [[fallthrough]]; } - case FUTEX_WAKE_BITSET: + case FUTEX_WAKE_BITSET_PRIVATE: { int res = 0; @@ -149,3 +149,144 @@ inline int futex(volatile void* uaddr, int futex_op, uint val, const timespec* t return g_futex(uaddr, futex_op, val, timeout, mask); #endif } + +template +bool balanced_wait_until(atomic_t& var, u64 usec_timeout, Pred&& pred) +{ + static_assert(sizeof(T) == 4); + + const bool is_inf = usec_timeout > u64{UINT32_MAX / 1000} * 1000000; + + // Optional second argument indicates that the predicate should try to retire + auto test_pred = [&](T& _new, auto... args) + { + T old = var.load(); + + while (true) + { + _new = old; + + // Zero indicates failure without modifying the value + // Negative indicates failure but modifies the value + auto ret = std::invoke(std::forward(pred), _new, args...); + + if (LIKELY(!ret || var.compare_exchange(old, _new))) + { + return ret > 0; + } + } + }; + + T value; + +#ifdef _WIN32 + if (OptWaitOnAddress) + { + while (!test_pred(value)) + { + if (OptWaitOnAddress(&var, &value, sizeof(u32), is_inf ? INFINITE : usec_timeout / 1000)) + { + if (!test_pred(value) && !test_pred(value, nullptr)) + { + return false; + } + + break; + } + + if (GetLastError() == ERROR_TIMEOUT) + { + // Retire + return test_pred(value, nullptr); + } + } + + return true; + } + + LARGE_INTEGER timeout; + timeout.QuadPart = usec_timeout * -10; + + if (!usec_timeout || NtWaitForKeyedEvent(nullptr, &var, false, is_inf ? nullptr : &timeout)) + { + // Timed out: retire + if (!test_pred(value, nullptr)) + { + return false; + } + + // Signaled in the last moment: restore balance + NtWaitForKeyedEvent(nullptr, &var, false, nullptr); + return true; + } + + if (!test_pred(value) && !test_pred(value, nullptr)) + { + // Stolen notification: restore balance + NtReleaseKeyedEvent(nullptr, &var, false, nullptr); + return false; + } + + return true; +#else + struct timespec timeout; + timeout.tv_sec = usec_timeout / 1000000; + timeout.tv_nsec = (usec_timeout % 1000000) * 1000; + + while (!test_pred(value)) + { + if (futex(&var, FUTEX_WAIT_PRIVATE, static_cast(value), is_inf ? nullptr : &timeout) == 0) + { + if (!test_pred(value) && !test_pred(value, nullptr)) + { + return false; + } + + break; + } + + switch (errno) + { + case EAGAIN: break; + case ETIMEDOUT: return test_pred(value, nullptr); + default: verify("Unknown futex error" HERE), 0; + } + } + + return true; +#endif +} + +template +void balanced_awaken(atomic_t& var, u32 weight) +{ + static_assert(sizeof(T) == 4); + +#ifdef _WIN32 + if (OptWaitOnAddress) + { + if (weight > 1) + { + OptWakeByAddressAll(&var); + } + else if (weight == 1) + { + OptWakeByAddressSingle(&var); + } + + return; + } + + for (u32 i = 0; i < weight; i++) + { + NtReleaseKeyedEvent(nullptr, &var, false, nullptr); + } +#else + if (weight) + { + futex(&var, FUTEX_WAKE_PRIVATE, std::min(INT_MAX, weight)); + } + + return; +#endif +} diff --git a/rpcs3/Emu/Cell/Modules/cellCamera.h b/rpcs3/Emu/Cell/Modules/cellCamera.h index 9af50a5707..5008dd279d 100644 --- a/rpcs3/Emu/Cell/Modules/cellCamera.h +++ b/rpcs3/Emu/Cell/Modules/cellCamera.h @@ -2,7 +2,6 @@ #include "Utilities/Timer.h" #include "Emu/Cell/lv2/sys_memory.h" -#include "Utilities/sema.h" #include "Utilities/Thread.h" #include diff --git a/rpcs3/Emu/Cell/Modules/cellMouse.cpp b/rpcs3/Emu/Cell/Modules/cellMouse.cpp index 1ece2e3446..141118bfe5 100644 --- a/rpcs3/Emu/Cell/Modules/cellMouse.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMouse.cpp @@ -5,8 +5,6 @@ #include "Emu/Io/MouseHandler.h" -#include "Utilities/sema.h" - #include "cellMouse.h" extern logs::channel sys_io; diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index d16c11abc1..dbe8178e39 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -1383,7 +1383,7 @@ extern void ppu_initialize(const ppu_module& info) std::shared_ptr jit; // Compiler mutex (global) - static semaphore<> jmutex; + static shared_mutex jmutex; // Initialize global semaphore with the max number of threads u32 max_threads = static_cast(g_cfg.core.llvm_threads); diff --git a/rpcs3/Emu/Cell/lv2/sys_event.h b/rpcs3/Emu/Cell/lv2/sys_event.h index 6bbe7b2fb9..2384c41133 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.h +++ b/rpcs3/Emu/Cell/lv2/sys_event.h @@ -83,7 +83,7 @@ struct lv2_event_queue final : public lv2_obj const u64 key; const s32 size; - semaphore<> mutex; + shared_mutex mutex; std::deque events; std::deque sq; diff --git a/rpcs3/Emu/Cell/lv2/sys_event_flag.h b/rpcs3/Emu/Cell/lv2/sys_event_flag.h index a7541c0319..ebcc3a839a 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event_flag.h +++ b/rpcs3/Emu/Cell/lv2/sys_event_flag.h @@ -40,7 +40,7 @@ struct lv2_event_flag final : lv2_obj const s32 type; const u64 name; - semaphore<> mutex; + shared_mutex mutex; atomic_t waiters{0}; atomic_t pattern; std::deque sq; diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.h b/rpcs3/Emu/Cell/lv2/sys_lwcond.h index a8fe686f27..db9c16fd10 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.h +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.h @@ -27,7 +27,7 @@ struct lv2_lwcond final : lv2_obj const u32 lwid; vm::ptr control; - semaphore<> mutex; + shared_mutex mutex; atomic_t waiters{0}; std::deque sq; diff --git a/rpcs3/Emu/Cell/lv2/sys_lwmutex.h b/rpcs3/Emu/Cell/lv2/sys_lwmutex.h index e3d66f50ed..d0c41f6416 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwmutex.h +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.h @@ -57,7 +57,7 @@ struct lv2_lwmutex final : lv2_obj const vm::ptr control; const u64 name; - semaphore<> mutex; + shared_mutex mutex; atomic_t signaled{0}; std::deque sq; diff --git a/rpcs3/Emu/Cell/lv2/sys_mmapper.h b/rpcs3/Emu/Cell/lv2/sys_mmapper.h index 2ce67b8a3b..65021cddb0 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mmapper.h +++ b/rpcs3/Emu/Cell/lv2/sys_mmapper.h @@ -56,7 +56,7 @@ struct page_fault_event struct page_fault_event_entries { std::vector events; - semaphore<> pf_mutex; + shared_mutex pf_mutex; }; // SysCalls diff --git a/rpcs3/Emu/Cell/lv2/sys_mutex.h b/rpcs3/Emu/Cell/lv2/sys_mutex.h index 28ce95d430..2d60d31f7a 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mutex.h +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.h @@ -31,7 +31,7 @@ struct lv2_mutex final : lv2_obj const u64 name; const s32 flags; - semaphore<> mutex; + shared_mutex mutex; atomic_t owner{0}; // Owner Thread ID atomic_t lock_count{0}; // Recursive Locks atomic_t cond_count{0}; // Condition Variables diff --git a/rpcs3/Emu/Cell/lv2/sys_net.cpp b/rpcs3/Emu/Cell/lv2/sys_net.cpp index 10076edd8e..427e752992 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net.cpp @@ -30,7 +30,7 @@ LOG_CHANNEL(sys_net); static std::vector s_to_awake; -static semaphore<> s_nw_mutex; +static shared_mutex s_nw_mutex; extern u64 get_system_time(); diff --git a/rpcs3/Emu/Cell/lv2/sys_net.h b/rpcs3/Emu/Cell/lv2/sys_net.h index bc02c27734..191677c513 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net.h +++ b/rpcs3/Emu/Cell/lv2/sys_net.h @@ -1,7 +1,7 @@ #pragma once #include "Utilities/bit_set.h" -#include "Utilities/sema.h" +#include "Utilities/mutex.h" #include #include @@ -324,7 +324,7 @@ struct lv2_socket final lv2_socket(socket_type s); ~lv2_socket(); - semaphore<> mutex; + shared_mutex mutex; #ifdef _WIN32 // Remember events (WSAEnumNetworkEvents) diff --git a/rpcs3/Emu/Cell/lv2/sys_rwlock.h b/rpcs3/Emu/Cell/lv2/sys_rwlock.h index de4759bb83..86b8772858 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rwlock.h +++ b/rpcs3/Emu/Cell/lv2/sys_rwlock.h @@ -27,7 +27,7 @@ struct lv2_rwlock final : lv2_obj const u64 name; const s32 flags; - semaphore<> mutex; + shared_mutex mutex; atomic_t owner{0}; std::deque rq; std::deque wq; diff --git a/rpcs3/Emu/Cell/lv2/sys_semaphore.h b/rpcs3/Emu/Cell/lv2/sys_semaphore.h index 580ef572b9..3c3862fbb2 100644 --- a/rpcs3/Emu/Cell/lv2/sys_semaphore.h +++ b/rpcs3/Emu/Cell/lv2/sys_semaphore.h @@ -28,7 +28,7 @@ struct lv2_sema final : lv2_obj const s32 flags; const s32 max; - semaphore<> mutex; + shared_mutex mutex; atomic_t val; std::deque sq; diff --git a/rpcs3/Emu/Cell/lv2/sys_sync.h b/rpcs3/Emu/Cell/lv2/sys_sync.h index f9f53ec5fb..429b1c74ed 100644 --- a/rpcs3/Emu/Cell/lv2/sys_sync.h +++ b/rpcs3/Emu/Cell/lv2/sys_sync.h @@ -215,7 +215,7 @@ struct lv2_obj private: // Scheduler mutex - static semaphore<> g_mutex; + static shared_mutex g_mutex; // Scheduler queue for active PPU threads static std::deque g_ppu; diff --git a/rpcs3/Emu/Cell/lv2/sys_timer.h b/rpcs3/Emu/Cell/lv2/sys_timer.h index b24a4d16ae..a13ba6a0a6 100644 --- a/rpcs3/Emu/Cell/lv2/sys_timer.h +++ b/rpcs3/Emu/Cell/lv2/sys_timer.h @@ -24,7 +24,7 @@ struct lv2_timer_context : lv2_obj void operator()(); void on_abort(); - semaphore<> mutex; + shared_mutex mutex; atomic_t state{SYS_TIMER_STATE_STOP}; std::weak_ptr port; diff --git a/rpcs3/Emu/Io/MouseHandler.h b/rpcs3/Emu/Io/MouseHandler.h index c4437bb338..77ea3a7824 100644 --- a/rpcs3/Emu/Io/MouseHandler.h +++ b/rpcs3/Emu/Io/MouseHandler.h @@ -1,7 +1,7 @@ #pragma once #include -#include "Utilities/sema.h" +#include "Utilities/mutex.h" // TODO: HLE info (constants, structs, etc.) should not be available here @@ -145,7 +145,7 @@ protected: } public: - semaphore<> mutex; + shared_mutex mutex; virtual void Init(const u32 max_connect) = 0; virtual ~MouseHandlerBase() = default; diff --git a/rpcs3/rpcs3qt/log_frame.cpp b/rpcs3/rpcs3qt/log_frame.cpp index afa81290dc..c894d62d4d 100644 --- a/rpcs3/rpcs3qt/log_frame.cpp +++ b/rpcs3/rpcs3qt/log_frame.cpp @@ -13,7 +13,7 @@ #include #include -#include "Utilities/sema.h" +#include "Utilities/mutex.h" extern fs::file g_tty; extern atomic_t g_tty_size;