66 lines
2.4 KiB
C++
66 lines
2.4 KiB
C++
#include "SceTypes.hpp"
|
|
#include <cstdlib>
|
|
#include <future>
|
|
|
|
extern "C" {
|
|
KernelCpumask APS5_VABI sceKernelGetAvailableCpumask(void);
|
|
int APS5_VABI scePthreadCreate(Pthread* thread, const PthreadAttr* attr, PthreadEntry entry, void* arg, const char* name);
|
|
int APS5_VABI scePthreadJoin(Pthread thread, void** retval);
|
|
int APS5_VABI scePthreadGetaffinity(Pthread thread, KernelCpumask* mask);
|
|
int APS5_VABI scePthreadSetaffinity(Pthread thread, KernelCpumask mask);
|
|
int APS5_VABI scePthreadAttrInit(PthreadAttr* attr);
|
|
int APS5_VABI scePthreadAttrDestroy(PthreadAttr* attr);
|
|
int APS5_VABI scePthreadAttrGetaffinity(const PthreadAttr* attr, KernelCpumask* mask);
|
|
}
|
|
|
|
static constexpr int SCE_OK = 0;
|
|
static constexpr int PS5_LOGICAL_CPUS = 16;
|
|
|
|
static void Require(bool value) { if (!value) std::abort(); }
|
|
|
|
static void* APS5_VABI Worker(void* arg) {
|
|
static_cast<std::future<void>*>(arg)->get();
|
|
return nullptr;
|
|
}
|
|
|
|
static void* APS5_VABI ReportMask(void* arg) {
|
|
*static_cast<KernelCpumask*>(arg) = sceKernelGetAvailableCpumask();
|
|
return nullptr;
|
|
}
|
|
|
|
int main() {
|
|
const KernelCpumask available = sceKernelGetAvailableCpumask();
|
|
Require(available != 0);
|
|
Require((available >> PS5_LOGICAL_CPUS) == 0);
|
|
Require(sceKernelGetAvailableCpumask() == available);
|
|
|
|
PthreadAttr attr = nullptr;
|
|
Require(scePthreadAttrInit(&attr) == SCE_OK);
|
|
KernelCpumask defaultAffinity = 0;
|
|
Require(scePthreadAttrGetaffinity(&attr, &defaultAffinity) == SCE_OK);
|
|
Require(defaultAffinity == available);
|
|
|
|
std::promise<void> release;
|
|
auto released = release.get_future();
|
|
Pthread thread = nullptr;
|
|
Require(scePthreadCreate(&thread, &attr, Worker, &released, nullptr) == SCE_OK);
|
|
KernelCpumask threadAffinity = 0;
|
|
Require(scePthreadGetaffinity(thread, &threadAffinity) == SCE_OK);
|
|
Require(threadAffinity == available);
|
|
|
|
for (KernelCpumask cpu = 1; cpu != 0; cpu <<= 1) {
|
|
if ((available & cpu) == 0) continue;
|
|
Require(scePthreadSetaffinity(thread, cpu) == SCE_OK);
|
|
Require(scePthreadGetaffinity(thread, &threadAffinity) == SCE_OK);
|
|
Require(threadAffinity == cpu);
|
|
}
|
|
release.set_value();
|
|
Require(scePthreadJoin(thread, nullptr) == SCE_OK);
|
|
|
|
KernelCpumask fromThread = 0;
|
|
Require(scePthreadCreate(&thread, &attr, ReportMask, &fromThread, nullptr) == SCE_OK);
|
|
Require(scePthreadJoin(thread, nullptr) == SCE_OK);
|
|
Require(fromThread == available);
|
|
Require(scePthreadAttrDestroy(&attr) == SCE_OK);
|
|
}
|