Merge pull request #3926 from bylaws/windef

FEXCore: Drop deferred signal handling on Windows
This commit is contained in:
Ryan Houdek 2024-08-08 17:33:44 -07:00 committed by GitHub
commit 1007f874bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 36 deletions

View File

@ -210,9 +210,11 @@ void Dispatcher::EmitDispatcher() {
ExitFunctionLinkerAddress = GetCursorAddress<uint64_t>();
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);
}

View File

@ -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<uint64_t> OriginalMask {};
};
#endif
/**
* @brief Produces a wrapper object around a scoped lock of the given mutex
@ -194,17 +176,12 @@ private:
template<template<typename> 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<MutexType> lock;
} scope_guard {ScopedSignalMasker {Mask}, LockType<MutexType> {mutex}};
return scope_guard;
#else
// TODO: Doesn't block signals which may or may not cause issues.
return LockType<MutexType> {mutex};
#endif
}
/**
@ -227,25 +204,50 @@ static auto GuardSignalDeferringSection(MutexType& mutex, FEXCore::Core::Interna
template<template<typename> 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<ScopedSignalMasker, DeferredSignalRefCountGuard>;
#else
using ExtraGuard = std::variant<std::monostate, DeferredSignalRefCountGuard>;
#endif
struct {
ExtraGuard refcount_or_mask;
LockType<MutexType> 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<MutexType> {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<template<typename> class LockType = std::unique_lock, typename MutexType>
[[nodiscard]]
static auto MaskSignalsAndLockMutex(MutexType& mutex, uint64_t Mask = ~0ULL) {
return LockType<MutexType> {mutex};
}
template<template<typename> class LockType = std::unique_lock, typename MutexType>
[[nodiscard]]
static auto GuardSignalDeferringSection(MutexType& mutex, FEXCore::Core::InternalThreadState* Thread, uint64_t Mask = ~0ULL) {
return LockType<MutexType> {mutex};
}
template<template<typename> class LockType = std::unique_lock, typename MutexType>
[[nodiscard]]
static auto GuardSignalDeferringSectionWithFallback(MutexType& mutex, FEXCore::Core::InternalThreadState* Thread, uint64_t Mask = ~0ULL) {
return LockType<MutexType> {mutex};
}
#endif
} // namespace FEXCore