Merge pull request #1922 from rmz-24/feat/libkernel-pthread-getaffinity-np
feat(libkernel): implement pthread_getaffinity_np
This commit is contained in:
commit
ccf9ff9044
|
|
@ -9,6 +9,7 @@
|
|||
#include "Common.hpp"
|
||||
#include "prx/libkernel/KernelErrors.hpp"
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
|
||||
extern "C" {
|
||||
|
|
@ -28,6 +29,8 @@ int APS5_VABI scePthreadGetprio(Pthread thread, int* prio);
|
|||
}
|
||||
|
||||
static constexpr int GUEST_SCHED_FIFO = 1;
|
||||
static constexpr std::size_t GUEST_CPUSET_BYTES = 32;
|
||||
static constexpr int GUEST_ERANGE = 34;
|
||||
|
||||
extern "C" {
|
||||
int* APS5_VABI __error_nid_postfix();
|
||||
|
|
@ -116,6 +119,18 @@ int APS5_VABI pthread_getschedparam_nid_postfix(Pthread thread, int* policy, Ker
|
|||
return PosixThread::ToErrno(scePthreadGetprio(thread, ¶m->sched_priority));
|
||||
}
|
||||
|
||||
int APS5_VABI pthread_getaffinity_np_nid_postfix(Pthread thread, std::size_t cpusetSize, void* cpuset) {
|
||||
if (!thread) return PosixThread::GUEST_EINVAL;
|
||||
if (cpusetSize != GUEST_CPUSET_BYTES) return GUEST_ERANGE;
|
||||
if (!cpuset) return PosixThread::GUEST_EFAULT;
|
||||
KernelCpumask mask = 0;
|
||||
const int result = scePthreadGetaffinity(thread, &mask);
|
||||
if (result != 0) return PosixThread::ToErrno(result);
|
||||
std::memset(cpuset, 0, GUEST_CPUSET_BYTES);
|
||||
std::memcpy(cpuset, &mask, sizeof(mask));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI pthread_join_nid_postfix(Pthread thread, void** value) {
|
||||
return PosixThread::ToErrno(scePthreadJoin(thread, value));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <future>
|
||||
|
||||
extern "C" {
|
||||
|
|
@ -18,6 +19,8 @@ int APS5_VABI cpuset_getaffinity_nid_postfix(int level, int which, std::int64_t
|
|||
int APS5_VABI cpuset_setaffinity_nid_postfix(int level, int which, std::int64_t id, std::size_t size, const void* mask);
|
||||
int APS5_VABI getpid_nid_postfix(void);
|
||||
int* APS5_VABI __error_nid_postfix();
|
||||
Pthread APS5_VABI pthread_self_nid_postfix(void);
|
||||
int APS5_VABI pthread_getaffinity_np_nid_postfix(Pthread thread, std::size_t cpusetSize, void* cpuset);
|
||||
}
|
||||
|
||||
static constexpr int SCE_OK = 0;
|
||||
|
|
@ -25,6 +28,22 @@ static constexpr int PS5_LOGICAL_CPUS = 16;
|
|||
|
||||
static void Require(bool value) { if (!value) std::abort(); }
|
||||
|
||||
static constexpr std::size_t GUEST_CPUSET_BYTES = 32;
|
||||
static constexpr int GUEST_EINVAL = 22;
|
||||
static constexpr int GUEST_EFAULT = 14;
|
||||
static constexpr int GUEST_ERANGE = 34;
|
||||
|
||||
static KernelCpumask ReadCpuset(Pthread thread) {
|
||||
std::uint8_t cpuset[GUEST_CPUSET_BYTES + 8];
|
||||
std::memset(cpuset, 0xAB, sizeof(cpuset));
|
||||
Require(pthread_getaffinity_np_nid_postfix(thread, GUEST_CPUSET_BYTES, cpuset) == 0);
|
||||
for (std::size_t i = sizeof(KernelCpumask); i < GUEST_CPUSET_BYTES; ++i) Require(cpuset[i] == 0);
|
||||
for (std::size_t i = GUEST_CPUSET_BYTES; i < sizeof(cpuset); ++i) Require(cpuset[i] == 0xAB);
|
||||
KernelCpumask mask = 0;
|
||||
std::memcpy(&mask, cpuset, sizeof(mask));
|
||||
return mask;
|
||||
}
|
||||
|
||||
static void* APS5_VABI Worker(void* arg) {
|
||||
static_cast<std::future<void>*>(arg)->get();
|
||||
return nullptr;
|
||||
|
|
@ -102,6 +121,7 @@ int main() {
|
|||
Require(scePthreadSetaffinity(thread, cpu) == SCE_OK);
|
||||
Require(scePthreadGetaffinity(thread, &threadAffinity) == SCE_OK);
|
||||
Require(threadAffinity == cpu);
|
||||
Require(ReadCpuset(thread) == cpu);
|
||||
}
|
||||
release.set_value();
|
||||
Require(scePthreadJoin(thread, nullptr) == SCE_OK);
|
||||
|
|
@ -143,4 +163,12 @@ int main() {
|
|||
hold.set_value();
|
||||
Require(scePthreadJoin(bystander, nullptr) == SCE_OK);
|
||||
Require(scePthreadAttrDestroy(&attr) == SCE_OK);
|
||||
|
||||
Require(ReadCpuset(pthread_self_nid_postfix()) == available);
|
||||
std::uint8_t rawSet[GUEST_CPUSET_BYTES]{};
|
||||
for (const std::size_t size : {std::size_t{0}, std::size_t{8}, std::size_t{31}, std::size_t{33}, std::size_t{64}})
|
||||
Require(pthread_getaffinity_np_nid_postfix(pthread_self_nid_postfix(), size, rawSet) == GUEST_ERANGE);
|
||||
Require(pthread_getaffinity_np_nid_postfix(nullptr, GUEST_CPUSET_BYTES, rawSet) == GUEST_EINVAL);
|
||||
Require(pthread_getaffinity_np_nid_postfix(nullptr, 0, rawSet) == GUEST_EINVAL);
|
||||
Require(pthread_getaffinity_np_nid_postfix(pthread_self_nid_postfix(), GUEST_CPUSET_BYTES, nullptr) == GUEST_EFAULT);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue