From b91661ae71adb837666e5a0bf504ca4729a12739 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 9 Sep 2019 00:55:48 +0300 Subject: [PATCH] Remove timeout support from lf_queue::wait Add notify method and use atomic wait --- Utilities/cond.cpp | 32 ----------------------------- Utilities/lockless.h | 28 +++++++++++++------------ rpcs3/Emu/Cell/Modules/cellVdec.cpp | 7 ++++++- 3 files changed, 21 insertions(+), 46 deletions(-) diff --git a/Utilities/cond.cpp b/Utilities/cond.cpp index 8a829cd282..6b1e47c1c5 100644 --- a/Utilities/cond.cpp +++ b/Utilities/cond.cpp @@ -443,35 +443,3 @@ bool shared_cond::notify_all(shared_cond::shared_lock& lock) noexcept balanced_awaken(m_cvx32, utils::popcnt32(wait_mask)); return true; } - -bool lf_queue_base::wait(u64 _timeout) -{ - auto _old = m_head.compare_and_swap(0, 1); - - if (_old) - { - verify("lf_queue concurrent wait" HERE), _old != 1; - return true; - } - - return balanced_wait_until(m_head, _timeout, [](std::uintptr_t& head, auto... ret) -> int - { - if (head != 1) - { - return +1; - } - - if constexpr (sizeof...(ret)) - { - head = 0; - return -1; - } - - return 0; - }); -} - -void lf_queue_base::imp_notify() -{ - balanced_awaken(m_head, 1); -} diff --git a/Utilities/lockless.h b/Utilities/lockless.h index 28831f8e9d..9429b22309 100644 --- a/Utilities/lockless.h +++ b/Utilities/lockless.h @@ -315,12 +315,6 @@ class lf_queue_base { protected: atomic_t m_head = 0; - - void imp_notify(); - -public: - // Wait for new elements pushed, no other thread shall call wait() or pop_all() simultaneously - bool wait(u64 usec_timeout = -1); }; // Linked list-based multi-producer queue (the consumer drains the whole queue at once) @@ -361,20 +355,28 @@ public: delete reinterpret_cast*>(m_head.load()); } + void wait() noexcept + { + while (m_head == 0) + { + m_head.wait(0); + } + } + + void notify() noexcept + { + m_head.notify_one(); + } + template void push(Args&&... args) { auto _old = m_head.load(); - auto* item = new lf_queue_item(_old & 1 ? nullptr : reinterpret_cast*>(_old), std::forward(args)...); + auto* item = new lf_queue_item(reinterpret_cast*>(_old), std::forward(args)...); while (!m_head.compare_exchange(_old, reinterpret_cast(item))) { - item->m_link = _old & 1 ? nullptr : reinterpret_cast*>(_old); - } - - if (_old & 1) - { - lf_queue_base::imp_notify(); + item->m_link = reinterpret_cast*>(_old); } } diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index f333e79303..f68eb8da92 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVdec.cpp @@ -184,7 +184,7 @@ struct vdec_context final { if (!cmds) { - in_cmd.wait(1000); + in_cmd.wait(); continue; } @@ -515,6 +515,7 @@ error_code cellVdecClose(ppu_thread& ppu, u32 handle) lv2_obj::sleep(ppu); vdec->out_max = 0; vdec->in_cmd.push(vdec_close); + vdec->in_cmd.notify(); while (!atomic_storage::load(vdec->ppu_tid)) { @@ -538,6 +539,7 @@ error_code cellVdecStartSeq(u32 handle) } vdec->in_cmd.push(vdec_start_seq); + vdec->in_cmd.notify(); return CELL_OK; } @@ -553,6 +555,7 @@ error_code cellVdecEndSeq(u32 handle) } vdec->in_cmd.push(vdec_cmd{-1}); + vdec->in_cmd.notify(); return CELL_OK; } @@ -574,6 +577,7 @@ error_code cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptrin_cmd.push(vdec_cmd{mode, *auInfo}); + vdec->in_cmd.notify(); return CELL_OK; } @@ -924,6 +928,7 @@ error_code cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frc) // TODO: check frc value vdec->in_cmd.push(frc); + vdec->in_cmd.notify(); return CELL_OK; }