mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-05-26 21:47:06 +02:00
ok fixup but better with bool returns
This commit is contained in:
parent
77bd862151
commit
f6ca90804d
2 changed files with 47 additions and 50 deletions
|
|
@ -124,54 +124,55 @@ static void GetFuncAddress(Common::DynamicLibrary& dll, const char* name, T& pfn
|
||||||
class HostMemory::Impl {
|
class HostMemory::Impl {
|
||||||
public:
|
public:
|
||||||
explicit Impl(size_t backing_size_, size_t virtual_size_)
|
explicit Impl(size_t backing_size_, size_t virtual_size_)
|
||||||
: backing_size{backing_size_}, virtual_size{virtual_size_}, process{GetCurrentProcess()},
|
: backing_size{backing_size_}
|
||||||
kernelbase_dll("Kernelbase") {
|
, virtual_size{virtual_size_}
|
||||||
|
, process{GetCurrentProcess()}
|
||||||
|
, kernelbase_dll("Kernelbase")
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool Init() {
|
||||||
if (!kernelbase_dll.IsOpen()) {
|
if (!kernelbase_dll.IsOpen()) {
|
||||||
LOG_CRITICAL(HW_Memory, "Failed to load Kernelbase.dll");
|
LOG_CRITICAL(HW_Memory, "Failed to load Kernelbase.dll");
|
||||||
throw std::bad_alloc{};
|
return false;
|
||||||
}
|
}
|
||||||
GetFuncAddress(kernelbase_dll, "CreateFileMapping2", pfn_CreateFileMapping2);
|
GetFuncAddress(kernelbase_dll, "CreateFileMapping2", pfn_CreateFileMapping2);
|
||||||
GetFuncAddress(kernelbase_dll, "VirtualAlloc2", pfn_VirtualAlloc2);
|
GetFuncAddress(kernelbase_dll, "VirtualAlloc2", pfn_VirtualAlloc2);
|
||||||
GetFuncAddress(kernelbase_dll, "MapViewOfFile3", pfn_MapViewOfFile3);
|
GetFuncAddress(kernelbase_dll, "MapViewOfFile3", pfn_MapViewOfFile3);
|
||||||
GetFuncAddress(kernelbase_dll, "UnmapViewOfFile2", pfn_UnmapViewOfFile2);
|
GetFuncAddress(kernelbase_dll, "UnmapViewOfFile2", pfn_UnmapViewOfFile2);
|
||||||
|
|
||||||
|
if (!pfn_CreateFileMapping2 || !pfn_VirtualAlloc2 || !pfn_MapViewOfFile3 || !pfn_UnmapViewOfFile2) {
|
||||||
|
LOG_CRITICAL(HW_Memory, "Failed to find functions for virtual allocs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate backing file map
|
// Allocate backing file map
|
||||||
backing_handle =
|
backing_handle = pfn_CreateFileMapping2(INVALID_HANDLE_VALUE, nullptr, FILE_MAP_WRITE | FILE_MAP_READ, PAGE_READWRITE, SEC_COMMIT, backing_size, nullptr, nullptr, 0);
|
||||||
pfn_CreateFileMapping2(INVALID_HANDLE_VALUE, nullptr, FILE_MAP_WRITE | FILE_MAP_READ,
|
|
||||||
PAGE_READWRITE, SEC_COMMIT, backing_size, nullptr, nullptr, 0);
|
|
||||||
if (!backing_handle) {
|
if (!backing_handle) {
|
||||||
LOG_CRITICAL(HW_Memory, "Failed to allocate {} MiB of backing memory",
|
LOG_CRITICAL(HW_Memory, "Failed to allocate {} MiB of backing memory", backing_size >> 20);
|
||||||
backing_size >> 20);
|
return false;
|
||||||
throw std::bad_alloc{};
|
|
||||||
}
|
}
|
||||||
// Allocate a virtual memory for the backing file map as placeholder
|
// Allocate a virtual memory for the backing file map as placeholder
|
||||||
backing_base = static_cast<u8*>(pfn_VirtualAlloc2(process, nullptr, backing_size,
|
backing_base = static_cast<u8*>(pfn_VirtualAlloc2(process, nullptr, backing_size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, PAGE_NOACCESS, nullptr, 0));
|
||||||
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
|
|
||||||
PAGE_NOACCESS, nullptr, 0));
|
|
||||||
if (!backing_base) {
|
if (!backing_base) {
|
||||||
Release();
|
Release();
|
||||||
LOG_CRITICAL(HW_Memory, "Failed to reserve {} MiB of virtual memory",
|
LOG_CRITICAL(HW_Memory, "Failed to reserve {} MiB of virtual memory", backing_size >> 20);
|
||||||
backing_size >> 20);
|
return false;
|
||||||
throw std::bad_alloc{};
|
|
||||||
}
|
}
|
||||||
// Map backing placeholder
|
// Map backing placeholder
|
||||||
void* const ret = pfn_MapViewOfFile3(backing_handle, process, backing_base, 0, backing_size,
|
void* const ret = pfn_MapViewOfFile3(backing_handle, process, backing_base, 0, backing_size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, nullptr, 0);
|
||||||
MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, nullptr, 0);
|
|
||||||
if (ret != backing_base) {
|
if (ret != backing_base) {
|
||||||
Release();
|
Release();
|
||||||
LOG_CRITICAL(HW_Memory, "Failed to map {} MiB of virtual memory", backing_size >> 20);
|
LOG_CRITICAL(HW_Memory, "Failed to map {} MiB of virtual memory", backing_size >> 20);
|
||||||
throw std::bad_alloc{};
|
return false;
|
||||||
}
|
}
|
||||||
// Allocate virtual address placeholder
|
// Allocate virtual address placeholder
|
||||||
virtual_base = static_cast<u8*>(pfn_VirtualAlloc2(process, nullptr, virtual_size,
|
virtual_base = static_cast<u8*>(pfn_VirtualAlloc2(process, nullptr, virtual_size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, PAGE_NOACCESS, nullptr, 0));
|
||||||
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
|
|
||||||
PAGE_NOACCESS, nullptr, 0));
|
|
||||||
if (!virtual_base) {
|
if (!virtual_base) {
|
||||||
Release();
|
Release();
|
||||||
LOG_CRITICAL(HW_Memory, "Failed to reserve {} GiB of virtual memory",
|
LOG_CRITICAL(HW_Memory, "Failed to reserve {} GiB of virtual memory", virtual_size >> 30);
|
||||||
virtual_size >> 30);
|
return false;
|
||||||
throw std::bad_alloc{};
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Impl() {
|
~Impl() {
|
||||||
|
|
@ -501,10 +502,13 @@ static int shm_open_anon(int flags, mode_t mode) {
|
||||||
class HostMemory::Impl {
|
class HostMemory::Impl {
|
||||||
public:
|
public:
|
||||||
explicit Impl(size_t backing_size_, size_t virtual_size_)
|
explicit Impl(size_t backing_size_, size_t virtual_size_)
|
||||||
: backing_size{backing_size_}, virtual_size{virtual_size_} {
|
: backing_size{backing_size_}
|
||||||
|
, virtual_size{virtual_size_}
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool Init() {
|
||||||
long page_size = sysconf(_SC_PAGESIZE);
|
long page_size = sysconf(_SC_PAGESIZE);
|
||||||
ASSERT_MSG(page_size == 0x1000, "page size {:#x} is incompatible with 4K paging",
|
ASSERT_MSG(page_size == 0x1000, "page size {:#x} is incompatible with 4K paging", page_size);
|
||||||
page_size);
|
|
||||||
// Backing memory initialization
|
// Backing memory initialization
|
||||||
#if defined(__sun__) || defined(__HAIKU__) || defined(__NetBSD__) || defined(__DragonFly__)
|
#if defined(__sun__) || defined(__HAIKU__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||||
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
||||||
|
|
@ -545,15 +549,22 @@ public:
|
||||||
} else {
|
} else {
|
||||||
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
|
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
|
||||||
}
|
}
|
||||||
ASSERT_MSG(backing_base != MAP_FAILED, "mmap failed: {}", strerror(errno));
|
if (backing_base == MAP_FAILED) {
|
||||||
|
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Virtual memory initialization
|
// Virtual memory initialization
|
||||||
virtual_base = virtual_map_base = static_cast<u8*>(ChooseVirtualBase(virtual_size));
|
virtual_base = virtual_map_base = static_cast<u8*>(ChooseVirtualBase(virtual_size));
|
||||||
ASSERT_MSG(virtual_base != MAP_FAILED, "mmap failed: {}", strerror(errno));
|
if (virtual_base == MAP_FAILED) {
|
||||||
|
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
madvise(virtual_base, virtual_size, MADV_HUGEPAGE);
|
madvise(virtual_base, virtual_size, MADV_HUGEPAGE);
|
||||||
#endif
|
#endif
|
||||||
free_manager.SetAddressSpace(virtual_base, virtual_size);
|
free_manager.SetAddressSpace(virtual_base, virtual_size);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Impl() {
|
~Impl() {
|
||||||
|
|
@ -684,21 +695,10 @@ HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_)
|
||||||
backing_base = fallback_buffer->data();
|
backing_base = fallback_buffer->data();
|
||||||
virtual_base = nullptr;
|
virtual_base = nullptr;
|
||||||
#else
|
#else
|
||||||
bool has_memfd = true; // all platforms support it
|
// Try to allocate a fastmem arena.
|
||||||
#ifdef _WIN32
|
// The implementation will fail with std::bad_alloc on errors.
|
||||||
// EXCEPT WINDOWS who may not (Windows 8.1, 7, Vista, etc)
|
impl = std::make_unique<HostMemory::Impl>(AlignUp(backing_size, PageAlignment), AlignUp(virtual_size, PageAlignment) + HugePageSize);
|
||||||
DynamicLibrary kernelbase_dll("KernelBase");
|
if (impl->Init()) {
|
||||||
has_memfd = kernelbase_dll.IsOpen();
|
|
||||||
if (has_memfd) {
|
|
||||||
PFN_CreateFileMapping2 p{};
|
|
||||||
GetFuncAddress(kernelbase_dll, "CreateFileMapping2", p);
|
|
||||||
has_memfd = p != nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (has_memfd) {
|
|
||||||
// Try to allocate a fastmem arena.
|
|
||||||
// The implementation will fail with std::bad_alloc on errors.
|
|
||||||
impl = std::make_unique<HostMemory::Impl>(AlignUp(backing_size, PageAlignment), AlignUp(virtual_size, PageAlignment) + HugePageSize);
|
|
||||||
backing_base = impl->backing_base;
|
backing_base = impl->backing_base;
|
||||||
virtual_base = impl->virtual_base;
|
virtual_base = impl->virtual_base;
|
||||||
if (virtual_base) {
|
if (virtual_base) {
|
||||||
|
|
@ -707,12 +707,11 @@ HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_)
|
||||||
virtual_base_offset = virtual_base - impl->virtual_base;
|
virtual_base_offset = virtual_base - impl->virtual_base;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_WARNING(HW_Memory, "Platform doesn't support fastmem");
|
impl.reset();
|
||||||
#ifdef _WIN32
|
LOG_WARNING(HW_Memory, "Platform can support fastmem, but can't create it");
|
||||||
fallback_buffer.emplace(backing_size);
|
fallback_buffer.emplace(backing_size);
|
||||||
backing_base = fallback_buffer->data();
|
backing_base = fallback_buffer->data();
|
||||||
virtual_base = nullptr;
|
virtual_base = nullptr;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,10 +85,8 @@ private:
|
||||||
u8* backing_base{};
|
u8* backing_base{};
|
||||||
u8* virtual_base{};
|
u8* virtual_base{};
|
||||||
size_t virtual_base_offset{};
|
size_t virtual_base_offset{};
|
||||||
// Windows requires it for kernels whom lack proper support for some functions!
|
// Windows requires it for kernels whom lack proper support for some functions!
|
||||||
#if defined(__OPENORBIS__) || defined(__managarm__) || defined(_WIN32)
|
|
||||||
std::optional<Common::VirtualBuffer<u8>> fallback_buffer;
|
std::optional<Common::VirtualBuffer<u8>> fallback_buffer;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue