mirror of
https://github.com/FEX-Emu/FEX.git
synced 2025-02-24 16:51:32 +00:00
Merge pull request #2742 from Sonicadvance1/fix_win32
FEXCore: Fixes WIN32 compiling again
This commit is contained in:
commit
2283c73fae
@ -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;
|
||||
|
||||
|
@ -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
External/FEXCore/Source/Utils/Telemetry.cpp
vendored
2
External/FEXCore/Source/Utils/Telemetry.cpp
vendored
@ -61,7 +61,7 @@ namespace FEXCore::Telemetry {
|
||||
}
|
||||
}
|
||||
|
||||
Value &GetObject(TelemetryType Type) {
|
||||
Value &GetTelemetryValue(TelemetryType Type) {
|
||||
return TelemetryValues.at(Type);
|
||||
}
|
||||
#endif
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -41,7 +41,7 @@ namespace FEXCore::Telemetry {
|
||||
TYPE_LAST,
|
||||
};
|
||||
|
||||
Value &GetObject(TelemetryType Type);
|
||||
FEX_DEFAULT_VISIBILITY Value &GetTelemetryValue(TelemetryType Type);
|
||||
|
||||
FEX_DEFAULT_VISIBILITY void Initialize();
|
||||
FEX_DEFAULT_VISIBILITY void Shutdown(fextl::string const &ApplicationName);
|
||||
@ -50,8 +50,8 @@ namespace FEXCore::Telemetry {
|
||||
// This returns the internal structure to the telemetry data structures
|
||||
// One must be careful with placing these in the hot path of code execution
|
||||
// It can be fairly costly, especially in the static version where it puts barriers in the code
|
||||
#define FEXCORE_TELEMETRY_STATIC_INIT(Name, Type) static FEXCore::Telemetry::Value &Name = FEXCore::Telemetry::GetObject(FEXCore::Telemetry::Type)
|
||||
#define FEXCORE_TELEMETRY_INIT(Name, Type) FEXCore::Telemetry::Value &Name = FEXCore::Telemetry::GetObject(FEXCore::Telemetry::Type)
|
||||
#define FEXCORE_TELEMETRY_STATIC_INIT(Name, Type) static FEXCore::Telemetry::Value &Name = FEXCore::Telemetry::GetTelemetryValue(FEXCore::Telemetry::Type)
|
||||
#define FEXCORE_TELEMETRY_INIT(Name, Type) FEXCore::Telemetry::Value &Name = FEXCore::Telemetry::GetTelemetryValue(FEXCore::Telemetry::Type)
|
||||
// Telemetry ALU operations
|
||||
// These are typically 3-4 instructions depending on what you're doing
|
||||
#define FEXCORE_TELEMETRY_SET(Name, Value) Name = Value
|
||||
|
2
External/FEXCore/include/FEXCore/fextl/fmt.h
vendored
2
External/FEXCore/include/FEXCore/fextl/fmt.h
vendored
@ -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
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user