Skip to content

Commit

Permalink
MemArena: Use mach vm functions on iOS
Browse files Browse the repository at this point in the history
  • Loading branch information
OatmealDome committed Nov 23, 2019
1 parent 09e063b commit fbffaa4
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
44 changes: 44 additions & 0 deletions Source/Core/Common/MemArena.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ void MemArena::GrabSHMSegment(size_t size)
const std::string name = "dolphin-emu." + std::to_string(GetCurrentProcessId());
hMemoryMapping = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0,
static_cast<DWORD>(size), UTF8ToTStr(name).c_str());
#elif defined(IPHONEOS)
vm_size = size;
kern_return_t retval = vm_allocate(mach_task_self(), &vm_mem, size, VM_FLAGS_ANYWHERE);
if (retval != KERN_SUCCESS)
{
PanicAlert("Failed to grab a block of virtual memory: 0x%x", retval);
}
#elif defined(ANDROID)
fd = AshmemCreateFileMapping(("dolphin-emu." + std::to_string(getpid())).c_str(), size);
if (fd < 0)
Expand All @@ -86,6 +93,10 @@ void MemArena::ReleaseSHMSegment()
#ifdef _WIN32
CloseHandle(hMemoryMapping);
hMemoryMapping = 0;
#elif defined(IPHONEOS)
vm_deallocate(mach_task_self(), vm_mem, vm_size);
vm_size = 0;
vm_mem = 0;
#else
close(fd);
#endif
Expand All @@ -95,6 +106,25 @@ void* MemArena::CreateView(s64 offset, size_t size, void* base)
{
#ifdef _WIN32
return MapViewOfFileEx(hMemoryMapping, FILE_MAP_ALL_ACCESS, 0, (DWORD)((u64)offset), size, base);
#elif defined(IPHONEOS)
vm_address_t target = (vm_address_t)base;
uint64_t mask = 0;
bool anywhere = false;
vm_address_t source = vm_mem + offset;
vm_prot_t cur_protection = 0;
vm_prot_t max_protection = 0;

kern_return_t retval = vm_remap(mach_task_self(), &target, size, mask, anywhere,
mach_task_self(), source, false,
&cur_protection, &max_protection, VM_INHERIT_DEFAULT);
if (retval != KERN_SUCCESS)
{
PanicAlert("vm_remap failed (0x%x) - could not remap from %llx (offset %llx) of size %llx to %p",
(int)retval, (uint64_t)source, (uint64_t)offset, (uint64_t)size, base);
return nullptr;
}

return (void *)target;
#else
void* retval = mmap(base, size, PROT_READ | PROT_WRITE,
MAP_SHARED | ((base == nullptr) ? 0 : MAP_FIXED), fd, offset);
Expand All @@ -115,6 +145,8 @@ void MemArena::ReleaseView(void* view, size_t size)
{
#ifdef _WIN32
UnmapViewOfFile(view);
#elif defined(IPHONEOS)
vm_deallocate(mach_task_self(), (vm_address_t)view, size);
#else
munmap(view, size);
#endif
Expand All @@ -137,6 +169,18 @@ u8* MemArena::FindMemoryBase()
}
VirtualFree(base, 0, MEM_RELEASE);
return base;
#elif defined(IPHONEOS)
vm_address_t addr = 0;
kern_return_t retval = vm_allocate(mach_task_self(), &addr, memory_size, VM_FLAGS_ANYWHERE);
if (retval != KERN_SUCCESS)
{
PanicAlert("Failed to map enough memory space: 0x%x", retval);
exit(0);
}

// Don't need the memory now, was just probing.
vm_deallocate(mach_task_self(), addr, memory_size);
return (u8*)addr;
#else
#ifdef ANDROID
// Android 4.3 changed how mmap works.
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/Common/MemArena.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#ifdef _WIN32
#include <windows.h>
#elif defined(IPHONEOS)
#include <mach/mach.h>
#endif

#include "Common/CommonTypes.h"
Expand All @@ -32,6 +34,9 @@ class MemArena
private:
#ifdef _WIN32
HANDLE hMemoryMapping;
#elif defined(IPHONEOS)
vm_size_t vm_size;
vm_address_t vm_mem;
#else
int fd;
#endif
Expand Down

0 comments on commit fbffaa4

Please sign in to comment.