#include "SceTypes.hpp" #include #include #include extern "C" { int APS5_VABI scePthreadAttrInit(PthreadAttr* attr); int APS5_VABI scePthreadAttrDestroy(PthreadAttr* attr); int APS5_VABI scePthreadAttrSetstacksize(PthreadAttr* attr, std::size_t stackSize); int APS5_VABI scePthreadAttrGetstacksize(const PthreadAttr* attr, std::size_t* stackSize); int APS5_VABI scePthreadAttrSetdetachstate(PthreadAttr* attr, int state); int APS5_VABI scePthreadAttrGetdetachstate(const PthreadAttr* attr, int* state); int APS5_VABI scePthreadAttrSetschedpolicy(PthreadAttr* attr, int policy); int APS5_VABI scePthreadAttrSetinheritsched(PthreadAttr* attr, int inheritSched); int APS5_VABI scePthreadAttrSetschedparam(PthreadAttr* attr, const KernelSchedParam* param); int APS5_VABI scePthreadAttrGetschedparam(const PthreadAttr* attr, KernelSchedParam* param); int APS5_VABI scePthreadAttrSetaffinity(PthreadAttr* attr, KernelCpumask mask); int APS5_VABI scePthreadAttrGetaffinity(const PthreadAttr* attr, KernelCpumask* mask); } static constexpr int SCE_OK = 0; static constexpr int SCE_KERNEL_ERROR_EINVAL = static_cast(0x80020016u); static constexpr int SCE_KERNEL_ERROR_EOPNOTSUPP = static_cast(0x8002002Du); static void Require(bool value) { if (!value) std::abort(); } int main() { PthreadAttr attr = nullptr; Require(scePthreadAttrInit(&attr) == SCE_OK); for (std::size_t size : {std::size_t{0}, std::size_t{1}, std::size_t{16383}}) Require(scePthreadAttrSetstacksize(&attr, size) == SCE_KERNEL_ERROR_EINVAL); Require(scePthreadAttrSetstacksize(&attr, 16384) == SCE_OK); for (int state : {-1, 2, 3, 100}) Require(scePthreadAttrSetdetachstate(&attr, state) == SCE_KERNEL_ERROR_EINVAL); for (int state : {0, 1}) Require(scePthreadAttrSetdetachstate(&attr, state) == SCE_OK); for (int policy : {-1, 0, 2, 4}) Require(scePthreadAttrSetschedpolicy(&attr, policy) == SCE_KERNEL_ERROR_EOPNOTSUPP); for (int policy : {1, 3}) Require(scePthreadAttrSetschedpolicy(&attr, policy) == SCE_OK); for (int inherit : {-1, 1, 2, 8}) Require(scePthreadAttrSetinheritsched(&attr, inherit) == SCE_KERNEL_ERROR_EOPNOTSUPP); for (int inherit : {0, 4}) Require(scePthreadAttrSetinheritsched(&attr, inherit) == SCE_OK); KernelSchedParam param{}; for (int priority : {-1, 0, 255, 768, 900, 960}) { param.sched_priority = priority; Require(scePthreadAttrSetschedparam(&attr, ¶m) == SCE_KERNEL_ERROR_EOPNOTSUPP); } Require(scePthreadAttrSetschedparam(&attr, nullptr) == SCE_KERNEL_ERROR_EOPNOTSUPP); for (int priority : {256, 767}) { param.sched_priority = priority; Require(scePthreadAttrSetschedparam(&attr, ¶m) == SCE_OK); KernelSchedParam read{}; Require(scePthreadAttrGetschedparam(&attr, &read) == SCE_OK && read.sched_priority == priority); } for (KernelCpumask mask : {KernelCpumask{0}, KernelCpumask{1}, ~KernelCpumask{0}}) Require(scePthreadAttrSetaffinity(&attr, mask) == SCE_OK); std::size_t size = 0; int state = 0; KernelCpumask mask = 0; Require(scePthreadAttrGetstacksize(&attr, nullptr) == SCE_KERNEL_ERROR_EINVAL); Require(scePthreadAttrGetdetachstate(&attr, nullptr) == SCE_KERNEL_ERROR_EINVAL); Require(scePthreadAttrGetschedparam(&attr, nullptr) == SCE_KERNEL_ERROR_EINVAL); for (PthreadAttr* missing : {static_cast(nullptr), static_cast(&attr)}) { PthreadAttr unset = nullptr; PthreadAttr* target = missing ? &unset : nullptr; Require(scePthreadAttrSetstacksize(target, 16384) == SCE_KERNEL_ERROR_EINVAL); Require(scePthreadAttrSetdetachstate(target, 0) == SCE_KERNEL_ERROR_EINVAL); Require(scePthreadAttrSetschedpolicy(target, 1) == SCE_KERNEL_ERROR_EINVAL); Require(scePthreadAttrSetinheritsched(target, 0) == SCE_KERNEL_ERROR_EINVAL); param.sched_priority = 700; Require(scePthreadAttrSetschedparam(target, ¶m) == SCE_KERNEL_ERROR_EINVAL); Require(scePthreadAttrSetaffinity(target, 1) == SCE_KERNEL_ERROR_EINVAL); Require(scePthreadAttrGetstacksize(target, &size) == SCE_KERNEL_ERROR_EINVAL); Require(scePthreadAttrGetdetachstate(target, &state) == SCE_KERNEL_ERROR_EINVAL); Require(scePthreadAttrGetschedparam(target, ¶m) == SCE_KERNEL_ERROR_EINVAL); Require(scePthreadAttrGetaffinity(target, &mask) == SCE_KERNEL_ERROR_EINVAL); Require(scePthreadAttrDestroy(target) == SCE_KERNEL_ERROR_EINVAL); } Require(scePthreadAttrDestroy(&attr) == SCE_OK); Require(scePthreadAttrDestroy(&attr) == SCE_KERNEL_ERROR_EINVAL); }