mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-10 06:00:18 +02:00
Noticed an issue where some applications were thinking that applications were running on a system with 512 CPU cores. Specifically freedreno/turnip was trying to create 512 worker threads which would cause my ARM devices to run out of memory. Looks like sysconf behaviour has changed around this where it is actually expecting the uint64_t alignment that the Linux kernel does. So follow that behaviour as well and resolve the issue.
110 lines
3.9 KiB
C++
110 lines
3.9 KiB
C++
/*
|
|
$info$
|
|
tags: LinuxSyscalls|syscalls-shared
|
|
$end_info$
|
|
*/
|
|
|
|
#include "Tests/LinuxSyscalls/Syscalls.h"
|
|
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
|
|
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
|
|
|
|
#include <FEXCore/Utils/MathUtils.h>
|
|
|
|
#include <stdint.h>
|
|
#include <sched.h>
|
|
#include <sys/time.h>
|
|
#include <sys/resource.h>
|
|
#include <sys/syscall.h>
|
|
#include <unistd.h>
|
|
|
|
namespace FEX::HLE {
|
|
void RegisterSched() {
|
|
|
|
REGISTER_SYSCALL_IMPL_PASS(sched_yield, [](FEXCore::Core::CpuStateFrame *Frame) -> uint64_t {
|
|
uint64_t Result = ::sched_yield();
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_PASS(getpriority, [](FEXCore::Core::CpuStateFrame *Frame, int which, int who) -> uint64_t {
|
|
uint64_t Result = ::syscall(SYSCALL_DEF(getpriority), which, who);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_PASS(setpriority, [](FEXCore::Core::CpuStateFrame *Frame, int which, int who, int prio) -> uint64_t {
|
|
uint64_t Result = ::setpriority(which, who, prio);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_PASS(sched_setparam, [](FEXCore::Core::CpuStateFrame *Frame, pid_t pid, const struct sched_param *param) -> uint64_t {
|
|
uint64_t Result = ::sched_setparam(pid, param);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_PASS(sched_getparam, [](FEXCore::Core::CpuStateFrame *Frame, pid_t pid, struct sched_param *param) -> uint64_t {
|
|
uint64_t Result = ::sched_getparam(pid, param);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_PASS(sched_setscheduler, [](FEXCore::Core::CpuStateFrame *Frame, pid_t pid, int policy, const struct sched_param *param) -> uint64_t {
|
|
uint64_t Result = ::sched_setscheduler(pid, policy, param);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_PASS(sched_getscheduler, [](FEXCore::Core::CpuStateFrame *Frame, pid_t pid) -> uint64_t {
|
|
uint64_t Result = ::sched_getscheduler(pid);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_PASS(sched_get_priority_max, [](FEXCore::Core::CpuStateFrame *Frame, int policy) -> uint64_t {
|
|
uint64_t Result = ::sched_get_priority_max(policy);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_PASS(sched_get_priority_min, [](FEXCore::Core::CpuStateFrame *Frame, int policy) -> uint64_t {
|
|
uint64_t Result = ::sched_get_priority_min(policy);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL(sched_setaffinity, [](FEXCore::Core::CpuStateFrame *Frame, pid_t pid, size_t cpusetsize, const unsigned long *mask) -> uint64_t {
|
|
return 0;
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL(sched_getaffinity, [](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;
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_PASS(sched_setattr, [](FEXCore::Core::CpuStateFrame *Frame, pid_t pid, struct sched_attr *attr, unsigned int flags) -> uint64_t {
|
|
uint64_t Result = ::syscall(SYSCALL_DEF(sched_setattr), pid, attr, flags);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_PASS(sched_getattr, [](FEXCore::Core::CpuStateFrame *Frame, pid_t pid, struct sched_attr *attr, unsigned int size, unsigned int flags) -> uint64_t {
|
|
uint64_t Result = ::syscall(SYSCALL_DEF(sched_getattr), pid, attr, size, flags);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
}
|
|
}
|