diff --git a/rpcs3/util/vm.hpp b/rpcs3/util/vm.hpp index c7ee241618..ab8aa20896 100644 --- a/rpcs3/util/vm.hpp +++ b/rpcs3/util/vm.hpp @@ -1,6 +1,7 @@ #pragma once #include "util/types.hpp" +#include "util/atomic.hpp" namespace utils { @@ -52,7 +53,7 @@ namespace utils #endif u32 m_size; u32 m_flags; - void* m_ptr; + atomic_t m_ptr; public: explicit shm(u32 size, u32 flags = 0); @@ -84,7 +85,7 @@ namespace utils // Get memory mapped by map_self() u8* get() const { - return reinterpret_cast(m_ptr); + return static_cast(+m_ptr); } u32 size() const diff --git a/rpcs3/util/vm_native.cpp b/rpcs3/util/vm_native.cpp index 9e273a662a..d174bbf11a 100644 --- a/rpcs3/util/vm_native.cpp +++ b/rpcs3/util/vm_native.cpp @@ -218,7 +218,7 @@ namespace utils shm::shm(u32 size, u32 flags) : m_size(utils::align(size, 0x10000)) , m_flags(flags) - , m_ptr(0) + , m_ptr(nullptr) { #ifdef _WIN32 m_handle = ::CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, m_size, NULL); @@ -362,12 +362,21 @@ namespace utils u8* shm::map_self(protection prot) { - if (!m_ptr) + void* ptr = m_ptr; + + if (!ptr) { - m_ptr = this->map(nullptr, prot); + const auto mapped = this->map(nullptr, prot); + + // Install mapped memory + if (!m_ptr.compare_exchange(ptr, mapped)) + { + // Mapped already, nothing to do. + this->unmap(mapped); + } } - return static_cast(m_ptr); + return static_cast(ptr); } void shm::unmap(void* ptr) const @@ -414,10 +423,9 @@ namespace utils void shm::unmap_self() { - if (m_ptr) + if (auto ptr = m_ptr.exchange(nullptr)) { - this->unmap(m_ptr); - m_ptr = nullptr; + this->unmap(ptr); } } }