FEXCore: Fixes WIN32 compiling again

Mostly a quick bandage while I'm setting getting ready to setup the
runners to test this for us.
This commit is contained in:
Ryan Houdek committed 2023-07-12 11:53:13 -07:00
1 parent 70d54122b2
commit d387c46aab
8 files changed
+140 -26

No files matched your search

+2
View File
@@ -153,8 +153,10 @@ namespace FEXCore::Context {
*/
void DestroyThread(FEXCore::Core::InternalThreadState *Thread) override;
#ifndef _WIN32
void LockBeforeFork(FEXCore::Core::InternalThreadState *Thread) override;
void UnlockAfterFork(FEXCore::Core::InternalThreadState *Thread, bool Child) override;
#endif
void SetSignalDelegator(FEXCore::SignalDelegator *SignalDelegation) override;
void SetSyscallHandler(FEXCore::HLE::SyscallHandler *Handler) override;
+6
View File
@@ -655,6 +655,7 @@ namespace FEXCore::Context {
delete Thread;
}
#ifndef _WIN32
void ContextImpl::UnlockAfterFork(FEXCore::Core::InternalThreadState *LiveThread, bool Child) {
Allocator::UnlockAfterFork(LiveThread, Child);
@@ -708,6 +709,7 @@ namespace FEXCore::Context {
CodeInvalidationMutex.lock();
Allocator::LockBeforeFork(Thread);
}
#endif
void ContextImpl::AddBlockMapping(FEXCore::Core::InternalThreadState *Thread, uint64_t Address, void *Ptr) {
Thread->LookupCache->AddBlockMapping(Address, Ptr);
@@ -1155,7 +1157,9 @@ namespace FEXCore::Context {
Thread->ExitReason = FEXCore::Context::ExitReason::EXIT_WAITING;
InitializeThreadTLSData(Thread);
#ifndef _WIN32
Alloc::OSAllocator::RegisterTLSData(Thread);
#endif
++IdleWaitRefCount;
@@ -1200,7 +1204,9 @@ namespace FEXCore::Context {
--IdleWaitRefCount;
IdleWaitCV.notify_all();
#ifndef _WIN32
Alloc::OSAllocator::UninstallTLSData(Thread);
#endif
SignalDelegation->UninstallTLSState(Thread);
// If the parent thread is waiting to join, then we can't destroy our thread object
+2
View File
@@ -243,8 +243,10 @@ namespace FEXCore::Context {
FEX_DEFAULT_VISIBILITY virtual void RunThread(FEXCore::Core::InternalThreadState *Thread) = 0;
FEX_DEFAULT_VISIBILITY virtual void StopThread(FEXCore::Core::InternalThreadState *Thread) = 0;
FEX_DEFAULT_VISIBILITY virtual void DestroyThread(FEXCore::Core::InternalThreadState *Thread) = 0;
#ifndef _WIN32
FEX_DEFAULT_VISIBILITY virtual void LockBeforeFork(FEXCore::Core::InternalThreadState *Thread) {}
FEX_DEFAULT_VISIBILITY virtual void UnlockAfterFork(FEXCore::Core::InternalThreadState *Thread, bool Child) {}
#endif
FEX_DEFAULT_VISIBILITY virtual void SetSignalDelegator(FEXCore::SignalDelegator *SignalDelegation) = 0;
FEX_DEFAULT_VISIBILITY virtual void SetSyscallHandler(FEXCore::HLE::SyscallHandler *Handler) = 0;
+107 -17
View File
@@ -7,7 +7,9 @@
#include <mutex>
#include <shared_mutex>
#include <signal.h>
#ifndef _WIN32
#include <sys/syscall.h>
#endif
#include <unistd.h>
namespace FEXCore {
@@ -93,8 +95,70 @@ namespace FEXCore {
};
#else
// Windows doesn't support forking, so these can be standard mutexes.
using ForkableUniqueMutex = std::mutex;
using ForkableSharedMutex = std::shared_mutex;
class ForkableUniqueMutex final {
public:
ForkableUniqueMutex() = default;
// Non-moveable
ForkableUniqueMutex(const ForkableUniqueMutex&) = delete;
ForkableUniqueMutex& operator=(const ForkableUniqueMutex&) = delete;
ForkableUniqueMutex(ForkableUniqueMutex &&rhs) = delete;
ForkableUniqueMutex& operator=(ForkableUniqueMutex &&) = delete;
void lock() {
Mutex.lock();
}
void unlock() {
Mutex.unlock();
}
// Initialize the internal pthread object to its default initializer state.
// Should only ever be used in the child process when a Linux fork() has occured.
void StealAndDropActiveLocks() {
LogMan::Msg::AFmt("{} is unsupported on WIN32 builds!", __func__);
}
private:
std::mutex Mutex;
};
class ForkableSharedMutex final {
public:
ForkableSharedMutex() = default;
// Non-moveable
ForkableSharedMutex(const ForkableSharedMutex&) = delete;
ForkableSharedMutex& operator=(const ForkableSharedMutex&) = delete;
ForkableSharedMutex(ForkableSharedMutex &&rhs) = delete;
ForkableSharedMutex& operator=(ForkableSharedMutex &&) = delete;
void lock() {
Mutex.lock();
}
void unlock() {
Mutex.unlock();
}
void lock_shared() {
Mutex.lock_shared();
}
void unlock_shared() {
Mutex.unlock_shared();
}
bool try_lock() {
return Mutex.try_lock();
}
bool try_lock_shared() {
return Mutex.try_lock_shared();
}
// Initialize the internal pthread object to its default initializer state.
// Should only ever be used in the child process when a Linux fork() has occured.
void StealAndDropActiveLocks() {
LogMan::Msg::AFmt("{} is unsupported on WIN32 builds!", __func__);
}
private:
std::shared_mutex Mutex;
};
#endif
template<typename MutexType, void (MutexType::*lock_fn)(), void (MutexType::*unlock_fn)()>
@@ -165,10 +229,37 @@ namespace FEXCore {
&FEXCore::ForkableSharedMutex::lock,
&FEXCore::ForkableSharedMutex::unlock>;
class ScopedSignalMasker final {
public:
ScopedSignalMasker() = default;
void Mask(uint64_t Mask) {
#ifndef _WIN32
// Mask all signals, storing the original incoming mask
::syscall(SYS_rt_sigprocmask, SIG_SETMASK, &Mask, &OriginalMask, sizeof(OriginalMask));
#endif
}
// Move-only type
ScopedSignalMasker(const ScopedSignalMasker&) = delete;
ScopedSignalMasker& operator=(ScopedSignalMasker&) = delete;
ScopedSignalMasker(ScopedSignalMasker &&rhs) = default;
ScopedSignalMasker& operator=(ScopedSignalMasker &&) = default;
void Unmask() {
#ifndef _WIN32
::syscall(SYS_rt_sigprocmask, SIG_SETMASK, &OriginalMask, nullptr, sizeof(OriginalMask));
#endif
}
private:
#ifndef _WIN32
uint64_t OriginalMask{};
#endif
};
template<typename MutexType, void (MutexType::*lock_fn)(), void (MutexType::*unlock_fn)()>
class ScopedPotentialDeferredSignalWithMutexBase final {
public:
ScopedPotentialDeferredSignalWithMutexBase(MutexType &_Mutex, FEXCore::Core::InternalThreadState *Thread, uint64_t Mask = ~0ULL)
: Mutex {&_Mutex}
, Thread {Thread} {
@@ -176,8 +267,7 @@ namespace FEXCore {
Thread->CurrentFrame->State.DeferredSignalRefCount.Increment(1);
}
else {
// Mask all signals, storing the original incoming mask
::syscall(SYS_rt_sigprocmask, SIG_SETMASK, &Mask, &OriginalMask, sizeof(OriginalMask));
Masker.Mask(Mask);
}
// Lock the mutex
(Mutex->*lock_fn)();
@@ -201,29 +291,29 @@ namespace FEXCore {
if (Thread) {
#ifdef _M_X86_64
// Needs to be atomic so that operations can't end up getting reordered around this.
// Without this, the refcount and the signal access could get reordered.
auto Result = Thread->CurrentFrame->State.DeferredSignalRefCount.Decrement(1);
// Needs to be atomic so that operations can't end up getting reordered around this.
// Without this, the refcount and the signal access could get reordered.
auto Result = Thread->CurrentFrame->State.DeferredSignalRefCount.Decrement(1);
// X86-64 must do an additional check around the store.
if ((Result - 1) == 0) {
// Must happen after the refcount store
Thread->CurrentFrame->State.DeferredSignalFaultAddress->Store(0);
}
// X86-64 must do an additional check around the store.
if ((Result - 1) == 0) {
// Must happen after the refcount store
Thread->CurrentFrame->State.DeferredSignalFaultAddress->Store(0);
}
#else
Thread->CurrentFrame->State.DeferredSignalRefCount.Decrement(1);
Thread->CurrentFrame->State.DeferredSignalFaultAddress->Store(0);
Thread->CurrentFrame->State.DeferredSignalRefCount.Decrement(1);
Thread->CurrentFrame->State.DeferredSignalFaultAddress->Store(0);
#endif
}
else {
// Unmask back to the original signal mask
::syscall(SYS_rt_sigprocmask, SIG_SETMASK, &OriginalMask, nullptr, sizeof(OriginalMask));
Masker.Unmask();
}
}
}
private:
MutexType *Mutex;
uint64_t OriginalMask{};
ScopedSignalMasker Masker;
FEXCore::Core::InternalThreadState *Thread;
};
+1 -1
View File
@@ -58,7 +58,7 @@ namespace fextl::fmt {
FMT_INLINE auto print(::fmt::format_string<T...> fmt, T&&... args)
-> void {
auto String = fextl::fmt::vformat(fmt, ::fmt::make_format_args(args...));
auto f = fextl::file::File::GetStdOUT();
auto f = FEXCore::File::File::GetStdOUT();
f.Write(String.c_str(), String.size());
}
@@ -7,6 +7,7 @@
#include <unistd.h>
namespace FHU::Symlinks {
#ifndef _WIN32
// Checks to see if a filepath is a symlink.
inline bool IsSymlink(const fextl::string &Filename) {
struct stat Buffer{};
@@ -26,4 +27,5 @@ inline std::string_view ResolveSymlink(const fextl::string &Filename, std::span<
return std::string_view(ResultBuffer.data(), Result);
}
#endif
}
+1 -1
View File
@@ -2,13 +2,13 @@ add_subdirectory(cpp-optparse/)
set(NAME Common)
set(SRCS
Config.cpp
ArgumentLoader.cpp
EnvironmentLoader.cpp
StringUtil.cpp)
if (NOT MINGW_BUILD)
list (APPEND SRCS
Config.cpp
FEXServerClient.cpp
FileFormatCheck.cpp)
endif()
+19 -7
View File
@@ -10,9 +10,11 @@
#include <FEXHeaderUtils/SymlinkChecks.h>
#include <cstring>
#ifndef _WIN32
#include <linux/limits.h>
#include <list>
#include <pwd.h>
#endif
#include <list>
#include <utility>
#include <json-maker.h>
#include <tiny-json.h>
@@ -103,12 +105,13 @@ namespace JSON {
Dest = json_objClose(Dest);
json_end(Dest);
constexpr int USER_PERMS = S_IRWXU | S_IRWXG | S_IRWXO;
int FD = open(Filename.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, USER_PERMS);
auto File = FEXCore::File::File(Filename.c_str(),
FEXCore::File::FileModes::WRITE |
FEXCore::File::FileModes::CREATE |
FEXCore::File::FileModes::TRUNCATE);
if (FD != -1) {
write(FD, Buffer, strlen(Buffer));
close(FD);
if (File.IsValid()) {
File.Write(Buffer, strlen(Buffer));
}
}
@@ -286,7 +289,7 @@ namespace JSON {
// This is because we rewrite `/proc/self/exe` to the absolute program path calculated in here.
if (!Program.starts_with('/')) {
char ExistsTempPath[PATH_MAX];
char *RealPath = realpath(Program.c_str(), ExistsTempPath);
char *RealPath = FHU::Filesystem::Absolute(Program.c_str(), ExistsTempPath);
if (RealPath) {
Program = RealPath;
}
@@ -315,6 +318,7 @@ namespace JSON {
// execveat binfmt_misc args layout: `FEXInterpreter <Path provided to execve pathname> <user provided argv[0]> <user provided argv[n]>...`
// - Regular execveat with FD. FD points to file on disk that has been deleted.
// execveat binfmt_misc args layout: `FEXInterpreter /dev/fd/<FD> <user provided argv[0]> <user provided argv[n]>...`
#ifndef _WIN32
if (ExecFDInterp || !ProgramFDFromEnv.empty()) {
// Only in the case that FEX is executing an FD will the program argument potentially be a symlink.
// This symlink will be in the style of `/dev/fd/<FD>`.
@@ -331,6 +335,7 @@ namespace JSON {
}
}
}
#endif
return Program;
}
@@ -425,6 +430,7 @@ namespace JSON {
return {};
}
#ifndef _WIN32
char const* FindUserHomeThroughUID() {
auto passwd = getpwuid(geteuid());
if (passwd) {
@@ -525,4 +531,10 @@ namespace JSON {
FEXCore::Config::SetConfigFileLocation(GetConfigFileLocation(false), false);
FEXCore::Config::SetConfigFileLocation(GetConfigFileLocation(true), true);
}
#else
void InitializeConfigs() {
// TODO: Find out how to set this up on WIN32.
LogMan::Msg::EFmt("{} Unsupported on WIN32!", __func__);
}
#endif
}