2023-07-18 17:54:46 +02:00
|
|
|
#include "ThreadManagement.h"
|
|
|
|
#include "../ErrorCodes.h"
|
|
|
|
|
2023-07-17 22:46:25 +02:00
|
|
|
namespace HLE::Libs::LibKernel::ThreadManagement
|
|
|
|
{
|
|
|
|
|
2023-07-18 17:54:46 +02:00
|
|
|
thread_local PthreadInternal* g_pthread_self = nullptr;
|
|
|
|
PThreadCxt* g_pthread_cxt = nullptr;
|
|
|
|
|
|
|
|
|
2023-07-20 10:20:11 +02:00
|
|
|
void Pthread_Init_Self_MainThread() {
|
|
|
|
g_pthread_self = new PthreadInternal{};
|
|
|
|
scePthreadAttrInit(&g_pthread_self->attr);
|
|
|
|
g_pthread_self->pth = pthread_self();
|
|
|
|
g_pthread_self->name = "Main_Thread";
|
|
|
|
}
|
2023-07-18 17:54:46 +02:00
|
|
|
|
|
|
|
int scePthreadAttrInit(ScePthreadAttr* attr) {
|
|
|
|
|
|
|
|
*attr = new PthreadAttrInternal{};
|
|
|
|
|
2023-07-20 10:20:11 +02:00
|
|
|
int result = pthread_attr_init(&(*attr)->pth_attr);
|
2023-07-18 17:54:46 +02:00
|
|
|
|
|
|
|
(*attr)->affinity = 0x7f;
|
|
|
|
(*attr)->guard_size = 0x1000;
|
|
|
|
|
|
|
|
SceKernelSchedParam param{};
|
|
|
|
param.sched_priority = 700;
|
|
|
|
|
|
|
|
result = (result == 0 ? scePthreadAttrSetinheritsched(attr, PTHREAD_INHERIT_SCHED) : result);
|
|
|
|
result = (result == 0 ? scePthreadAttrSetschedparam(attr, ¶m) : result);
|
|
|
|
result = (result == 0 ? scePthreadAttrSetschedpolicy(attr, SCHED_OTHER) : result);
|
|
|
|
result = (result == 0 ? scePthreadAttrSetdetachstate(attr, PTHREAD_CREATE_JOINABLE) : result);
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case 0: return SCE_OK;
|
|
|
|
case ENOMEM: return SCE_KERNEL_ERROR_ENOMEM;
|
|
|
|
default: return SCE_KERNEL_ERROR_EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int scePthreadAttrSetdetachstate(ScePthreadAttr* attr, int detachstate) {
|
|
|
|
|
|
|
|
if (attr == nullptr || *attr == nullptr) {
|
|
|
|
return SCE_KERNEL_ERROR_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int pstate = PTHREAD_CREATE_JOINABLE;
|
|
|
|
switch (detachstate) {
|
|
|
|
case 0: pstate = PTHREAD_CREATE_JOINABLE; break;
|
|
|
|
case 1: pstate = PTHREAD_CREATE_DETACHED; break;
|
|
|
|
default:
|
|
|
|
__debugbreak(); //unknown state
|
|
|
|
}
|
|
|
|
|
2023-07-20 10:20:11 +02:00
|
|
|
int result = pthread_attr_setdetachstate(&(*attr)->pth_attr, pstate);
|
2023-07-18 17:54:46 +02:00
|
|
|
|
|
|
|
(*attr)->detached = (pstate == PTHREAD_CREATE_DETACHED);
|
|
|
|
|
|
|
|
if (result == 0) {
|
|
|
|
return SCE_OK;
|
|
|
|
}
|
|
|
|
return SCE_KERNEL_ERROR_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inheritSched) {
|
|
|
|
|
|
|
|
if (attr == nullptr || *attr == nullptr) {
|
|
|
|
return SCE_KERNEL_ERROR_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int pinherit_sched = PTHREAD_INHERIT_SCHED;
|
|
|
|
switch (inheritSched) {
|
|
|
|
case 0: pinherit_sched = PTHREAD_EXPLICIT_SCHED; break;
|
|
|
|
case 4: pinherit_sched = PTHREAD_INHERIT_SCHED; break;
|
|
|
|
default: __debugbreak(); // unknown inheritSched
|
|
|
|
}
|
|
|
|
|
2023-07-20 10:20:11 +02:00
|
|
|
int result = pthread_attr_setinheritsched(&(*attr)->pth_attr, pinherit_sched);
|
2023-07-18 17:54:46 +02:00
|
|
|
|
|
|
|
if (result == 0) {
|
|
|
|
return SCE_OK;
|
|
|
|
}
|
|
|
|
return SCE_KERNEL_ERROR_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int scePthreadAttrSetschedparam(ScePthreadAttr* attr, const SceKernelSchedParam* param) {
|
|
|
|
|
|
|
|
if (param == nullptr || attr == nullptr || *attr == nullptr) {
|
|
|
|
return SCE_KERNEL_ERROR_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
SceKernelSchedParam pparam{};
|
|
|
|
if (param->sched_priority <= 478) {
|
|
|
|
pparam.sched_priority = +2;
|
|
|
|
} else if (param->sched_priority >= 733) {
|
|
|
|
pparam.sched_priority = -2;
|
|
|
|
} else {
|
|
|
|
pparam.sched_priority = 0;
|
|
|
|
}
|
|
|
|
|
2023-07-20 10:20:11 +02:00
|
|
|
int result = pthread_attr_setschedparam(&(*attr)->pth_attr, &pparam);
|
2023-07-18 17:54:46 +02:00
|
|
|
|
|
|
|
if (result == 0) {
|
|
|
|
return SCE_OK;
|
|
|
|
}
|
|
|
|
return SCE_KERNEL_ERROR_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int scePthreadAttrSetschedpolicy(ScePthreadAttr* attr, int policy) {
|
|
|
|
|
|
|
|
if (attr == nullptr || *attr == nullptr) {
|
|
|
|
return SCE_KERNEL_ERROR_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (policy!= SCHED_OTHER)
|
|
|
|
{
|
|
|
|
__debugbreak();//invest if policy is other and if winpthreadlibrary support it
|
|
|
|
}
|
|
|
|
|
|
|
|
(*attr)->policy = policy;
|
|
|
|
|
2023-07-20 10:20:11 +02:00
|
|
|
int result = pthread_attr_setschedpolicy(&(*attr)->pth_attr, policy);
|
2023-07-18 17:54:46 +02:00
|
|
|
|
|
|
|
if (result == 0) {
|
|
|
|
return SCE_OK;
|
|
|
|
}
|
|
|
|
return SCE_KERNEL_ERROR_EINVAL;
|
|
|
|
}
|
|
|
|
|
2023-07-17 22:46:25 +02:00
|
|
|
};
|