From a9b28f9f2857873d06c1558fc494610aa43b6d49 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 22 Jan 2025 18:41:13 -0800 Subject: [PATCH] Wine: Add support for magic fex+wine shm path Fallback to the previous path if it doesn't exist. --- Source/Windows/Common/Profiler.cpp | 35 +++++++++++++++++++++++++++++- Source/Windows/Common/Profiler.h | 1 + Source/Windows/include/winternl.h | 7 ++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/Source/Windows/Common/Profiler.cpp b/Source/Windows/Common/Profiler.cpp index 6e24be04c2..cfa6437105 100644 --- a/Source/Windows/Common/Profiler.cpp +++ b/Source/Windows/Common/Profiler.cpp @@ -21,11 +21,44 @@ __attribute__((naked)) uint64_t linux_getpid() { } uint32_t StatAlloc::FrontendAllocateSlots(uint32_t NewSize) { - LogMan::Msg::DFmt("Ran out of slots. Can't allocate more"); + if (CurrentSize == MAX_STATS_SIZE || !UsingNTQueryPath) { + LogMan::Msg::DFmt("Ran out of slots. Can't allocate more"); + return CurrentSize; + } + + MEMORY_FEX_STATS_SHM_INFORMATION Info { + .shm_base = nullptr, + .map_size = std::min(CurrentSize * 2, MAX_STATS_SIZE), + .max_size = MAX_STATS_SIZE, + }; + size_t Length {}; + auto Result = NtQueryVirtualMemory(NtCurrentProcess(), nullptr, MemoryFexStatsShm, &Info, sizeof(Info), &Length); + if (!Result) { + CurrentSize = Info.map_size; + } + return CurrentSize; } StatAlloc::StatAlloc(FEXCore::Profiler::AppType AppType) { + // Try wine+fex magic path. + + { + MEMORY_FEX_STATS_SHM_INFORMATION Info { + .shm_base = nullptr, + .map_size = 4096, + .max_size = MAX_STATS_SIZE, + }; + size_t Length {}; + auto Result = NtQueryVirtualMemory(NtCurrentProcess(), nullptr, MemoryFexStatsShm, &Info, sizeof(Info), &Length); + if (!Result) { + UsingNTQueryPath = true; + CurrentSize = Info.map_size; + Base = Info.shm_base; + SaveHeader(AppType); + return; + } + } CurrentSize = MAX_STATS_SIZE; auto handle = CreateFile(fextl::fmt::format("/dev/shm/fex-{}-stats", linux_getpid()).c_str(), GENERIC_READ | GENERIC_WRITE, diff --git a/Source/Windows/Common/Profiler.h b/Source/Windows/Common/Profiler.h index 6bdd0f87fc..9deea2e552 100644 --- a/Source/Windows/Common/Profiler.h +++ b/Source/Windows/Common/Profiler.h @@ -23,6 +23,7 @@ class StatAlloc final : public FEX::Profiler::StatAllocBase { private: uint32_t FrontendAllocateSlots(uint32_t NewSize) override; + bool UsingNTQueryPath {}; }; } // namespace FEX::Windows diff --git a/Source/Windows/include/winternl.h b/Source/Windows/include/winternl.h index 2a3bbe1dd0..914d38a2ce 100644 --- a/Source/Windows/include/winternl.h +++ b/Source/Windows/include/winternl.h @@ -434,6 +434,7 @@ typedef enum _MEMORY_INFORMATION_CLASS { MemoryWineUnixFuncs = 1000, MemoryWineUnixWow64Funcs, #endif + MemoryFexStatsShm = 2000, } MEMORY_INFORMATION_CLASS; typedef enum _KEY_VALUE_INFORMATION_CLASS { @@ -452,6 +453,12 @@ typedef struct _KEY_VALUE_PARTIAL_INFORMATION { UCHAR Data[1]; } KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION; +typedef struct _MEMORY_FEX_STATS_SHM_INFORMATION { + void* shm_base; + DWORD map_size; + DWORD max_size; +} MEMORY_FEX_STATS_SHM_INFORMATION, *PMEMORY_FEX_STATS_SHM_INFORMATION; + NTSTATUS WINAPIV DbgPrint(LPCSTR fmt, ...); NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE); NTSTATUS WINAPI LdrGetDllFullName(HMODULE, UNICODE_STRING*);