From fb7ccbd7b4d6ceaa4d39e2afff16c4176c5c5c64 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 24 Jul 2017 21:47:27 +0300 Subject: [PATCH] vulkan: Workaround to avoid lockup due to double fault - TODO: Ensure no page faults occur within a page-fault handler! --- rpcs3/Emu/RSX/VK/VKTextureCache.h | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 92f35bf206..14ac857ec6 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -315,6 +315,7 @@ namespace vk }; private: + std::atomic_bool in_access_violation_handler = { false }; shared_mutex m_cache_mutex; std::unordered_map m_cache; @@ -766,7 +767,11 @@ namespace vk std::pair trampled_range = std::make_pair(0xffffffff, 0x0); std::unordered_map processed_ranges; - reader_lock lock(m_cache_mutex); + const bool _false = false; + const bool acquire_lock = in_access_violation_handler.compare_exchange_weak(const_cast(_false), true); + + if (acquire_lock) + m_cache_mutex.lock_shared(); for (auto It = m_cache.begin(); It != m_cache.end(); It++) { @@ -829,6 +834,12 @@ namespace vk processed_ranges[base] = true; } + if (acquire_lock) + { + in_access_violation_handler = false; + m_cache_mutex.unlock_shared(); + } + return response; } @@ -847,7 +858,11 @@ namespace vk std::pair trampled_range = std::make_pair(0xffffffff, 0x0); std::unordered_map processed_ranges; - reader_lock lock(m_cache_mutex); + const bool _false = false; + const bool acquire_lock = in_access_violation_handler.compare_exchange_weak(const_cast(_false), true); + + if (acquire_lock) + m_cache_mutex.lock_shared(); for (auto It = m_cache.begin(); It != m_cache.end(); It++) { @@ -889,9 +904,6 @@ namespace vk range_reset = true; } - // Upgrade to writer lock - lock.upgrade(); - tex.set_dirty(true); tex.unprotect(); @@ -909,6 +921,12 @@ namespace vk processed_ranges[base] = true; } + if (acquire_lock) + { + in_access_violation_handler = false; + m_cache_mutex.unlock_shared(); + } + return response; }