mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 08:33:12 -05:00
scePthreadAttrGet wrote priority 700 and left the affinity of the destination untouched, whatever the thread was created with or set to afterwards. It now reports the values the thread holds, as pthread_attr_get_np already does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
102 lines
4.4 KiB
C++
102 lines
4.4 KiB
C++
#include "SceTypes.hpp"
|
|
#include <cstddef>
|
|
#include <cstdlib>
|
|
#include <future>
|
|
|
|
extern "C" {
|
|
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 scePthreadSetprio(Pthread thread, int prio);
|
|
int APS5_VABI scePthreadSetaffinity(Pthread thread, KernelCpumask mask);
|
|
int APS5_VABI scePthreadAttrInit(PthreadAttr* attr);
|
|
int APS5_VABI scePthreadAttrDestroy(PthreadAttr* attr);
|
|
int APS5_VABI scePthreadAttrGet(Pthread thread, PthreadAttr* attr);
|
|
int APS5_VABI scePthreadAttrSetinheritsched(PthreadAttr* attr, int inheritSched);
|
|
int APS5_VABI scePthreadAttrSetschedparam(PthreadAttr* attr, const KernelSchedParam* param);
|
|
int APS5_VABI scePthreadAttrSetaffinity(PthreadAttr* attr, KernelCpumask mask);
|
|
int APS5_VABI scePthreadAttrSetstacksize(PthreadAttr* attr, std::size_t stackSize);
|
|
int APS5_VABI scePthreadAttrGetschedparam(const PthreadAttr* attr, KernelSchedParam* param);
|
|
int APS5_VABI scePthreadAttrGetaffinity(const PthreadAttr* attr, KernelCpumask* mask);
|
|
int APS5_VABI scePthreadAttrGetstacksize(const PthreadAttr* attr, std::size_t* stackSize);
|
|
int APS5_VABI scePthreadAttrGetdetachstate(const PthreadAttr* attr, int* state);
|
|
}
|
|
|
|
static constexpr int SCE_OK = 0;
|
|
static constexpr int SCE_KERNEL_ERROR_EINVAL = static_cast<int>(0x80020016);
|
|
static constexpr int EXPLICIT_SCHED = 0;
|
|
static constexpr int DETACH_JOINABLE = 0;
|
|
static constexpr int CREATION_PRIORITY = 256;
|
|
static constexpr int UPDATED_PRIORITY = 767;
|
|
static constexpr KernelCpumask CREATION_AFFINITY = 0x3;
|
|
static constexpr KernelCpumask UPDATED_AFFINITY = 0x1000;
|
|
static constexpr std::size_t STACK_SIZE = 2u << 20;
|
|
|
|
static void Require(bool value) { if (!value) std::abort(); }
|
|
|
|
struct ReportedAttributes {
|
|
int priority = 0;
|
|
KernelCpumask affinity = 0;
|
|
std::size_t stackSize = 0;
|
|
int detachState = -1;
|
|
};
|
|
|
|
static ReportedAttributes Query(Pthread thread) {
|
|
PthreadAttr attr = nullptr;
|
|
Require(scePthreadAttrInit(&attr) == SCE_OK);
|
|
Require(scePthreadAttrGet(thread, &attr) == SCE_OK);
|
|
ReportedAttributes reported;
|
|
KernelSchedParam param{};
|
|
Require(scePthreadAttrGetschedparam(&attr, ¶m) == SCE_OK);
|
|
reported.priority = param.sched_priority;
|
|
Require(scePthreadAttrGetaffinity(&attr, &reported.affinity) == SCE_OK);
|
|
Require(scePthreadAttrGetstacksize(&attr, &reported.stackSize) == SCE_OK);
|
|
Require(scePthreadAttrGetdetachstate(&attr, &reported.detachState) == SCE_OK);
|
|
Require(scePthreadAttrDestroy(&attr) == SCE_OK);
|
|
return reported;
|
|
}
|
|
|
|
static void* APS5_VABI Worker(void* arg) {
|
|
static_cast<std::future<void>*>(arg)->get();
|
|
return nullptr;
|
|
}
|
|
|
|
int main() {
|
|
PthreadAttr attr = nullptr;
|
|
Require(scePthreadAttrInit(&attr) == SCE_OK);
|
|
Require(scePthreadAttrSetinheritsched(&attr, EXPLICIT_SCHED) == SCE_OK);
|
|
const KernelSchedParam requested{CREATION_PRIORITY};
|
|
Require(scePthreadAttrSetschedparam(&attr, &requested) == SCE_OK);
|
|
Require(scePthreadAttrSetaffinity(&attr, CREATION_AFFINITY) == SCE_OK);
|
|
Require(scePthreadAttrSetstacksize(&attr, STACK_SIZE) == SCE_OK);
|
|
|
|
std::promise<void> release;
|
|
auto released = release.get_future();
|
|
Pthread thread = nullptr;
|
|
Require(scePthreadCreate(&thread, &attr, Worker, &released, nullptr) == SCE_OK);
|
|
Require(scePthreadAttrDestroy(&attr) == SCE_OK);
|
|
|
|
auto reported = Query(thread);
|
|
Require(reported.priority == CREATION_PRIORITY);
|
|
Require(reported.affinity == CREATION_AFFINITY);
|
|
Require(reported.stackSize == STACK_SIZE);
|
|
Require(reported.detachState == DETACH_JOINABLE);
|
|
|
|
Require(scePthreadSetprio(thread, UPDATED_PRIORITY) == SCE_OK);
|
|
Require(scePthreadSetaffinity(thread, UPDATED_AFFINITY) == SCE_OK);
|
|
reported = Query(thread);
|
|
Require(reported.priority == UPDATED_PRIORITY);
|
|
Require(reported.affinity == UPDATED_AFFINITY);
|
|
Require(reported.stackSize == STACK_SIZE);
|
|
Require(reported.detachState == DETACH_JOINABLE);
|
|
|
|
PthreadAttr destroyed = nullptr;
|
|
Require(scePthreadAttrGet(thread, &destroyed) == SCE_KERNEL_ERROR_EINVAL);
|
|
Require(scePthreadAttrGet(thread, nullptr) == SCE_KERNEL_ERROR_EINVAL);
|
|
Require(scePthreadAttrInit(&attr) == SCE_OK);
|
|
Require(scePthreadAttrGet(nullptr, &attr) == SCE_KERNEL_ERROR_EINVAL);
|
|
Require(scePthreadAttrDestroy(&attr) == SCE_OK);
|
|
|
|
release.set_value();
|
|
Require(scePthreadJoin(thread, nullptr) == SCE_OK);
|
|
}
|