diff --git a/Utilities/lockless.h b/Utilities/lockless.h index 63c2774bc8..5028b398c3 100644 --- a/Utilities/lockless.h +++ b/Utilities/lockless.h @@ -384,7 +384,7 @@ public: template class lf_queue final { -public: +private: struct fat_ptr { u64 ptr{}; @@ -392,7 +392,6 @@ public: u32 reserved{}; }; -private: atomic_t m_head{fat_ptr{}}; lf_queue_item* load(fat_ptr value) const noexcept @@ -439,8 +438,7 @@ public: return *this; } - delete load(m_head); - m_head.release(other.m_head.exchange(fat_ptr{})); + delete load(m_head.exchange(other.m_head.exchange(fat_ptr{}))); return *this; } @@ -453,10 +451,15 @@ public: { if (!operator bool()) { - utils::bless>(&m_head.raw().is_non_null)->wait(0); + get_wait_atomic().wait(0); } } + atomic_t &get_wait_atomic() + { + return *utils::bless>(&m_head.raw().is_non_null); + } + const volatile void* observe() const noexcept { return load(m_head); @@ -491,7 +494,7 @@ public: { if (force || operator bool()) { - utils::bless>(&m_head.raw().is_non_null)->notify_one(); + get_wait_atomic().notify_one(); } } diff --git a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp index ae1d5bd889..d73efc8e84 100644 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -7376,7 +7376,7 @@ struct spu_llvm_worker set_relax_flag = false; } - thread_ctrl::wait_on(utils::bless>(®istered)[1], 0); + thread_ctrl::wait_on(registered.get_wait_atomic(), 0); slice = registered.pop_all(); }()) { @@ -7491,7 +7491,7 @@ struct spu_llvm while (!registered && thread_ctrl::state() != thread_state::aborting) { // Wait for the first SPU block before launching any thread - thread_ctrl::wait_on(utils::bless>(®istered)[1], 0); + thread_ctrl::wait_on(registered.get_wait_atomic(), 0); } if (thread_ctrl::state() == thread_state::aborting) @@ -7594,7 +7594,7 @@ struct spu_llvm // Interrupt profiler thread and put it to sleep static_cast(prof_mutex.reset()); - thread_ctrl::wait_on(utils::bless>(®istered)[1], 0); + thread_ctrl::wait_on(registered.get_wait_atomic(), 0); std::fill(notify_compile.begin(), notify_compile.end(), 0); // Reset notification flags notify_compile_count = 0; compile_pending = 0; diff --git a/rpcs3/util/atomic.hpp b/rpcs3/util/atomic.hpp index 85c8b10482..80d9e34f9d 100644 --- a/rpcs3/util/atomic.hpp +++ b/rpcs3/util/atomic.hpp @@ -207,7 +207,7 @@ namespace atomic_wait static_assert(Index < Max); static_assert(sizeof(var) == sizeof(uptr) * 2); - m_info[Index].data = reinterpret_cast(&var) + offsetof(typename lf_queue::fat_ptr, is_non_null); + m_info[Index].data = std::bit_cast(&var.get_wait_atomic().raw()); m_info[Index].old = 0; } @@ -217,7 +217,7 @@ namespace atomic_wait static_assert(Index < Max); static_assert(sizeof(var) == sizeof(uptr) * 2); - m_info[Index].data = reinterpret_cast(&var) + offsetof(typename stx::atomic_ptr::fat_ptr, is_non_null); + m_info[Index].data = std::bit_cast(&var.get_wait_atomic().raw()); m_info[Index].old = 0; } diff --git a/rpcs3/util/shared_ptr.hpp b/rpcs3/util/shared_ptr.hpp index 375784e7dd..093d90ef7e 100644 --- a/rpcs3/util/shared_ptr.hpp +++ b/rpcs3/util/shared_ptr.hpp @@ -576,7 +576,7 @@ namespace stx template class atomic_ptr { - public: + private: struct fat_ptr { uptr ptr{}; @@ -584,8 +584,6 @@ namespace stx u32 ref_ctr{}; }; - private: - mutable atomic_t m_val{fat_ptr{}}; static shared_counter* d(fat_ptr val) noexcept @@ -1117,19 +1115,24 @@ namespace stx return static_cast(observe()) == r.get(); } + atomic_t &get_wait_atomic() + { + return *utils::bless>(&m_val.raw().is_non_null); + } + void wait(std::nullptr_t, atomic_wait_timeout timeout = atomic_wait_timeout::inf) { - utils::bless>(&m_val.raw().is_non_null)->wait(0, timeout); + get_wait_atomic().wait(0, timeout); } void notify_one() { - utils::bless>(&m_val.raw().is_non_null)->notify_one(); + get_wait_atomic().notify_one(); } void notify_all() { - utils::bless>(&m_val.raw().is_non_null)->notify_all(); + get_wait_atomic().notify_all(); } };