From edc92843a7c95a8204aed17f7e499f924803182a Mon Sep 17 00:00:00 2001 From: Ivan Date: Tue, 24 May 2016 01:59:39 +0300 Subject: [PATCH] Hotfix (#1705) --- Utilities/File.cpp | 2 +- Utilities/sync.h | 17 ++++++--------- rpcs3/Emu/Memory/wait_engine.cpp | 37 ++++++++++++++++++++++---------- rpcs3/Emu/Memory/wait_engine.h | 2 -- rpcs3/Loader/PSF.cpp | 4 ++-- 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/Utilities/File.cpp b/Utilities/File.cpp index 573b251b83..bea4bc905c 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -1169,7 +1169,7 @@ const std::string& fs::get_executable_dir() wchar_t buf[2048]; if (GetModuleFileName(NULL, buf, ::size32(buf)) - 1 >= ::size32(buf) - 1) { - MessageBoxA(0, fmt::format("GetModuleFileName() failed: error %u.", GetLastError()).c_str(), "fs::get_config_dir()", MB_ICONERROR); + MessageBoxA(0, fmt::format("GetModuleFileName() failed: error %u.", GetLastError()).c_str(), "fs::get_executable_dir()", MB_ICONERROR); return dir; // empty } diff --git a/Utilities/sync.h b/Utilities/sync.h index ba91a76e1f..01c5d2e7d6 100644 --- a/Utilities/sync.h +++ b/Utilities/sync.h @@ -38,38 +38,35 @@ namespace util { while (true) { - NtWaitForKeyedEvent(NULL, &key, FALSE, NULL); - u32 read = key.load(); u32 copy = read; - while (pred(read), read != copy) + while (func(read), read != copy) { read = key.compare_and_swap(copy, read); if (copy == read) { - break; + return; } copy = read; } + + NtWaitForKeyedEvent(NULL, &key, FALSE, NULL); } } // Try to wake up a thread. inline bool keyed_post(atomic_t& key, u32 acknowledged_value) { - LARGE_INTEGER zero; - zero.QuadPart = 0; + LARGE_INTEGER timeout; + timeout.QuadPart = -50; - while (UNLIKELY(NtReleaseKeyedEvent(NULL, &key, FALSE, &zero) == WAIT_TIMEOUT)) + while (UNLIKELY(NtReleaseKeyedEvent(NULL, &key, FALSE, &timeout) != ERROR_SUCCESS)) { if (key.load() != acknowledged_value) return false; - - //NtReleaseKeyedEvent(NULL, &key, FALSE, NULL); - //return true; } return true; diff --git a/rpcs3/Emu/Memory/wait_engine.cpp b/rpcs3/Emu/Memory/wait_engine.cpp index ed6530a12e..9c616ec2f4 100644 --- a/rpcs3/Emu/Memory/wait_engine.cpp +++ b/rpcs3/Emu/Memory/wait_engine.cpp @@ -22,13 +22,34 @@ namespace vm this->mask = ~(size - 1); this->thread = thread_ctrl::get_current(); + struct waiter final { - writer_lock lock(s_mutex); - s_waiters.emplace(this); - } + waiter_base* m_ptr; + thread_ctrl* m_thread; + + waiter(waiter_base* ptr) + : m_ptr(ptr) + , m_thread(ptr->thread) + { + // Initialize waiter + writer_lock{s_mutex}, s_waiters.emplace(m_ptr); + + m_thread->lock(); + } + + ~waiter() + { + // Reset thread + atomic_storage::store(m_ptr->thread, nullptr); + m_thread->unlock(); + + // Remove waiter + writer_lock{s_mutex}, s_waiters.erase(m_ptr); + } + }; // Wait until thread == nullptr - thread_lock(), thread_ctrl::wait(WRAP_EXPR(!thread || test())); + waiter{this}, thread_ctrl::wait(WRAP_EXPR(!thread || test())); } bool waiter_base::try_notify() @@ -66,12 +87,6 @@ namespace vm return true; } - waiter_base::~waiter_base() - { - writer_lock lock(s_mutex); - s_waiters.erase(this); - } - void notify_at(u32 addr, u32 size) { reader_lock lock(s_mutex); @@ -111,7 +126,7 @@ namespace vm while (!Emu.IsStopped()) { // Poll waiters periodically (TODO) - while (notify_all() && !Emu.IsPaused()) + while (notify_all() && !Emu.IsPaused() && !Emu.IsStopped()) { thread_ctrl::sleep(50); } diff --git a/rpcs3/Emu/Memory/wait_engine.h b/rpcs3/Emu/Memory/wait_engine.h index e674ca7250..a777c90af4 100644 --- a/rpcs3/Emu/Memory/wait_engine.h +++ b/rpcs3/Emu/Memory/wait_engine.h @@ -17,8 +17,6 @@ namespace vm bool try_notify(); protected: - ~waiter_base(); - virtual bool test() = 0; }; diff --git a/rpcs3/Loader/PSF.cpp b/rpcs3/Loader/PSF.cpp index f5caf5182f..5d7da0130b 100644 --- a/rpcs3/Loader/PSF.cpp +++ b/rpcs3/Loader/PSF.cpp @@ -216,7 +216,7 @@ namespace psf } // Skip padding - stream.seek(header.off_data_table); + stream.trunc(stream.seek(header.off_data_table)); // Save data for (const auto& entry : psf) @@ -241,7 +241,7 @@ namespace psf } stream.write(value); - stream.seek(max - size, fs::seek_cur); // Skip up to max_size + stream.trunc(stream.seek(max - size, fs::seek_cur)); // Skip up to max_size } else {