From e0cb7f3475422e15b25fcdbee9456099cc1acde1 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Wed, 4 Oct 2023 09:01:40 +0300 Subject: [PATCH] scePthreadCondInit,scePthreadCondattrInit,scePthreadCondBroadcast --- src/Core/PS4/HLE/Kernel/ThreadManagement.cpp | 61 ++++++++++++++++++++ src/Core/PS4/HLE/Kernel/ThreadManagement.h | 21 ++++++- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/Core/PS4/HLE/Kernel/ThreadManagement.cpp b/src/Core/PS4/HLE/Kernel/ThreadManagement.cpp index 682959309..36e20d460 100644 --- a/src/Core/PS4/HLE/Kernel/ThreadManagement.cpp +++ b/src/Core/PS4/HLE/Kernel/ThreadManagement.cpp @@ -225,4 +225,65 @@ int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex) { default: return SCE_KERNEL_ERROR_EINVAL; } } + +int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr) { + + *attr = new PthreadCondAttrInternal{}; + + int result = pthread_condattr_init(&(*attr)->cond_attr); + + switch (result) { + case 0: return SCE_OK; + case ENOMEM: return SCE_KERNEL_ERROR_ENOMEM; + default: return SCE_KERNEL_ERROR_EINVAL; + } +} + +int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondattr* attr, const char* name) { + if (cond == nullptr) { + return SCE_KERNEL_ERROR_EINVAL; + } + + if (attr == nullptr) { + ScePthreadCondattr condattr = nullptr; + scePthreadCondattrInit(&condattr); + attr = &condattr; + } + + *cond = new PthreadCondInternal{}; + + (*cond)->name = name; + + int result = pthread_cond_init(&(*cond)->cond, &(*attr)->cond_attr); + + printf("cond init: %s, %d\n", (*cond)->name.c_str(), result); + + switch (result) { + case 0: return SCE_OK; + case EAGAIN: return SCE_KERNEL_ERROR_EAGAIN; + case EINVAL: return SCE_KERNEL_ERROR_EINVAL; + case ENOMEM: return SCE_KERNEL_ERROR_ENOMEM; + default: return SCE_KERNEL_ERROR_EINVAL; + } +} +int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond) { + + static int count = 0; + std::string name = "internal cond "; + name += std::to_string(count); + count++; + // we assume we need one cond so init one (we don't even check if it exists TODO) + scePthreadCondInit(cond, nullptr, name.c_str()); + + if (cond == nullptr) { + return SCE_KERNEL_ERROR_EINVAL; + } + + int result = pthread_cond_broadcast(&(*cond)->cond); + + printf("cond broadcast: %s, %d\n", (*cond)->name.c_str(), result); + + return (result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL); +} + }; // namespace HLE::Libs::LibKernel::ThreadManagement \ No newline at end of file diff --git a/src/Core/PS4/HLE/Kernel/ThreadManagement.h b/src/Core/PS4/HLE/Kernel/ThreadManagement.h index bd71967ce..2faa2eb61 100644 --- a/src/Core/PS4/HLE/Kernel/ThreadManagement.h +++ b/src/Core/PS4/HLE/Kernel/ThreadManagement.h @@ -1,8 +1,8 @@ #pragma once #define _TIMESPEC_DEFINED -#include #include #include +#include #include @@ -11,11 +11,15 @@ namespace HLE::Libs::LibKernel::ThreadManagement { struct PthreadAttrInternal; struct PthreadMutexInternal; struct PthreadMutexAttrInternal; +struct PthreadCondAttrInternal; +struct PthreadCondInternal; using SceKernelSchedParam = ::sched_param; using ScePthreadAttr = PthreadAttrInternal*; using ScePthreadMutex = PthreadMutexInternal*; using ScePthreadMutexattr = PthreadMutexAttrInternal*; +using ScePthreadCondattr = PthreadCondAttrInternal*; +using ScePthreadCond = PthreadCondInternal*; struct PthreadInternal { u08 reserved[4096]; @@ -32,7 +36,6 @@ struct PthreadAttrInternal { pthread_attr_t pth_attr; }; - struct PthreadMutexAttrInternal { u08 reserved[64]; pthread_mutexattr_t mutex_attr; @@ -45,6 +48,17 @@ struct PthreadMutexInternal { pthread_mutex_t mutex; }; +struct PthreadCondAttrInternal { + u08 reserved[64]; + pthread_condattr_t cond_attr; +}; + +struct PthreadCondInternal { + u08 reserved[256]; + std::string name; + pthread_cond_t cond; +}; + class PThreadCxt {}; void Pthread_Init_Self_MainThread(); @@ -61,4 +75,7 @@ int PS4_SYSV_ABI scePthreadMutexattrSettype(ScePthreadMutexattr* attr, int type) int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int protocol); int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr, const char* name); int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex); +int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr); +int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond); +int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondattr* attr, const char* name); } // namespace HLE::Libs::LibKernel::ThreadManagement \ No newline at end of file