diff --git a/src/common/memory_arena.cpp b/src/common/memory_arena.cpp index 0f44d17ce..74e15092a 100644 --- a/src/common/memory_arena.cpp +++ b/src/common/memory_arena.cpp @@ -103,14 +103,37 @@ bool MemoryArena::IsValid() const #endif } +static std::string GetFileMappingName() +{ +#if defined(_WIN32) + const unsigned pid = GetCurrentThreadId(); +#elif defined(__ANDROID__) || defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) + const unsigned pid = static_cast(getpid()); +#else +#error Unknown platform. +#endif + +#ifdef LIBRETRO + // libretro second-instance runahead is insane, and loads a second copy of the module in the same process, which means + // we'd overlap the memory mapping for the "primary" core. Work around this by taking the address of this function, + // which should be unique per instance. + std::string ret(StringUtil::StdStringFromFormat("duckstation_%u_%p", pid, ((void*)&GetFileMappingName))); +#else + std::string ret(StringUtil::StdStringFromFormat("duckstation_%u", pid)); +#endif + + Log_InfoPrintf("File mapping name: %s", ret.c_str()); + return ret; +} + bool MemoryArena::Create(size_t size, bool writable, bool executable) { if (IsValid()) Destroy(); -#if defined(WIN32) - const std::string file_mapping_name = StringUtil::StdStringFromFormat("duckstation_%u", GetCurrentProcessId()); + const std::string file_mapping_name(GetFileMappingName()); +#if defined(_WIN32) const DWORD protect = (writable ? (executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE) : PAGE_READONLY); m_file_handle = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, protect, Truncate32(size >> 32), Truncate32(size), file_mapping_name.c_str()); @@ -121,9 +144,7 @@ bool MemoryArena::Create(size_t size, bool writable, bool executable) } return true; -#elif defined(ANDROID) - const std::string file_mapping_name = - StringUtil::StdStringFromFormat("duckstation_%u", static_cast(getpid())); +#elif defined(__ANDROID__) m_shmem_fd = AshmemCreateFileMapping(file_mapping_name.c_str(), size); if (m_shmem_fd < 0) { @@ -133,8 +154,6 @@ bool MemoryArena::Create(size_t size, bool writable, bool executable) return true; #elif defined(__linux__) - const std::string file_mapping_name = - StringUtil::StdStringFromFormat("duckstation_%u", static_cast(getpid())); m_shmem_fd = shm_open(file_mapping_name.c_str(), O_CREAT | O_EXCL | (writable ? O_RDWR : O_RDONLY), 0600); if (m_shmem_fd < 0) { @@ -155,8 +174,6 @@ bool MemoryArena::Create(size_t size, bool writable, bool executable) return true; #elif defined(__APPLE__) || defined(__FreeBSD__) #if defined(__APPLE__) - const std::string file_mapping_name = - StringUtil::StdStringFromFormat("duckstation_%u", static_cast(getpid())); m_shmem_fd = shm_open(file_mapping_name.c_str(), O_CREAT | O_EXCL | (writable ? O_RDWR : O_RDONLY), 0600); #else m_shmem_fd = shm_open(SHM_ANON, O_CREAT | O_EXCL | (writable ? O_RDWR : O_RDONLY), 0600);