mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-24 12:25:00 +00:00
add scePthreadSetaffinity and emulate affinity (#2885)
* add implementation * fix preprocessor * fixes squidbus's comments * fix clang * comment became fucked up? * fix removed return
This commit is contained in:
parent
c7fb3ebd93
commit
1aa7eb8a42
2 changed files with 72 additions and 0 deletions
|
@ -289,7 +289,12 @@ int PS4_SYSV_ABI posix_pthread_create_name_np(PthreadT* thread, const PthreadAtt
|
||||||
/* Create thread */
|
/* Create thread */
|
||||||
new_thread->native_thr = Core::NativeThread();
|
new_thread->native_thr = Core::NativeThread();
|
||||||
int ret = new_thread->native_thr.Create(RunThread, new_thread, &new_thread->attr);
|
int ret = new_thread->native_thr.Create(RunThread, new_thread, &new_thread->attr);
|
||||||
|
|
||||||
ASSERT_MSG(ret == 0, "Failed to create thread with error {}", ret);
|
ASSERT_MSG(ret == 0, "Failed to create thread with error {}", ret);
|
||||||
|
|
||||||
|
if (attr != nullptr && *attr != nullptr && (*attr)->cpuset != nullptr) {
|
||||||
|
new_thread->SetAffinity((*attr)->cpuset);
|
||||||
|
}
|
||||||
if (ret) {
|
if (ret) {
|
||||||
*thread = nullptr;
|
*thread = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -521,6 +526,69 @@ int PS4_SYSV_ABI posix_pthread_setcancelstate(PthreadCancelState state,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Pthread::SetAffinity(const Cpuset* cpuset) {
|
||||||
|
const auto processor_count = std::thread::hardware_concurrency();
|
||||||
|
if (processor_count < 8) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (cpuset == nullptr) {
|
||||||
|
return POSIX_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 mask = cpuset->bits;
|
||||||
|
|
||||||
|
uintptr_t handle = native_thr.GetHandle();
|
||||||
|
if (handle == 0) {
|
||||||
|
return POSIX_ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't use this currently because some games gets performance problems
|
||||||
|
// when applying affinity even on strong hardware
|
||||||
|
/*
|
||||||
|
#ifdef _WIN64
|
||||||
|
DWORD_PTR affinity_mask = static_cast<DWORD_PTR>(mask);
|
||||||
|
if (!SetThreadAffinityMask(reinterpret_cast<HANDLE>(handle), affinity_mask)) {
|
||||||
|
return POSIX_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__linux__)
|
||||||
|
cpu_set_t cpu_set;
|
||||||
|
CPU_ZERO(&cpu_set);
|
||||||
|
|
||||||
|
u64 mask = cpuset->bits;
|
||||||
|
for (int cpu = 0; cpu < std::min(64, CPU_SETSIZE); ++cpu) {
|
||||||
|
if (mask & (1ULL << cpu)) {
|
||||||
|
CPU_SET(cpu, &cpu_set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int result =
|
||||||
|
pthread_setaffinity_np(static_cast<pthread_t>(handle), sizeof(cpu_set_t), &cpu_set);
|
||||||
|
if (result != 0) {
|
||||||
|
return POSIX_EINVAL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI posix_pthread_setaffinity_np(PthreadT thread, size_t cpusetsize,
|
||||||
|
const Cpuset* cpusetp) {
|
||||||
|
if (thread == nullptr || cpusetp == nullptr) {
|
||||||
|
return POSIX_EINVAL;
|
||||||
|
}
|
||||||
|
thread->attr.cpusetsize = cpusetsize;
|
||||||
|
return thread->SetAffinity(cpusetp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI scePthreadSetaffinity(PthreadT thread, const Cpuset mask) {
|
||||||
|
int result = posix_pthread_setaffinity_np(thread, 0x10, &mask);
|
||||||
|
if (result != 0) {
|
||||||
|
return ErrnoToSceKernelError(result);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterThread(Core::Loader::SymbolsResolver* sym) {
|
void RegisterThread(Core::Loader::SymbolsResolver* sym) {
|
||||||
// Posix
|
// Posix
|
||||||
LIB_FUNCTION("Z4QosVuAsA0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_once);
|
LIB_FUNCTION("Z4QosVuAsA0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_once);
|
||||||
|
@ -544,6 +612,7 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("Z4QosVuAsA0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_once);
|
LIB_FUNCTION("Z4QosVuAsA0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_once);
|
||||||
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self);
|
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self);
|
||||||
LIB_FUNCTION("OxhIB8LB-PQ", "libkernel", 1, "libkernel", 1, 1, posix_pthread_create);
|
LIB_FUNCTION("OxhIB8LB-PQ", "libkernel", 1, "libkernel", 1, 1, posix_pthread_create);
|
||||||
|
LIB_FUNCTION("5KWrg7-ZqvE", "libkernel", 1, "libkernel", 1, 1, posix_pthread_setaffinity_np);
|
||||||
|
|
||||||
// Orbis
|
// Orbis
|
||||||
LIB_FUNCTION("14bOACANTBo", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_once));
|
LIB_FUNCTION("14bOACANTBo", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_once));
|
||||||
|
@ -566,6 +635,7 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("W0Hpm2X0uPE", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_setprio));
|
LIB_FUNCTION("W0Hpm2X0uPE", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_setprio));
|
||||||
LIB_FUNCTION("rNhWz+lvOMU", "libkernel", 1, "libkernel", 1, 1, _sceKernelSetThreadDtors);
|
LIB_FUNCTION("rNhWz+lvOMU", "libkernel", 1, "libkernel", 1, 1, _sceKernelSetThreadDtors);
|
||||||
LIB_FUNCTION("6XG4B33N09g", "libkernel", 1, "libkernel", 1, 1, sched_yield);
|
LIB_FUNCTION("6XG4B33N09g", "libkernel", 1, "libkernel", 1, 1, sched_yield);
|
||||||
|
LIB_FUNCTION("bt3CTBKmGyI", "libkernel", 1, "libkernel", 1, 1, scePthreadSetaffinity)
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
|
|
@ -332,6 +332,8 @@ struct Pthread {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SetAffinity(const Cpuset* cpuset);
|
||||||
};
|
};
|
||||||
using PthreadT = Pthread*;
|
using PthreadT = Pthread*;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue