diff --git a/Utilities/lockless.h b/Utilities/lockless.h index 85ab4703d6..f6d4857e78 100644 --- a/Utilities/lockless.h +++ b/Utilities/lockless.h @@ -307,14 +307,25 @@ public: delete m_head.load(); } - void wait() noexcept + template + void wait(std::nullptr_t null = nullptr) noexcept { if (m_head == nullptr) { - m_head.wait(nullptr); + m_head.template wait(nullptr); } } + const volatile void* observe() const noexcept + { + return m_head.load(); + } + + explicit operator bool() const noexcept + { + return m_head != nullptr; + } + template void push(Args&&... args) { @@ -414,6 +425,18 @@ public: } }; +namespace atomic_wait +{ + template + inline __m128i default_mask> = _mm_cvtsi64_si128(-1); + + template + constexpr __m128i get_value(lf_queue&, std::nullptr_t value = nullptr) + { + return _mm_setzero_si128(); + } +} + // Concurrent linked list, elements remain until destroyed. template class lf_bunch final diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 999cdf6408..d01ff98244 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -182,7 +182,7 @@ struct cpu_prof if (threads.empty()) { // Wait for messages if no work (don't waste CPU) - registered.wait(); + atomic_wait::list(registered).wait(); continue; } diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index a69c610094..3f95c029a6 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -8847,6 +8847,11 @@ struct spu_llvm_worker continue; } + if (!prog->second) + { + break; + } + const auto& func = *prog->second; // Get data start @@ -8986,7 +8991,7 @@ struct spu_llvm { // Interrupt profiler thread and put it to sleep static_cast(prof_mutex.reset()); - registered.wait(); + atomic_wait::list(registered).wait(); // TODO continue; } @@ -9017,6 +9022,11 @@ struct spu_llvm // Push the workload (workers.begin() + (worker_index++ % worker_count))->registered.push(reinterpret_cast(_old), &func); } + + for (u32 i = 0; i < worker_count; i++) + { + (workers.begin() + i)->registered.push(0, nullptr); + } } static constexpr auto thread_name = "SPU LLVM"sv; diff --git a/rpcs3/stdafx.cpp b/rpcs3/stdafx.cpp index e40f3479b3..6a4bceaab6 100644 --- a/rpcs3/stdafx.cpp +++ b/rpcs3/stdafx.cpp @@ -8,3 +8,5 @@ CHECK_SIZE_ALIGN(s128, 16, 16); static_assert(be_t(1) + be_t(2) + be_t(3) == 6); static_assert(le_t(1) + le_t(2) + le_t(3) == 6); + +static_assert(sizeof(nullptr) == sizeof(void*));