MemoryArena: Use module-unique shared memory name for libretro

This commit is contained in:
Connor McLaughlin 2021-05-31 20:46:51 +10:00
parent 179a7aea89
commit 5edc645d1f

View file

@ -103,14 +103,37 @@ bool MemoryArena::IsValid() const
#endif #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<unsigned>(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) bool MemoryArena::Create(size_t size, bool writable, bool executable)
{ {
if (IsValid()) if (IsValid())
Destroy(); Destroy();
#if defined(WIN32) const std::string file_mapping_name(GetFileMappingName());
const std::string file_mapping_name = StringUtil::StdStringFromFormat("duckstation_%u", GetCurrentProcessId());
#if defined(_WIN32)
const DWORD protect = (writable ? (executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE) : PAGE_READONLY); 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), m_file_handle = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, protect, Truncate32(size >> 32), Truncate32(size),
file_mapping_name.c_str()); file_mapping_name.c_str());
@ -121,9 +144,7 @@ bool MemoryArena::Create(size_t size, bool writable, bool executable)
} }
return true; return true;
#elif defined(ANDROID) #elif defined(__ANDROID__)
const std::string file_mapping_name =
StringUtil::StdStringFromFormat("duckstation_%u", static_cast<unsigned>(getpid()));
m_shmem_fd = AshmemCreateFileMapping(file_mapping_name.c_str(), size); m_shmem_fd = AshmemCreateFileMapping(file_mapping_name.c_str(), size);
if (m_shmem_fd < 0) if (m_shmem_fd < 0)
{ {
@ -133,8 +154,6 @@ bool MemoryArena::Create(size_t size, bool writable, bool executable)
return true; return true;
#elif defined(__linux__) #elif defined(__linux__)
const std::string file_mapping_name =
StringUtil::StdStringFromFormat("duckstation_%u", static_cast<unsigned>(getpid()));
m_shmem_fd = shm_open(file_mapping_name.c_str(), O_CREAT | O_EXCL | (writable ? O_RDWR : O_RDONLY), 0600); 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) if (m_shmem_fd < 0)
{ {
@ -155,8 +174,6 @@ bool MemoryArena::Create(size_t size, bool writable, bool executable)
return true; return true;
#elif defined(__APPLE__) || defined(__FreeBSD__) #elif defined(__APPLE__) || defined(__FreeBSD__)
#if defined(__APPLE__) #if defined(__APPLE__)
const std::string file_mapping_name =
StringUtil::StdStringFromFormat("duckstation_%u", static_cast<unsigned>(getpid()));
m_shmem_fd = shm_open(file_mapping_name.c_str(), O_CREAT | O_EXCL | (writable ? O_RDWR : O_RDONLY), 0600); m_shmem_fd = shm_open(file_mapping_name.c_str(), O_CREAT | O_EXCL | (writable ? O_RDWR : O_RDONLY), 0600);
#else #else
m_shmem_fd = shm_open(SHM_ANON, O_CREAT | O_EXCL | (writable ? O_RDWR : O_RDONLY), 0600); m_shmem_fd = shm_open(SHM_ANON, O_CREAT | O_EXCL | (writable ? O_RDWR : O_RDONLY), 0600);