diff --git a/Source/Core/Common/MemArena.h b/Source/Core/Common/MemArena.h index 7a0a683579..e365b78e0b 100644 --- a/Source/Core/Common/MemArena.h +++ b/Source/Core/Common/MemArena.h @@ -113,7 +113,13 @@ private: void* m_address_VirtualAlloc2 = nullptr; void* m_address_MapViewOfFile3 = nullptr; #else +#ifdef ANDROID int fd; +#else + int m_shm_fd; + void* m_reserved_region; + std::size_t m_reserved_region_size; +#endif #endif }; diff --git a/Source/Core/Common/MemArenaUnix.cpp b/Source/Core/Common/MemArenaUnix.cpp index 1743c2ace0..549ce09cfd 100644 --- a/Source/Core/Common/MemArenaUnix.cpp +++ b/Source/Core/Common/MemArenaUnix.cpp @@ -28,30 +28,39 @@ MemArena::~MemArena() = default; void MemArena::GrabSHMSegment(size_t size) { const std::string file_name = "/dolphin-emu." + std::to_string(getpid()); - fd = shm_open(file_name.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600); - if (fd == -1) + m_shm_fd = shm_open(file_name.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600); + if (m_shm_fd == -1) { ERROR_LOG_FMT(MEMMAP, "shm_open failed: {}", strerror(errno)); return; } shm_unlink(file_name.c_str()); - if (ftruncate(fd, size) < 0) + if (ftruncate(m_shm_fd, size) < 0) ERROR_LOG_FMT(MEMMAP, "Failed to allocate low memory space"); } void MemArena::ReleaseSHMSegment() { - close(fd); + close(m_shm_fd); } void* MemArena::CreateView(s64 offset, size_t size) { - return MapInMemoryRegion(offset, size, nullptr); + void* retval = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, m_shm_fd, offset); + if (retval == MAP_FAILED) + { + NOTICE_LOG_FMT(MEMMAP, "mmap failed"); + return nullptr; + } + else + { + return retval; + } } void MemArena::ReleaseView(void* view, size_t size) { - UnmapFromMemoryRegion(view, size); + munmap(view, size); } u8* MemArena::ReserveMemoryRegion(size_t memory_size) @@ -63,19 +72,23 @@ u8* MemArena::ReserveMemoryRegion(size_t memory_size) PanicAlertFmt("Failed to map enough memory space: {}", LastStrerrorString()); return nullptr; } - munmap(base, memory_size); + m_reserved_region = base; + m_reserved_region_size = memory_size; return static_cast(base); } void MemArena::ReleaseMemoryRegion() { + if (m_reserved_region) + { + munmap(m_reserved_region, m_reserved_region_size); + m_reserved_region = nullptr; + } } void* MemArena::MapInMemoryRegion(s64 offset, size_t size, void* base) { - void* retval = mmap(base, size, PROT_READ | PROT_WRITE, - MAP_SHARED | ((base == nullptr) ? 0 : MAP_FIXED), fd, offset); - + void* retval = mmap(base, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, m_shm_fd, offset); if (retval == MAP_FAILED) { NOTICE_LOG_FMT(MEMMAP, "mmap failed"); @@ -89,6 +102,8 @@ void* MemArena::MapInMemoryRegion(s64 offset, size_t size, void* base) void MemArena::UnmapFromMemoryRegion(void* view, size_t size) { - munmap(view, size); + void* retval = mmap(view, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); + if (retval == MAP_FAILED) + NOTICE_LOG_FMT(MEMMAP, "mmap failed"); } } // namespace Common