From 6700511cdfd43bb4aa79324b9fb973274c7c4e26 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Wed, 31 Jul 2024 16:48:24 +0000 Subject: [PATCH] FEXCore: Drop deferred signal handling on Windows The async signal issues this handles do not exist on Windows. --- .../Interface/Core/Dispatcher/Dispatcher.cpp | 8 ++ .../include/FEXCore/Utils/SignalScopeGuards.h | 74 ++++++++++--------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp b/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp index 18276f855..cf7e77982 100644 --- a/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp +++ b/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp @@ -210,9 +210,11 @@ void Dispatcher::EmitDispatcher() { ExitFunctionLinkerAddress = GetCursorAddress(); SpillStaticRegs(TMP1); +#ifndef _WIN32 ldr(ARMEmitter::XReg::x0, STATE, offsetof(FEXCore::Core::CPUState, DeferredSignalRefCount)); add(ARMEmitter::Size::i64Bit, ARMEmitter::XReg::x0, ARMEmitter::XReg::x0, 1); str(ARMEmitter::XReg::x0, STATE, offsetof(FEXCore::Core::CPUState, DeferredSignalRefCount)); +#endif #ifdef _M_ARM_64EC ldr(ARMEmitter::XReg::x0, ARMEmitter::XReg::x18, TEB_CPU_AREA_OFFSET); @@ -241,6 +243,7 @@ void Dispatcher::EmitDispatcher() { strb(ARMEmitter::WReg::zr, TMP2, CPU_AREA_IN_SYSCALL_CALLBACK_OFFSET); #endif +#ifndef _WIN32 ldr(TMP2, STATE, offsetof(FEXCore::Core::CPUState, DeferredSignalRefCount)); sub(ARMEmitter::Size::i64Bit, TMP2, TMP2, 1); str(TMP2, STATE, offsetof(FEXCore::Core::CPUState, DeferredSignalRefCount)); @@ -248,6 +251,7 @@ void Dispatcher::EmitDispatcher() { // Trigger segfault if any deferred signals are pending strb(ARMEmitter::XReg::zr, STATE, offsetof(FEXCore::Core::InternalThreadState, InterruptFaultPage) - offsetof(FEXCore::Core::InternalThreadState, BaseFrameState)); +#endif br(TMP1); } @@ -283,9 +287,11 @@ void Dispatcher::EmitDispatcher() { mov(ARMEmitter::XReg::x2, RipReg); } +#ifndef _WIN32 ldr(ARMEmitter::XReg::x0, STATE, offsetof(FEXCore::Core::CPUState, DeferredSignalRefCount)); add(ARMEmitter::Size::i64Bit, ARMEmitter::XReg::x0, ARMEmitter::XReg::x0, 1); str(ARMEmitter::XReg::x0, STATE, offsetof(FEXCore::Core::CPUState, DeferredSignalRefCount)); +#endif #ifdef _M_ARM_64EC ldr(ARMEmitter::XReg::x0, ARMEmitter::XReg::x18, TEB_CPU_AREA_OFFSET); @@ -312,6 +318,7 @@ void Dispatcher::EmitDispatcher() { strb(ARMEmitter::WReg::zr, TMP1, CPU_AREA_IN_SYSCALL_CALLBACK_OFFSET); #endif +#ifndef _WIN32 ldr(TMP1, STATE, offsetof(FEXCore::Core::CPUState, DeferredSignalRefCount)); sub(ARMEmitter::Size::i64Bit, TMP1, TMP1, 1); str(TMP1, STATE, offsetof(FEXCore::Core::CPUState, DeferredSignalRefCount)); @@ -319,6 +326,7 @@ void Dispatcher::EmitDispatcher() { // Trigger segfault if any deferred signals are pending strb(ARMEmitter::XReg::zr, STATE, offsetof(FEXCore::Core::InternalThreadState, InterruptFaultPage) - offsetof(FEXCore::Core::InternalThreadState, BaseFrameState)); +#endif b(&LoopTop); } diff --git a/FEXCore/include/FEXCore/Utils/SignalScopeGuards.h b/FEXCore/include/FEXCore/Utils/SignalScopeGuards.h index b570a7122..187cfbe41 100644 --- a/FEXCore/include/FEXCore/Utils/SignalScopeGuards.h +++ b/FEXCore/include/FEXCore/Utils/SignalScopeGuards.h @@ -93,22 +93,6 @@ public: private: pthread_rwlock_t Mutex; }; -#else -// Windows doesn't support forking, so these can be standard mutexes. -class ForkableUniqueMutex final : public std::mutex { -public: - void StealAndDropActiveLocks() { - LogMan::Msg::AFmt("{} is unsupported on WIN32 builds!", __func__); - } -}; - -class ForkableSharedMutex final : public std::shared_mutex { -public: - void StealAndDropActiveLocks() { - LogMan::Msg::AFmt("{} is unsupported on WIN32 builds!", __func__); - } -}; -#endif // Helper class to manage deferred signal refcounting within a block scope class DeferredSignalRefCountGuard final { @@ -151,7 +135,6 @@ private: FEXCore::Core::InternalThreadState* Thread; }; -#ifndef _WIN32 // Helper class to mask POSIX signals within a block scope class ScopedSignalMasker final { public: @@ -177,7 +160,6 @@ public: private: std::optional OriginalMask {}; }; -#endif /** * @brief Produces a wrapper object around a scoped lock of the given mutex @@ -194,17 +176,12 @@ private: template class LockType = std::unique_lock, typename MutexType> [[nodiscard]] static auto MaskSignalsAndLockMutex(MutexType& mutex, uint64_t Mask = ~0ULL) { -#ifndef _WIN32 // Signals are masked first, and then the lock is acquired struct { ScopedSignalMasker mask; LockType lock; } scope_guard {ScopedSignalMasker {Mask}, LockType {mutex}}; return scope_guard; -#else - // TODO: Doesn't block signals which may or may not cause issues. - return LockType {mutex}; -#endif } /** @@ -227,25 +204,50 @@ static auto GuardSignalDeferringSection(MutexType& mutex, FEXCore::Core::Interna template class LockType = std::unique_lock, typename MutexType> [[nodiscard]] static auto GuardSignalDeferringSectionWithFallback(MutexType& mutex, FEXCore::Core::InternalThreadState* Thread, uint64_t Mask = ~0ULL) { -#ifndef _WIN32 using ExtraGuard = std::variant; -#else - using ExtraGuard = std::variant; -#endif struct { ExtraGuard refcount_or_mask; LockType lock; - } scope_guard {Thread ? ExtraGuard {DeferredSignalRefCountGuard {Thread}} -#ifndef _WIN32 - : - ExtraGuard {ScopedSignalMasker {Mask}} -#else - : - ExtraGuard {} -#endif - }; + } scope_guard {Thread ? ExtraGuard {DeferredSignalRefCountGuard {Thread}} : ExtraGuard {ScopedSignalMasker {Mask}}}; scope_guard.lock = LockType {mutex}; return scope_guard; } + +#else + +// Dummy implementations as Windows doesn't support forking or async signals. +class ForkableUniqueMutex final : public std::mutex { +public: + void StealAndDropActiveLocks() { + LogMan::Msg::AFmt("{} is unsupported on WIN32 builds!", __func__); + } +}; + +class ForkableSharedMutex final : public std::shared_mutex { +public: + void StealAndDropActiveLocks() { + LogMan::Msg::AFmt("{} is unsupported on WIN32 builds!", __func__); + } +}; + +template class LockType = std::unique_lock, typename MutexType> +[[nodiscard]] +static auto MaskSignalsAndLockMutex(MutexType& mutex, uint64_t Mask = ~0ULL) { + return LockType {mutex}; +} + +template class LockType = std::unique_lock, typename MutexType> +[[nodiscard]] +static auto GuardSignalDeferringSection(MutexType& mutex, FEXCore::Core::InternalThreadState* Thread, uint64_t Mask = ~0ULL) { + return LockType {mutex}; +} + +template class LockType = std::unique_lock, typename MutexType> +[[nodiscard]] +static auto GuardSignalDeferringSectionWithFallback(MutexType& mutex, FEXCore::Core::InternalThreadState* Thread, uint64_t Mask = ~0ULL) { + return LockType {mutex}; +} + +#endif } // namespace FEXCore