somehow working scePthreadCreate

This commit is contained in:
georgemoralis 2024-04-04 19:16:10 +03:00
parent c832e3831a
commit 121759d836
2 changed files with 134 additions and 6 deletions

View File

@ -6,6 +6,7 @@
#include "core/hle/error_codes.h"
#include "core/hle/libraries/libkernel/thread_management.h"
#include "core/hle/libraries/libs.h"
#include <mutex>
namespace Core::Libraries::LibKernel {
@ -22,6 +23,12 @@ void init_pthreads() {
ScePthreadCondattr default_condattr = nullptr;
scePthreadCondattrInit(&default_condattr);
g_pthread_cxt->setDefaultCondattr(default_condattr);
// default attr init
ScePthreadAttr default_attr = nullptr;
scePthreadAttrInit(&default_attr);
g_pthread_cxt->SetDefaultAttr(default_attr);
g_pthread_cxt->SetPthreadPool(new PThreadPool);
}
void pthreadInitSelfMainThread() {
@ -348,12 +355,6 @@ int PS4_SYSV_ABI scePthreadSetaffinity(ScePthread thread, const /*SceKernelCpuma
return result;
}
int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr,
pthreadEntryFunc start_routine, void* arg, const char* name) {
LOG_INFO(Kernel_Pthread, "(STUBBED) called");
return 0;
}
void* createMutex(void* addr) {
if (addr == nullptr || *static_cast<ScePthreadMutex*>(addr) != nullptr) {
return addr;
@ -754,6 +755,100 @@ int PS4_SYSV_ABI scePthreadAttrGet(ScePthread thread, ScePthreadAttr* attr) {
return pthread_copy_attributes(attr, &thread->attr);
}
static void cleanup_thread(void* arg) {
auto* thread = static_cast<ScePthread>(arg);
thread->is_almost_done = true;
}
static void* run_thread(void* arg) {
auto* thread = static_cast<ScePthread>(arg);
void* ret = nullptr;
g_pthread_self = thread;
pthread_cleanup_push(cleanup_thread, thread);
thread->is_started = true;
ret = thread->entry(thread->arg);
pthread_cleanup_pop(1);
return ret;
}
int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr,
pthreadEntryFunc start_routine, void* arg, const char* name) {
if (thread == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
auto* pthread_pool = g_pthread_cxt->GetPthreadPool();
if (attr == nullptr) {
attr = g_pthread_cxt->GetDefaultAttr();
}
*thread = pthread_pool->Create();
if ((*thread)->attr != nullptr) {
scePthreadAttrDestroy(&(*thread)->attr);
}
scePthreadAttrInit(&(*thread)->attr);
int result = pthread_copy_attributes(&(*thread)->attr, attr);
if (result == 0) {
(*thread)->name = name;
(*thread)->entry = start_routine;
(*thread)->arg = arg;
(*thread)->is_almost_done = false;
(*thread)->is_detached = (*attr)->detached;
(*thread)->is_started = false;
result = pthread_create(&(*thread)->pth, &(*attr)->pth_attr, run_thread, *thread);
}
if (result == 0) {
while (!(*thread)->is_started) {
std::this_thread::sleep_for(std::chrono::microseconds(1000));
}
}
LOG_INFO(Kernel_Pthread, "thread create name = {}",(*thread)->name);
switch (result) {
case 0:
return SCE_OK;
case ENOMEM:
return SCE_KERNEL_ERROR_ENOMEM;
case EAGAIN:
return SCE_KERNEL_ERROR_EAGAIN;
case EDEADLK:
return SCE_KERNEL_ERROR_EDEADLK;
case EPERM:
return SCE_KERNEL_ERROR_EPERM;
default:
return SCE_KERNEL_ERROR_EINVAL;
}
}
ScePthread PThreadPool::Create() {
std::scoped_lock lock{m_mutex};
for (auto* p : m_threads) {
if (p->is_free) {
p->is_free = false;
return p;
}
}
auto* ret = new PthreadInternal{};
ret->is_free = false;
ret->is_detached = false;
ret->is_almost_done = false;
ret->attr = nullptr;
m_threads.push_back(ret);
return ret;
}
void pthreadSymbolsRegister(Loader::SymbolsResolver* sym) {
LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy);
LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate);

View File

@ -7,6 +7,8 @@
#include <string>
#include <pthread.h>
#include <sched.h>
#include <vector>
#include <mutex>
#include "common/types.h"
@ -43,6 +45,12 @@ struct PthreadInternal {
std::string name;
pthread_t pth;
ScePthreadAttr attr;
pthreadEntryFunc entry;
void* arg;
std::atomic_bool is_started;
std::atomic_bool is_detached;
std::atomic_bool is_almost_done;
std::atomic_bool is_free;
};
struct PthreadAttrInternal {
@ -77,6 +85,17 @@ struct PthreadCondAttrInternal {
pthread_condattr_t cond_attr;
};
class PThreadPool {
public:
ScePthread Create();
void FreeDetachedThreads();
private:
std::vector<ScePthread> m_threads;
std::mutex m_mutex;
};
class PThreadCxt {
public:
ScePthreadMutexattr* getDefaultMutexattr() {
@ -91,10 +110,24 @@ public:
void setDefaultCondattr(ScePthreadCondattr attr) {
m_default_condattr = attr;
}
ScePthreadAttr* GetDefaultAttr() {
return &m_default_attr;
}
void SetDefaultAttr(ScePthreadAttr attr) {
m_default_attr = attr;
}
PThreadPool* GetPthreadPool() {
return m_pthread_pool;
}
void SetPthreadPool(PThreadPool* pool) {
m_pthread_pool = pool;
}
private:
ScePthreadMutexattr m_default_mutexattr = nullptr;
ScePthreadCondattr m_default_condattr = nullptr;
ScePthreadAttr m_default_attr = nullptr;
PThreadPool* m_pthread_pool = nullptr;
};
void init_pthreads();