diff --git a/FEXCore/Source/Interface/Config/Config.cpp b/FEXCore/Source/Interface/Config/Config.cpp index 6fd525e01..9f7b512cc 100644 --- a/FEXCore/Source/Interface/Config/Config.cpp +++ b/FEXCore/Source/Interface/Config/Config.cpp @@ -321,16 +321,6 @@ namespace DefaultValues { Meta->Load(); // Do configuration option fix ups after everything is reloaded - { - // Always fix up the number of threads and create the configuration - // Otherwise the application could receive zero as the number of threads - FEX_CONFIG_OPT(Cores, THREADS); - if (Cores == 0) { - // When the number of emulated CPU cores is zero then auto detect - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_THREADS, fextl::fmt::format("{}", FEXCore::CPUInfo::CalculateNumberOfCPUs())); - } - } - if (FEXCore::Config::Exists(FEXCore::Config::CONFIG_CORE)) { // Sanitize Core option FEX_CONFIG_OPT(Core, CORE); diff --git a/FEXCore/Source/Interface/Config/Config.json.in b/FEXCore/Source/Interface/Config/Config.json.in index f112d99f3..35e29a6b1 100644 --- a/FEXCore/Source/Interface/Config/Config.json.in +++ b/FEXCore/Source/Interface/Config/Config.json.in @@ -31,15 +31,6 @@ "Maximum number of instruction to store in a block" ] }, - "Threads": { - "Type": "uint32", - "Default": "0", - "ShortArg": "T", - "Desc": [ - "Number of physical hardware threads to tell the process we have.", - "0 will auto detect." - ] - }, "CacheObjectCodeCompilation": { "Type": "uint32", "Default": "FEXCore::Config::ConfigObjectCodeHandler::CONFIG_NONE", diff --git a/FEXCore/Source/Interface/Core/CPUID.cpp b/FEXCore/Source/Interface/Core/CPUID.cpp index dd9d8dac0..bbafa4a29 100644 --- a/FEXCore/Source/Interface/Core/CPUID.cpp +++ b/FEXCore/Source/Interface/Core/CPUID.cpp @@ -106,11 +106,10 @@ static uint32_t GetCycleCounterFrequency() { } void CPUIDEmu::SetupHostHybridFlag() { - size_t CPUs = FEXCore::CPUInfo::CalculateNumberOfCPUs(); - PerCPUData.resize(CPUs); + PerCPUData.resize(Cores); uint64_t MIDR{}; - for (size_t i = 0; i < CPUs; ++i) { + for (size_t i = 0; i < Cores; ++i) { std::error_code ec{}; fextl::string MIDRPath = fextl::fmt::format("/sys/devices/system/cpu/cpu{}/regs/identification/midr_el1", i); @@ -218,7 +217,7 @@ void CPUIDEmu::SetupHostHybridFlag() { fextl::vector LittleCores; // Separate CPU cores out to big or little selected - for (size_t i = 0; i < CPUs; ++i) { + for (size_t i = 0; i < Cores; ++i) { uint32_t MIDR = PerCPUData[i].MIDR; auto MIDROption = FindDefinedMIDR(MIDR); if (MIDROption) { @@ -334,7 +333,7 @@ void CPUIDEmu::SetupHostHybridFlag() { } else { // If we aren't hybrid then just claim everything is big - for (size_t i = 0; i < CPUs; ++i) { + for (size_t i = 0; i < Cores; ++i) { uint32_t MIDR = PerCPUData[i].MIDR; auto MIDROption = FindDefinedMIDR(MIDR); @@ -380,7 +379,6 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_0h(uint32_t Leaf) const { // Processor Info and Features bits FEXCore::CPUID::FunctionResults CPUIDEmu::Function_01h(uint32_t Leaf) const { FEXCore::CPUID::FunctionResults Res{}; - uint32_t CoreCount = Cores(); // Hypervisor bit is normally set but some applications have issues with it. uint32_t Hypervisor = HideHypervisorBit() ? 0 : 1; @@ -389,7 +387,7 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_01h(uint32_t Leaf) const { Res.ebx = 0 | // Brand index (8 << 8) | // Cache line size in bytes - (CoreCount << 16) | // Number of addressable IDs for the logical cores in the physical CPU + (Cores << 16) | // Number of addressable IDs for the logical cores in the physical CPU (0 << 24); // Local APIC ID Res.ecx = @@ -496,7 +494,7 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_04h(uint32_t Leaf) const { if (Leaf == 0) { // Report L1D - uint32_t CoreCount = Cores() - 1; + uint32_t CoreCount = Cores - 1; Res.eax = CacheType_Data | // Cache type (0b001 << 5) | // Cache level @@ -520,7 +518,7 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_04h(uint32_t Leaf) const { } else if (Leaf == 1) { // Report L1I - uint32_t CoreCount = Cores() - 1; + uint32_t CoreCount = Cores - 1; Res.eax = CacheType_Instruction | // Cache type (0b001 << 5) | // Cache level @@ -544,7 +542,7 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_04h(uint32_t Leaf) const { } else if (Leaf == 2) { // Report L2 - uint32_t CoreCount = Cores() - 1; + uint32_t CoreCount = Cores - 1; Res.eax = CacheType_Unified | // Cache type (0b010 << 5) | // Cache level @@ -568,7 +566,7 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_04h(uint32_t Leaf) const { } else if (Leaf == 3) { // Report L3 - uint32_t CoreCount = Cores() - 1; + uint32_t CoreCount = Cores - 1; Res.eax = CacheType_Unified | // Cache type (0b011 << 5) | // Cache level @@ -1070,7 +1068,7 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_8000_0008h(uint32_t Leaf) con (0 << 1) | // IRPerf: Instructions retired count support (CTX->HostFeatures.SupportsCLZERO << 0); // CLZERO support - uint32_t CoreCount = Cores() - 1; + uint32_t CoreCount = Cores - 1; Res.ecx = (0 << 16) | // PerfTscSize: Performance timestamp count size ((uint32_t)std::log2(CoreCount + 1) << 12) | // ApicIdSize: Number of bits in ApicID @@ -1168,7 +1166,7 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_8000_001Dh(uint32_t Leaf) con } else if (Leaf == 3) { // Report L3 - uint32_t CoreCount = Cores() - 1; + uint32_t CoreCount = Cores - 1; Res.eax = CacheType_Unified | // Cache type (0b011 << 5) | // Cache level @@ -1209,6 +1207,7 @@ FEXCore::CPUID::XCRResults CPUIDEmu::XCRFunction_0h() const { void CPUIDEmu::Init(FEXCore::Context::ContextImpl *ctx) { CTX = ctx; + Cores = FEXCore::CPUInfo::CalculateNumberOfCPUs(); // Setup some state tracking SetupHostHybridFlag(); diff --git a/FEXCore/Source/Interface/Core/CPUID.h b/FEXCore/Source/Interface/Core/CPUID.h index 5f0e58160..59ab4748d 100644 --- a/FEXCore/Source/Interface/Core/CPUID.h +++ b/FEXCore/Source/Interface/Core/CPUID.h @@ -113,7 +113,7 @@ public: private: FEXCore::Context::ContextImpl *CTX; bool Hybrid{}; - FEX_CONFIG_OPT(Cores, THREADS); + uint32_t Cores{}; FEX_CONFIG_OPT(HideHypervisorBit, HIDEHYPERVISORBIT); // XFEATURE_ENABLED_MASK diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp b/Source/Tools/FEXLoader/LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp index 20af6021d..5e8614582 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp +++ b/Source/Tools/FEXLoader/LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp @@ -14,6 +14,7 @@ $end_info$ #include #include #include +#include #include #include #include @@ -621,12 +622,13 @@ namespace FEX::EmulatedFile { } EmulatedFDManager::EmulatedFDManager(FEXCore::Context::Context *ctx) - : CTX {ctx} { + : CTX {ctx} + , ThreadsConfig { FEXCore::CPUInfo::CalculateNumberOfCPUs() } { FDReadCreators["/proc/cpuinfo"] = [&](FEXCore::Context::Context *ctx, int32_t fd, const char *pathname, int32_t flags, mode_t mode) -> int32_t { // Only allow a single thread to initialize the cpu_info. // Jit in-case multiple threads try to initialize at once. // Check if deferred cpuinfo initialization has occured. - std::call_once(cpu_info_initialized, [&]() { cpu_info = GenerateCPUInfo(ctx, ThreadsConfig()); }); + std::call_once(cpu_info_initialized, [&]() { cpu_info = GenerateCPUInfo(ctx, ThreadsConfig); }); int FD = GenTmpFD(); write(FD, (void*)&cpu_info.at(0), cpu_info.size()); @@ -702,9 +704,8 @@ namespace FEX::EmulatedFile { fextl::string procCmdLine = fextl::fmt::format("/proc/{}/cmdline", getpid()); FDReadCreators[procCmdLine] = cmdline_handler; - uint64_t CPUCores = ThreadsConfig(); - if (CPUCores > 1) { - cpus_online = fextl::fmt::format("0-{}", CPUCores - 1); + if (ThreadsConfig > 1) { + cpus_online = fextl::fmt::format("0-{}", ThreadsConfig - 1); } else { cpus_online = "0"; diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h b/Source/Tools/FEXLoader/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h index c6fa89bf3..71a46c21e 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h +++ b/Source/Tools/FEXLoader/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h @@ -34,6 +34,6 @@ namespace FEX::EmulatedFile { fextl::unordered_map FDReadCreators; static int32_t ProcAuxv(FEXCore::Context::Context* ctx, int32_t fd, const char* pathname, int32_t flags, mode_t mode); - FEX_CONFIG_OPT(ThreadsConfig, THREADS); + const uint32_t ThreadsConfig; }; } diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls.h b/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls.h index 3da407147..11de00ee8 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls.h +++ b/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls.h @@ -175,7 +175,6 @@ public: FEX_CONFIG_OPT(IsInterpreterInstalled, INTERPRETER_INSTALLED); FEX_CONFIG_OPT(Filename, APP_FILENAME); FEX_CONFIG_OPT(RootFSPath, ROOTFS); - FEX_CONFIG_OPT(ThreadsConfig, THREADS); FEX_CONFIG_OPT(Is64BitMode, IS64BIT_MODE); FEX_CONFIG_OPT(SMCChecks, SMCCHECKS); diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Info.cpp b/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Info.cpp index 5e4c4f64e..84b3501f7 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Info.cpp +++ b/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Info.cpp @@ -89,21 +89,8 @@ namespace FEX::HLE { REGISTER_SYSCALL_IMPL_FLAGS(getcpu, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, [](FEXCore::Core::CpuStateFrame *Frame, unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) -> uint64_t { - uint32_t LocalCPU{}; - uint32_t LocalNode{}; // tcache is ignored - uint64_t Result = ::syscall(SYSCALL_DEF(getcpu), cpu ? &LocalCPU : nullptr, node ? &LocalNode : nullptr, nullptr); - if (Result == 0) { - if (cpu) { - // Ensure we don't return a number over our number of emulated cores - *cpu = LocalCPU % FEX::HLE::_SyscallHandler->ThreadsConfig(); - } - - if (node) { - // Just claim we are part of node zero - *node = 0; - } - } + uint64_t Result = ::syscall(SYSCALL_DEF(getcpu), cpu, node, nullptr); SYSCALL_ERRNO(); }); diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Sched.cpp b/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Sched.cpp index 971bcd99b..08c0100c4 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Sched.cpp +++ b/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Sched.cpp @@ -80,35 +80,14 @@ namespace FEX::HLE { REGISTER_SYSCALL_IMPL_FLAGS(sched_setaffinity, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY | SyscallFlags::NOSIDEEFFECTS, [](FEXCore::Core::CpuStateFrame *Frame, pid_t pid, size_t cpusetsize, const unsigned long *mask) -> uint64_t { - return 0; + uint64_t Result = ::syscall(SYSCALL_DEF(sched_setaffinity), pid, cpusetsize, mask); + SYSCALL_ERRNO(); }); REGISTER_SYSCALL_IMPL_FLAGS(sched_getaffinity, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, [](FEXCore::Core::CpuStateFrame *Frame, pid_t pid, size_t cpusetsize, unsigned char *mask) -> uint64_t { - uint64_t Cores = FEX::HLE::_SyscallHandler->ThreadsConfig(); - - // Bytes need to round up to size of uint64_t - uint64_t Bytes = FEXCore::AlignUp(Cores, sizeof(uint64_t)); - - // cpusetsize needs to be 8byte aligned - if (cpusetsize & (sizeof(uint64_t) - 1)) { - return -EINVAL; - } - - // If we don't have enough bytes to store the resulting structure - // then we need to return -EINVAL - if (cpusetsize < Bytes) { - return -EINVAL; - } - - memset(mask, 0, Bytes); - - for (uint64_t i = 0; i < Cores; ++i) { - mask[i / 8] |= (1 << (i % 8)); - } - - // Returns the number of bytes written in to mask - return Bytes; + uint64_t Result = ::syscall(SYSCALL_DEF(sched_getaffinity), pid, cpusetsize, mask); + SYSCALL_ERRNO(); }); REGISTER_SYSCALL_IMPL_PASS_FLAGS(sched_setattr, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,