From eca7339a67e38f70ee9992f061ff81bfee220832 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 26 Jun 2014 01:59:23 +0400 Subject: [PATCH] Some freezing fixed --- Utilities/SSemaphore.cpp | 41 ++++++++++++++--------- Utilities/SSemaphore.h | 3 +- rpcs3/Emu/GS/RSXThread.cpp | 5 +++ rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 4 ++- rpcs3/Emu/SysCalls/Modules/cellResc.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp | 3 +- 6 files changed, 38 insertions(+), 20 deletions(-) diff --git a/Utilities/SSemaphore.cpp b/Utilities/SSemaphore.cpp index ec23211dd6..47e9c76079 100644 --- a/Utilities/SSemaphore.cpp +++ b/Utilities/SSemaphore.cpp @@ -6,6 +6,11 @@ void SSemaphore::wait() u32 order; { std::lock_guard lock(m_mutex); + if (m_count && m_out_order == m_in_order) + { + m_count--; + return; + } order = m_in_order++; } @@ -17,21 +22,23 @@ void SSemaphore::wait() { return; } - - m_cond.wait_for(cv_lock, std::chrono::milliseconds(1)); - std::lock_guard lock(m_mutex); - if (m_count) + m_cond.wait_for(cv_lock, std::chrono::milliseconds(1)); + { - if (m_out_order == order) + std::lock_guard lock(m_mutex); + if (m_count) { - m_count--; - m_out_order++; - return; - } - else - { - m_cond.notify_one(); + if (m_out_order == order) + { + m_count--; + m_out_order++; + return; + } + else + { + m_cond.notify_one(); + } } } } @@ -41,7 +48,6 @@ bool SSemaphore::try_wait() { std::lock_guard lock(m_mutex); - // TODO: ordering? if (m_count && m_in_order == m_out_order) { m_count--; @@ -57,18 +63,21 @@ void SSemaphore::post() { std::lock_guard lock(m_mutex); - if (m_count >= m_max) + if (m_count < m_max) + { + m_count++; + } + else { return; } - m_count++; m_cond.notify_one(); } bool SSemaphore::post_and_wait() { - // TODO: ??? + // TODO: merge these functions? Probably has a race condition. if (try_wait()) return false; post(); diff --git a/Utilities/SSemaphore.h b/Utilities/SSemaphore.h index 890b445d91..2e61262959 100644 --- a/Utilities/SSemaphore.h +++ b/Utilities/SSemaphore.h @@ -6,7 +6,8 @@ class SSemaphore u32 m_count; u32 m_in_order; u32 m_out_order; - std::mutex m_mutex, m_cv_mutex; + std::mutex m_cv_mutex; + std::mutex m_mutex; std::condition_variable m_cond; public: diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index 268eb8cf1d..a8b2d853e4 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -1882,8 +1882,13 @@ void RSXThread::Task() inc=1; u32 put, get; + // this code produces only mov + bswap: se_t::func(put, std::atomic_load((volatile std::atomic*)((u8*)m_ctrl + offsetof(CellGcmControl, put)))); se_t::func(get, std::atomic_load((volatile std::atomic*)((u8*)m_ctrl + offsetof(CellGcmControl, get)))); + /* + se_t::func(put, InterlockedCompareExchange((volatile unsigned long*)((u8*)m_ctrl + offsetof(CellGcmControl, put)), 0, 0)); + se_t::func(get, InterlockedCompareExchange((volatile unsigned long*)((u8*)m_ctrl + offsetof(CellGcmControl, get)), 0, 0)); + */ if(put == get || !Emu.IsRunning()) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index ee394c5254..2ecab1dab9 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -471,7 +471,7 @@ int cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id) return CELL_GCM_ERROR_FAILURE; } - GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); // could freeze on exit + GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); u32 current = ctxt->current; u32 end = ctxt->end; @@ -488,6 +488,8 @@ int cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id) if(res > 0) Memory.Copy(ctxt->begin, ctxt->current - res, res); ctxt->current = ctxt->begin + res; + + //InterlockedExchange64((volatile long long*)((u8*)&ctrl + offsetof(CellGcmControl, put)), (u64)(u32)re(res)); ctrl.put = res; ctrl.get = 0; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index aaa1a464f8..7ba35d2e92 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -802,7 +802,7 @@ int cellRescSetConvertAndFlip(mem_ptr_t cntxt, s32 idx) int cellRescSetWaitFlip() { cellResc->Log("cellRescSetWaitFlip()"); - GSLockCurrent lock(GS_LOCK_WAIT_FLIP); // could stall on exit + GSLockCurrent lock(GS_LOCK_WAIT_FLIP); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp b/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp index 53767cdb94..c81b3e9e45 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp @@ -13,7 +13,7 @@ extern gcmInfo gcm_info; int cellGcmCallback(u32 context_addr, u32 count) { - GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); // could freeze on exit + GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); CellGcmContextData& ctx = (CellGcmContextData&)Memory[context_addr]; CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr]; @@ -24,6 +24,7 @@ int cellGcmCallback(u32 context_addr, u32 count) ctx.current = ctx.begin + res; + //InterlockedExchange64((volatile long long*)((u8*)&ctrl + offsetof(CellGcmControl, put)), (u64)(u32)re(res)); ctrl.put = res; ctrl.get = 0;