diff --git a/pcsx2/microVU_Divtrace.cpp b/pcsx2/microVU_Divtrace.cpp index 9be4307ad8..bdd85c0897 100644 --- a/pcsx2/microVU_Divtrace.cpp +++ b/pcsx2/microVU_Divtrace.cpp @@ -17,7 +17,11 @@ #include #include #include -#if defined(__APPLE__) +#if defined(_WIN32) +// No ucontext/sigaction on Windows — the SIGTRAP capture machinery below is +// compiled out entirely (see EnterMode). The shared globals and fingerprint +// helpers still build, so the interp/JIT consumer sites link unchanged. +#elif defined(__APPLE__) // declares the deprecated getcontext/setcontext/... routines and // #errors out unless _XOPEN_SOURCE is defined. We only need the ucontext_t // type, which provides without that guard. (Mirrors @@ -117,6 +121,7 @@ namespace mvu_divtrace g_interp_op_idx = 0; } +#ifndef _WIN32 namespace { struct sigaction s_prev_handler{}; @@ -190,9 +195,19 @@ namespace mvu_divtrace #endif } } +#endif // !_WIN32 void EnterMode(int vu_index) { +#ifdef _WIN32 + // The capture path is SIGTRAP + ucontext (the JIT emits brk, the + // handler snapshots and skips it) — there is no Windows port. Only + // the offline replay drivers call this, and they don't build on + // Windows; fail loudly rather than letting an unhandled brk look + // like a JIT crash if that ever changes. + (void)vu_index; + pxFailRel("mvu_divtrace::EnterMode: SIGTRAP capture is not supported on Windows"); +#else g_vu_index = vu_index; Reset(); // Fingerprint streams: large, always recorded — these are what scale @@ -215,16 +230,19 @@ namespace mvu_divtrace s_installed = true; } g_enabled.store(true, std::memory_order_release); +#endif } void ExitMode() { g_enabled.store(false, std::memory_order_release); +#ifndef _WIN32 if (s_installed) { sigaction(SIGTRAP, &s_prev_handler, nullptr); s_installed = false; } +#endif } } // namespace mvu_divtrace diff --git a/pcsx2/vu_capture.cpp b/pcsx2/vu_capture.cpp index 64a7aa61c6..d208116afb 100644 --- a/pcsx2/vu_capture.cpp +++ b/pcsx2/vu_capture.cpp @@ -26,10 +26,24 @@ #include #include #include +#ifdef _WIN32 +#include +#else #include +#endif namespace vu_capture { + // Only used to salt filenames/reports so concurrent processes don't + // collide — any process-unique integer will do. + static int capture_pid() + { +#ifdef _WIN32 + return ::_getpid(); +#else + return ::getpid(); +#endif + } namespace { // Single mutex covers all WriteToFile callers so concurrent VU0/VU1 @@ -285,7 +299,7 @@ namespace vu_capture std::unordered_map g_count_seen; // Rank-mode: total executions per (vu_index, start_pc). std::unordered_map g_rank_counts; - std::mt19937_64 g_rng{0x5EEDu ^ static_cast(::getpid())}; + std::mt19937_64 g_rng{0x5EEDu ^ static_cast(capture_pid())}; void DumpRankReportAtExit() { @@ -303,7 +317,7 @@ namespace vu_capture std::sort(sorted.begin(), sorted.end(), [](const auto& a, const auto& b) { return a.second > b.second; }); - std::fprintf(f, "# vu_capture rank report — pid %d\n", ::getpid()); + std::fprintf(f, "# vu_capture rank report — pid %d\n", capture_pid()); std::fprintf(f, "# %-3s %-10s %16s\n", "vu", "start_pc", "executions"); for (const auto& [key, count] : sorted) { @@ -359,7 +373,7 @@ namespace vu_capture std::fprintf(g_traj_file, "# vu_capture trajectory — pid %d\n" "# seq vu pc budget cpu_cycle vu_cycle state_hash vumem_hash core_hash\n", - ::getpid()); + capture_pid()); std::atexit(&CloseTrajAtExit); } }