Wine: Implements support for profile stats

This is a little trickier, we actually open the
`/dev/shm/fex-<pid>-stats` file directly using Windows APIs that way
Mangohud (which is going to be on the Linux side, or potentially even
embedded in to Gamescope) can safely pick up the stats.

A little quirky plus doesn't support expanding its size since WINE
doesn't support NtExtendSection, but that's fine.
This commit is contained in:
Ryan Houdek committed 2025-02-11 12:56:11 -08:00
1 parent 2ba0b66426
commit dcebe85f3a
5 files changed
+131 -5

No files matched your search

+19 -2
View File
@@ -39,6 +39,7 @@ $end_info$
#include "Common/PortabilityInfo.h"
#include "DummyHandlers.h"
#include "BTInterface.h"
#include "Windows/Common/Profiler.h"
#include <cstdint>
#include <type_traits>
@@ -106,6 +107,7 @@ namespace BridgeInstrs {
fextl::unique_ptr<FEXCore::Context::Context> CTX;
fextl::unique_ptr<FEX::DummyHandlers::DummySignalDelegator> SignalDelegator;
fextl::unique_ptr<WowSyscallHandler> SyscallHandler;
fextl::unique_ptr<FEX::Windows::StatAlloc> StatAllocHandler;
std::optional<FEX::Windows::InvalidationTracker> InvalidationTracker;
std::optional<FEX::Windows::CPUFeatures> CPUFeatures;
@@ -500,9 +502,17 @@ void BTCpuProcessInit() {
// wow64.dll will only initialise the cross-process queue if this is set
GetTLS().Wow64Info().CpuFlags = WOW64_CPUFLAGS_SOFTWARE;
FEX_CONFIG_OPT(ProfileStats, PROFILESTATS);
if (IsWine && ProfileStats()) {
StatAllocHandler = fextl::make_unique<FEX::Windows::StatAlloc>(FEXCore::Profiler::AppType::WIN_WOW64);
}
}
void BTCpuProcessTerm(HANDLE Handle, BOOL After, ULONG Status) {}
void BTCpuProcessTerm(HANDLE Handle, BOOL After, ULONG Status) {
StatAllocHandler.reset();
}
void BTCpuThreadInit() {
FEX::Windows::InitCRTThread();
@@ -511,7 +521,11 @@ void BTCpuThreadInit() {
GetTLS().ControlWord().fetch_or(ControlBits::WOW_CPU_AREA_DIRTY, std::memory_order::relaxed);
std::scoped_lock Lock(ThreadCreationMutex);
Threads.emplace(GetCurrentThreadId(), Thread);
auto ThreadTID = GetCurrentThreadId();
Threads.emplace(ThreadTID, Thread);
if (StatAllocHandler) {
Thread->ThreadStats = StatAllocHandler->AllocateSlot(ThreadTID);
}
}
void BTCpuThreadTerm(HANDLE Thread, LONG ExitCode) {
@@ -531,6 +545,9 @@ void BTCpuThreadTerm(HANDLE Thread, LONG ExitCode) {
{
std::scoped_lock Lock(ThreadCreationMutex);
Threads.erase(ThreadTID);
if (StatAllocHandler) {
StatAllocHandler->DeallocateSlot(OldThreadState->ThreadStats);
}
}
CTX->DestroyThread(OldThreadState);