vm_native: add cow flag to map functions

CoW is copy-on-write mapping type.
This commit is contained in:
Nekotekina 2021-04-30 17:18:12 +03:00
parent 35ee550171
commit e327d47169
2 changed files with 16 additions and 11 deletions

View file

@ -65,13 +65,13 @@ namespace utils
~shm(); ~shm();
// Map shared memory // Map shared memory
u8* map(void* ptr, protection prot = protection::rw) const; u8* map(void* ptr, protection prot = protection::rw, bool cow = false) const;
// Attempt to map shared memory fix fixed pointer // Attempt to map shared memory fix fixed pointer
u8* try_map(void* ptr, protection prot = protection::rw) const; u8* try_map(void* ptr, protection prot = protection::rw, bool cow = false) const;
// Map shared memory over reserved memory region, which is unsafe (non-atomic) under Win32 // Map shared memory over reserved memory region, which is unsafe (non-atomic) under Win32
u8* map_critical(void* ptr, protection prot = protection::rw); u8* map_critical(void* ptr, protection prot = protection::rw, bool cow = false);
// Map shared memory into its own storage (not mapped by default) // Map shared memory into its own storage (not mapped by default)
u8* map_self(protection prot = protection::rw); u8* map_self(protection prot = protection::rw);

View file

@ -337,7 +337,7 @@ namespace utils
#endif #endif
} }
u8* shm::map(void* ptr, protection prot) const u8* shm::map(void* ptr, protection prot, bool cow) const
{ {
#ifdef _WIN32 #ifdef _WIN32
DWORD access = FILE_MAP_WRITE; DWORD access = FILE_MAP_WRITE;
@ -353,6 +353,11 @@ namespace utils
break; break;
} }
if (cow)
{
access |= FILE_MAP_COPY;
}
if (auto ret = static_cast<u8*>(::MapViewOfFileEx(m_handle, access, 0, 0, m_size, ptr))) if (auto ret = static_cast<u8*>(::MapViewOfFileEx(m_handle, access, 0, 0, m_size, ptr)))
{ {
if (prot != protection::rw && prot != protection::wx) if (prot != protection::rw && prot != protection::wx)
@ -374,7 +379,7 @@ namespace utils
if (ptr64) if (ptr64)
{ {
const auto result = ::mmap(reinterpret_cast<void*>(ptr64), m_size, +prot, MAP_SHARED | MAP_FIXED, m_file, 0); const auto result = ::mmap(reinterpret_cast<void*>(ptr64), m_size, +prot, (cow ? MAP_PRIVATE : MAP_SHARED) | MAP_FIXED, m_file, 0);
return reinterpret_cast<u8*>(result); return reinterpret_cast<u8*>(result);
} }
@ -383,7 +388,7 @@ namespace utils
const u64 res64 = reinterpret_cast<u64>(::mmap(reinterpret_cast<void*>(ptr64), m_size + 0xf000, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0)); const u64 res64 = reinterpret_cast<u64>(::mmap(reinterpret_cast<void*>(ptr64), m_size + 0xf000, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0));
const u64 aligned = utils::align(res64, 0x10000); const u64 aligned = utils::align(res64, 0x10000);
const auto result = ::mmap(reinterpret_cast<void*>(aligned), m_size, +prot, MAP_SHARED | MAP_FIXED, m_file, 0); const auto result = ::mmap(reinterpret_cast<void*>(aligned), m_size, +prot, (cow ? MAP_PRIVATE : MAP_SHARED) | MAP_FIXED, m_file, 0);
// Now cleanup remnants // Now cleanup remnants
if (aligned > res64) if (aligned > res64)
@ -401,15 +406,15 @@ namespace utils
#endif #endif
} }
u8* shm::try_map(void* ptr, protection prot) const u8* shm::try_map(void* ptr, protection prot, bool cow) const
{ {
// Non-null pointer shall be specified // Non-null pointer shall be specified
const auto target = ensure(reinterpret_cast<u8*>(reinterpret_cast<u64>(ptr) & -0x10000)); const auto target = ensure(reinterpret_cast<u8*>(reinterpret_cast<u64>(ptr) & -0x10000));
#ifdef _WIN32 #ifdef _WIN32
return this->map(target, prot); return this->map(target, prot, cow);
#else #else
const auto result = reinterpret_cast<u8*>(::mmap(reinterpret_cast<void*>(target), m_size, +prot, MAP_SHARED, m_file, 0)); const auto result = reinterpret_cast<u8*>(::mmap(reinterpret_cast<void*>(target), m_size, +prot, (cow ? MAP_PRIVATE : MAP_SHARED), m_file, 0));
if (result == reinterpret_cast<void*>(UINT64_MAX)) if (result == reinterpret_cast<void*>(UINT64_MAX))
{ {
@ -420,7 +425,7 @@ namespace utils
#endif #endif
} }
u8* shm::map_critical(void* ptr, protection prot) u8* shm::map_critical(void* ptr, protection prot, bool cow)
{ {
const auto target = reinterpret_cast<u8*>(reinterpret_cast<u64>(ptr) & -0x10000); const auto target = reinterpret_cast<u8*>(reinterpret_cast<u64>(ptr) & -0x10000);
@ -445,7 +450,7 @@ namespace utils
} }
#endif #endif
return this->map(target, prot); return this->map(target, prot, cow);
} }
u8* shm::map_self(protection prot) u8* shm::map_self(protection prot)