Skip to content

Commit

Permalink
Memory Cards: mmap on Linux and MacOS
Browse files Browse the repository at this point in the history
  • Loading branch information
F0bes committed Jan 14, 2025
1 parent 909b6d8 commit 4d600dc
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 17 deletions.
18 changes: 18 additions & 0 deletions common/Darwin/DarwinMisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,24 @@ void* HostSys::CreateSharedMemory(const char* name, size_t size)
return reinterpret_cast<void*>(static_cast<uintptr_t>(port));
}

void* HostSys::CreateMappingFromFile(FILE* file)
{
return reinterpret_cast<void*>(static_cast<uintptr_t>(fileno(file)));
}

void* HostSys::MapMapping(void* handle, const PageProtectionMode& mode)
{
const u32 mmap_prot = (mode.CanWrite() ? (PROT_READ | PROT_WRITE) : (PROT_READ)) | (mode.CanExecute() ? PROT_EXEC : 0);

return mmap(nullptr, 0, mmap_prot, MAP_PRIVATE | MAP_ANON, static_cast<int>(reinterpret_cast<intptr_t>(handle)), 0);
}

void HostSys::DestroyMapping(void* handle)
{
// The handle mmap requires is the same as the file descriptor.
return;
}

void HostSys::DestroySharedMemory(void* ptr)
{
mach_port_deallocate(mach_task_self(), static_cast<mach_port_t>(reinterpret_cast<uintptr_t>(ptr)));
Expand Down
5 changes: 5 additions & 0 deletions common/HostSys.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ namespace HostSys

extern std::string GetFileMappingName(const char* prefix);
extern void* CreateSharedMemory(const char* name, size_t size);

extern void* CreateMappingFromFile(FILE* file);
extern void* MapMapping(void* handle, const PageProtectionMode& mode);
extern void DestroyMapping(void* handle);

extern void DestroySharedMemory(void* ptr);
extern void* MapSharedMemory(void* handle, size_t offset, void* baseaddr, size_t size, const PageProtectionMode& mode);
extern void UnmapSharedMemory(void* baseaddr, size_t size);
Expand Down
16 changes: 16 additions & 0 deletions common/Linux/LnxHostSys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,22 @@ void* HostSys::CreateSharedMemory(const char* name, size_t size)
return reinterpret_cast<void*>(static_cast<intptr_t>(fd));
}

void* HostSys::CreateMappingFromFile(FILE* file)
{
return reinterpret_cast<void*>(static_cast<intptr_t>(fileno(file)));
}

void* HostSys::MapMapping(void* handle, const PageProtectionMode& mode)
{
return HostSys::MapSharedMemory(handle, 0, nullptr, 0, mode);
}

void HostSys::DestroyMapping(void* handle)
{
// The handle mmap requires is the same as the file descriptor.
return;
}

void HostSys::DestroySharedMemory(void* ptr)
{
close(static_cast<int>(reinterpret_cast<intptr_t>(ptr)));
Expand Down
17 changes: 17 additions & 0 deletions common/Windows/WinHostSys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "fmt/core.h"
#include "fmt/format.h"

#include <io.h>
#include <mutex>

static DWORD ConvertToWinApi(const PageProtectionMode& mode)
Expand Down Expand Up @@ -72,6 +73,22 @@ void* HostSys::CreateSharedMemory(const char* name, size_t size)
static_cast<DWORD>(size >> 32), static_cast<DWORD>(size), StringUtil::UTF8StringToWideString(name).c_str()));
}

void* HostSys::CreateMappingFromFile(FILE* fd)
{
return static_cast<void*>(CreateFileMappingW(reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(fd))), NULL, PAGE_READWRITE,
0, 0, nullptr));
}

void* HostSys::MapMapping(void* handle, const PageProtectionMode& mode)
{
return MapViewOfFile(static_cast<HANDLE>(handle), FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
}

void HostSys::DestroyMapping(void* handle)
{
CloseHandle(static_cast<HANDLE>(handle));
}

void HostSys::DestroySharedMemory(void* ptr)
{
CloseHandle(static_cast<HANDLE>(ptr));
Expand Down
27 changes: 10 additions & 17 deletions pcsx2/SIO/Memcard/MemoryCardFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "common/Console.h"
#include "common/Error.h"
#include "common/FileSystem.h"
#include "common/HostSys.h"
#include "common/Path.h"
#include "common/StringUtil.h"

Expand All @@ -24,11 +25,6 @@

#include <map>

#ifdef _WIN32
#include <windows.h>
#include <io.h>
#endif

static constexpr int MCD_SIZE = 1024 * 8 * 16; // Legacy PSX card default size

static constexpr int MC2_MBSIZE = 1024 * 528 * 2; // Size of a single megabyte of card data
Expand Down Expand Up @@ -163,6 +159,7 @@ class FileMemoryCard
protected:
std::FILE* m_file[8] = {};
u8* m_mappings[8] = {};
void* m_mapping_handles[8] = {};

s64 m_fileSize[8] = {};
std::string m_filenames[8] = {};
Expand Down Expand Up @@ -345,20 +342,16 @@ void FileMemoryCard::Open()
Host::ReportErrorAsync("Memory Card Read Failed", "Error reading memory card.");
}

#ifdef _WIN32
const int fd = _fileno(m_file[slot]);
// Doesn't leak, refcounted based on views
const HANDLE hMapping = CreateFileMapping(reinterpret_cast<HANDLE>(_get_osfhandle(fd)), nullptr, PAGE_READWRITE, 0, 0, nullptr);
if (!hMapping)
m_mapping_handles[slot] = HostSys::CreateMappingFromFile(m_file[slot]);
if (!m_mapping_handles[slot])
{
Console.Warning("CreateFileMapping failed: %d", GetLastError());
Console.Warning("CreateMappingFromFile failed!");
}
m_mappings[slot] = reinterpret_cast<u8*>(MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0));
m_mappings[slot] = static_cast<u8*>(HostSys::MapMapping(m_mapping_handles[slot], PageAccess_ReadWrite()));
if (!m_mappings[slot])
{
Console.Warning("MapViewOfFile failed: %d", GetLastError());
Console.Warning("MapSharedMemory failed!");
}
#endif
}
}
}
Expand Down Expand Up @@ -386,13 +379,13 @@ void FileMemoryCard::Close()

m_filenames[slot] = {};
m_fileSize[slot] = -1;
#ifdef _WIN32

if (m_mappings[slot])
{
UnmapViewOfFile(m_mappings[slot]);
HostSys::UnmapSharedMemory(m_mappings[slot], 0);
HostSys::DestroyMapping(m_mapping_handles[slot]);
m_mappings[slot] = nullptr;
}
#endif
}
}

Expand Down

0 comments on commit 4d600dc

Please sign in to comment.