From 4c0e24b076e4b7b4eeef3f9703200a974b66f87c Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sun, 9 Jun 2024 11:39:04 +0300 Subject: [PATCH] rewrote threadCond functions --- CMakeLists.txt | 1 + .../libraries/kernel/thread_management.cpp | 236 +----------- src/core/libraries/kernel/thread_management.h | 19 +- .../libraries/kernel/threads/kernel_threads.h | 35 ++ .../kernel/threads/kernel_threads_cond.cpp | 345 ++++++++++++++++++ 5 files changed, 393 insertions(+), 243 deletions(-) create mode 100644 src/core/libraries/kernel/threads/kernel_threads_cond.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b4006dd8..5d06f316 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,6 +106,7 @@ set(KERNEL_LIB src/core/libraries/kernel/event_flag/event_flag_obj.cpp src/core/libraries/kernel/event_flag/event_flag_obj.h src/core/libraries/kernel/threads/kernel_threads.h + src/core/libraries/kernel/threads/kernel_threads_cond.cpp src/core/libraries/kernel/threads/kernel_threads_rwlock.cpp src/core/libraries/kernel/cpu_management.cpp src/core/libraries/kernel/cpu_management.h diff --git a/src/core/libraries/kernel/thread_management.cpp b/src/core/libraries/kernel/thread_management.cpp index 1de8cb1d..5a0a1287 100644 --- a/src/core/libraries/kernel/thread_management.cpp +++ b/src/core/libraries/kernel/thread_management.cpp @@ -28,13 +28,17 @@ void init_pthreads() { scePthreadMutexattrInit(&default_mutexattr); g_pthread_cxt->setDefaultMutexattr(default_mutexattr); // default cond init - ScePthreadCondattr default_condattr = nullptr; + OrbisPthreadCondattr 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); + // default rw init + OrbisPthreadRwlockattr default_rwattr = nullptr; + scePthreadRwlockattrInit(&default_rwattr); + g_pthread_cxt->setDefaultRwattr(default_rwattr); g_pthread_cxt->SetPthreadPool(new PThreadPool); } @@ -581,132 +585,6 @@ int PS4_SYSV_ABI scePthreadMutexattrDestroy(ScePthreadMutexattr* attr) { } } -void* createCond(void* addr) { - if (addr == nullptr || *static_cast(addr) != nullptr) { - return addr; - } - auto vaddr = reinterpret_cast(addr); - - std::string name = fmt::format("cond{:#x}", vaddr); - scePthreadCondInit(static_cast(addr), nullptr, name.c_str()); - return addr; -} - -int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondattr* attr, - const char* name) { - if (cond == nullptr) { - return SCE_KERNEL_ERROR_EINVAL; - } - - if (attr == nullptr) { - attr = g_pthread_cxt->getDefaultCondattr(); - } - - *cond = new PthreadCondInternal{}; - - if (name != nullptr) { - (*cond)->name = name; - } else { - (*cond)->name = "nonameCond"; - } - - int result = pthread_cond_init(&(*cond)->cond, &(*attr)->cond_attr); - - if (name != nullptr) { - LOG_INFO(Kernel_Pthread, "name={}, result={}", (*cond)->name, 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 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 scePthreadCondBroadcast(ScePthreadCond* cond) { - LOG_INFO(Kernel_Pthread, "called"); - cond = static_cast(createCond(cond)); - - if (cond == nullptr) { - return SCE_KERNEL_ERROR_EINVAL; - } - - int result = pthread_cond_broadcast(&(*cond)->cond); - - LOG_INFO(Kernel_Pthread, "name={}, result={}", (*cond)->name, result); - - return (result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL); -} - -int PS4_SYSV_ABI scePthreadCondTimedwait(ScePthreadCond* cond, ScePthreadMutex* mutex, u64 usec) { - cond = static_cast(createCond(cond)); - if (cond == nullptr) { - return SCE_KERNEL_ERROR_EINVAL; - } - if (mutex == nullptr || *mutex == nullptr) { - return SCE_KERNEL_ERROR_EINVAL; - } - timespec time{}; - time.tv_sec = usec / 1000000; - time.tv_nsec = ((usec % 1000000) * 1000); - int result = pthread_cond_timedwait(&(*cond)->cond, &(*mutex)->pth_mutex, &time); - - LOG_INFO(Kernel_Pthread, "scePthreadCondTimedwait, result={}", result); - - switch (result) { - case 0: - return SCE_OK; - case ETIMEDOUT: - return SCE_KERNEL_ERROR_ETIMEDOUT; - case EINTR: - return SCE_KERNEL_ERROR_EINTR; - case EAGAIN: - return SCE_KERNEL_ERROR_EAGAIN; - default: - return SCE_KERNEL_ERROR_EINVAL; - } -} - -int PS4_SYSV_ABI scePthreadCondDestroy(ScePthreadCond* cond) { - if (cond == nullptr) { - return SCE_KERNEL_ERROR_EINVAL; - } - int result = pthread_cond_destroy(&(*cond)->cond); - - LOG_INFO(Kernel_Pthread, "scePthreadCondDestroy, result={}", result); - - switch (result) { - case 0: - return SCE_OK; - case EBUSY: - return SCE_KERNEL_ERROR_EBUSY; - default: - return SCE_KERNEL_ERROR_EINVAL; - } -} - int PS4_SYSV_ABI posix_pthread_mutex_init(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr) { // LOG_INFO(Kernel_Pthread, "posix pthread_mutex_init redirect to scePthreadMutexInit"); int result = scePthreadMutexInit(mutex, attr, nullptr); @@ -754,27 +632,6 @@ int PS4_SYSV_ABI posix_pthread_mutex_destroy(ScePthreadMutex* mutex) { return result; } -int PS4_SYSV_ABI posix_pthread_cond_wait(ScePthreadCond* cond, ScePthreadMutex* mutex) { - int result = scePthreadCondWait(cond, mutex); - if (result < 0) { - UNREACHABLE(); - } - return result; -} - -int PS4_SYSV_ABI posix_pthread_cond_broadcast(ScePthreadCond* cond) { - LOG_INFO(Kernel_Pthread, - "posix posix_pthread_cond_broadcast redirect to scePthreadCondBroadcast"); - int result = scePthreadCondBroadcast(cond); - if (result != 0) { - int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP - ? result + -SCE_KERNEL_ERROR_UNKNOWN - : POSIX_EOTHER; - return rt; - } - return result; -} - int PS4_SYSV_ABI posix_pthread_mutexattr_init(ScePthreadMutexattr* attr) { // LOG_INFO(Kernel_Pthread, "posix pthread_mutexattr_init redirect to scePthreadMutexattrInit"); int result = scePthreadMutexattrInit(attr); @@ -1064,67 +921,6 @@ ScePthread PS4_SYSV_ABI posix_pthread_self() { return g_pthread_self; } -int PS4_SYSV_ABI scePthreadCondSignal(ScePthreadCond* cond) { - if (cond == nullptr) { - return SCE_KERNEL_ERROR_EINVAL; - } - - int result = pthread_cond_signal(&(*cond)->cond); - - LOG_INFO(Kernel_Pthread, "scePthreadCondSignal, result={}", result); - - switch (result) { - case 0: - return SCE_OK; - case EBUSY: - return SCE_KERNEL_ERROR_EBUSY; - default: - return SCE_KERNEL_ERROR_EINVAL; - } -} - -int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex) { - if (cond == nullptr || *cond == nullptr) { - // return SCE_KERNEL_ERROR_EINVAL; - cond = static_cast(createCond(cond)); // check this. Kero Blaster. - } - if (mutex == nullptr || *mutex == nullptr) { - return SCE_KERNEL_ERROR_EINVAL; - } - int result = pthread_cond_wait(&(*cond)->cond, &(*mutex)->pth_mutex); - - LOG_INFO(Kernel_Pthread, "scePthreadCondWait, result={}", result); - - switch (result) { - case 0: - return SCE_OK; - case EINTR: - return SCE_KERNEL_ERROR_EINTR; - case EAGAIN: - return SCE_KERNEL_ERROR_EAGAIN; - default: - return SCE_KERNEL_ERROR_EINVAL; - } -} - -int PS4_SYSV_ABI scePthreadCondattrDestroy(ScePthreadCondattr* attr) { - if (attr == nullptr) { - return SCE_KERNEL_ERROR_EINVAL; - } - int result = pthread_condattr_destroy(&(*attr)->cond_attr); - - LOG_INFO(Kernel_Pthread, "scePthreadCondattrDestroy: result = {} ", result); - - switch (result) { - case 0: - return SCE_OK; - case ENOMEM: - return SCE_KERNEL_ERROR_ENOMEM; - default: - return SCE_KERNEL_ERROR_EINVAL; - } -} - int PS4_SYSV_ABI scePthreadMutexTrylock(ScePthreadMutex* mutex) { if (mutex == nullptr) { @@ -1229,13 +1025,6 @@ int PS4_SYSV_ABI posix_pthread_create(ScePthread* thread, const ScePthreadAttr* return result; } -int PS4_SYSV_ABI posix_pthread_cond_init(ScePthreadCond* cond, const ScePthreadCondattr* attr) { - int result = scePthreadCondInit(cond, attr, ""); - if (result < 0) { - UNREACHABLE(); - } - return result; -} void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy); LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate); @@ -1249,7 +1038,6 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("7Xl257M4VNI", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_equal); LIB_FUNCTION("7Xl257M4VNI", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_join); LIB_FUNCTION("OxhIB8LB-PQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create); - LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init); LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSelf); LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self); @@ -1275,15 +1063,6 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("9UK1vLZQft4", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexLock); LIB_FUNCTION("tn3VlD0hG60", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexUnlock); LIB_FUNCTION("upoVrzMHFeE", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexTrylock); - // cond calls - LIB_FUNCTION("2Tb92quprl0", "libkernel", 1, "libkernel", 1, 1, scePthreadCondInit); - LIB_FUNCTION("m5-2bsNfv7s", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrInit); - LIB_FUNCTION("JGgj7Uvrl+A", "libkernel", 1, "libkernel", 1, 1, scePthreadCondBroadcast); - LIB_FUNCTION("WKAXJ4XBPQ4", "libkernel", 1, "libkernel", 1, 1, scePthreadCondWait); - LIB_FUNCTION("waPcxYiR3WA", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrDestroy); - LIB_FUNCTION("kDh-NfxgMtE", "libkernel", 1, "libkernel", 1, 1, scePthreadCondSignal); - LIB_FUNCTION("BmMjYxmew1w", "libkernel", 1, "libkernel", 1, 1, scePthreadCondTimedwait); - LIB_FUNCTION("g+PZd2hiacg", "libkernel", 1, "libkernel", 1, 1, scePthreadCondDestroy); // posix calls LIB_FUNCTION("wtkt-teR1so", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_init); @@ -1293,8 +1072,6 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("7H0iTOciTLo", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_lock); LIB_FUNCTION("2Z+PpY6CaJg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_unlock); LIB_FUNCTION("ltCfaGr2JGE", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_destroy); - LIB_FUNCTION("Op8TBGY5KHg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_wait); - LIB_FUNCTION("mkx2fVhNMsg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast); LIB_FUNCTION("dQHWEsJtoE4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutexattr_init); LIB_FUNCTION("mDmgMOGVUqg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutexattr_settype); @@ -1310,7 +1087,7 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { // openorbis weird functions LIB_FUNCTION("7H0iTOciTLo", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_lock); LIB_FUNCTION("2Z+PpY6CaJg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_unlock); - LIB_FUNCTION("mkx2fVhNMsg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast); + LIB_FUNCTION("K-jXhbt2gn4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_trylock); LIB_FUNCTION("E+tyo3lp5Lw", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_setdetachstate); @@ -1320,6 +1097,7 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("m0iS6jNsXds", "libScePosix", 1, "libkernel", 1, 1, posix_sched_get_priority_min); // libs ThreadsRwlockSymbolsRegister(sym); + ThreadsCondSymbolsRegister(sym); } } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/thread_management.h b/src/core/libraries/kernel/thread_management.h index ab97d0a4..afd8fec6 100644 --- a/src/core/libraries/kernel/thread_management.h +++ b/src/core/libraries/kernel/thread_management.h @@ -34,8 +34,8 @@ using ScePthread = PthreadInternal*; using ScePthreadAttr = PthreadAttrInternal*; using ScePthreadMutex = PthreadMutexInternal*; using ScePthreadMutexattr = PthreadMutexattrInternal*; -using ScePthreadCond = PthreadCondInternal*; -using ScePthreadCondattr = PthreadCondAttrInternal*; +using OrbisPthreadCond = PthreadCondInternal*; +using OrbisPthreadCondattr = PthreadCondAttrInternal*; using OrbisPthreadRwlock = PthreadRwInternal*; using OrbisPthreadRwlockattr = PthreadRwLockAttrInernal*; @@ -119,10 +119,10 @@ public: void setDefaultMutexattr(ScePthreadMutexattr attr) { m_default_mutexattr = attr; } - ScePthreadCondattr* getDefaultCondattr() { + OrbisPthreadCondattr* getDefaultCondattr() { return &m_default_condattr; } - void setDefaultCondattr(ScePthreadCondattr attr) { + void setDefaultCondattr(OrbisPthreadCondattr attr) { m_default_condattr = attr; } ScePthreadAttr* GetDefaultAttr() { @@ -146,7 +146,7 @@ public: private: ScePthreadMutexattr m_default_mutexattr = nullptr; - ScePthreadCondattr m_default_condattr = nullptr; + OrbisPthreadCondattr m_default_condattr = nullptr; ScePthreadAttr m_default_attr = nullptr; PThreadPool* m_pthread_pool = nullptr; OrbisPthreadRwlockattr m_default_Rwattr = nullptr; @@ -178,21 +178,12 @@ int PS4_SYSV_ABI scePthreadMutexattrSettype(ScePthreadMutexattr* attr, int type) int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int protocol); int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex); int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex); -/**** - * Cond calls - */ -int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondattr* attr, - const char* name); -int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr); -int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond); -int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex); /**** * Posix calls */ int PS4_SYSV_ABI posix_pthread_mutex_init(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr); int PS4_SYSV_ABI posix_pthread_mutex_lock(ScePthreadMutex* mutex); int PS4_SYSV_ABI posix_pthread_mutex_unlock(ScePthreadMutex* mutex); -int PS4_SYSV_ABI posix_pthread_cond_broadcast(ScePthreadCond* cond); void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads/kernel_threads.h b/src/core/libraries/kernel/threads/kernel_threads.h index a2a2eb48..013153d5 100644 --- a/src/core/libraries/kernel/threads/kernel_threads.h +++ b/src/core/libraries/kernel/threads/kernel_threads.h @@ -10,6 +10,40 @@ class SymbolsResolver; } namespace Libraries::Kernel { +/**** + * cond calls + */ +int PS4_SYSV_ABI posix_pthread_cond_broadcast(OrbisPthreadCond* cond); +int PS4_SYSV_ABI posix_pthread_cond_destroy(OrbisPthreadCond* cond); +int PS4_SYSV_ABI posix_pthread_cond_init(OrbisPthreadCond* cond, const OrbisPthreadCondattr* attr); +int PS4_SYSV_ABI posix_pthread_cond_reltimedwait_np(); +int PS4_SYSV_ABI posix_pthread_cond_setname_np(); +int PS4_SYSV_ABI posix_pthread_cond_signal(OrbisPthreadCond* cond); +int PS4_SYSV_ABI posix_pthread_cond_signalto_np(); +int PS4_SYSV_ABI posix_pthread_cond_timedwait(OrbisPthreadCond* cond, ScePthreadMutex* mutex, + u64 usec); +int PS4_SYSV_ABI posix_pthread_cond_wait(OrbisPthreadCond* cond, ScePthreadMutex* mutex); +int PS4_SYSV_ABI posix_pthread_condattr_destroy(OrbisPthreadCondattr* attr); +int PS4_SYSV_ABI posix_pthread_condattr_getclock(); +int PS4_SYSV_ABI posix_pthread_condattr_getpshared(); +int PS4_SYSV_ABI posix_pthread_condattr_init(OrbisPthreadCondattr* attr); +int PS4_SYSV_ABI posix_pthread_condattr_setclock(); +int PS4_SYSV_ABI posix_pthread_condattr_setpshared(); +int PS4_SYSV_ABI scePthreadCondattrDestroy(OrbisPthreadCondattr* attr); +int PS4_SYSV_ABI scePthreadCondattrGetclock(); +int PS4_SYSV_ABI scePthreadCondattrGetpshared(); +int PS4_SYSV_ABI scePthreadCondattrInit(OrbisPthreadCondattr* attr); +int PS4_SYSV_ABI scePthreadCondattrSetclock(); +int PS4_SYSV_ABI scePthreadCondattrSetpshared(); +int PS4_SYSV_ABI scePthreadCondBroadcast(OrbisPthreadCond* cond); +int PS4_SYSV_ABI scePthreadCondDestroy(OrbisPthreadCond* cond); +int PS4_SYSV_ABI scePthreadCondInit(OrbisPthreadCond* cond, const OrbisPthreadCondattr* attr, + const char* name); +int PS4_SYSV_ABI scePthreadCondSignal(OrbisPthreadCond* cond); +int PS4_SYSV_ABI scePthreadCondSignalto(); +int PS4_SYSV_ABI scePthreadCondTimedwait(OrbisPthreadCond* cond, ScePthreadMutex* mutex, u64 usec); +int PS4_SYSV_ABI scePthreadCondWait(OrbisPthreadCond* cond, ScePthreadMutex* mutex); + /**** * rwlock calls */ @@ -49,5 +83,6 @@ int PS4_SYSV_ABI scePthreadRwlockTrywrlock(OrbisPthreadRwlock* rwlock); int PS4_SYSV_ABI scePthreadRwlockUnlock(OrbisPthreadRwlock* rwlock); int PS4_SYSV_ABI scePthreadRwlockWrlock(OrbisPthreadRwlock* rwlock); +void ThreadsCondSymbolsRegister(Core::Loader::SymbolsResolver* sym); void ThreadsRwlockSymbolsRegister(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::Kernel \ No newline at end of file diff --git a/src/core/libraries/kernel/threads/kernel_threads_cond.cpp b/src/core/libraries/kernel/threads/kernel_threads_cond.cpp new file mode 100644 index 00000000..3bb58625 --- /dev/null +++ b/src/core/libraries/kernel/threads/kernel_threads_cond.cpp @@ -0,0 +1,345 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/log.h" +#include "core/libraries/error_codes.h" +#include "core/libraries/libs.h" +#include "kernel_threads.h" + +namespace Libraries::Kernel { + +extern PThreadCxt* g_pthread_cxt; + +void* CreatePosixCond(void* addr) { + if (addr == nullptr || *static_cast(addr) != nullptr) { + return addr; + } + posix_pthread_cond_init(static_cast(addr), nullptr); + return addr; +} + +int PS4_SYSV_ABI posix_pthread_cond_broadcast(OrbisPthreadCond* cond) { + if (*cond == nullptr) { + cond = static_cast(CreatePosixCond(cond)); + } + int result = pthread_cond_broadcast(&(*cond)->cond); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_cond_broadcast: error = {}", result); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_cond_destroy(OrbisPthreadCond* cond) { + int result = pthread_cond_destroy(&(*cond)->cond); + delete *cond; + *cond = nullptr; + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_cond_destroy: error = {}", result); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_cond_init(OrbisPthreadCond* cond, const OrbisPthreadCondattr* attr) { + *cond = new PthreadCondInternal{}; + if (attr == nullptr) { + attr = g_pthread_cxt->getDefaultCondattr(); + } + int result = pthread_cond_init(&(*cond)->cond, &(*attr)->cond_attr); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_cond_init: error = {}", result); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_cond_reltimedwait_np() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_cond_setname_np() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_cond_signal(OrbisPthreadCond* cond) { + if (*cond == nullptr) { + cond = static_cast(CreatePosixCond(cond)); + } + int result = pthread_cond_signal(&(*cond)->cond); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondSignal: error = {}", result); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_cond_signalto_np() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_cond_timedwait(OrbisPthreadCond* cond, ScePthreadMutex* mutex, + u64 usec) { + if (*cond == nullptr) { + cond = static_cast(CreatePosixCond(cond)); + } + timespec time{}; + time.tv_sec = usec / 1000000; + time.tv_nsec = ((usec % 1000000) * 1000); + int result = pthread_cond_timedwait(&(*cond)->cond, &(*mutex)->pth_mutex, &time); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_cond_timedwait: error = {}", result); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_cond_wait(OrbisPthreadCond* cond, ScePthreadMutex* mutex) { + if (*cond == nullptr) { + cond = static_cast(CreatePosixCond(cond)); + } + int result = pthread_cond_wait(&(*cond)->cond, &(*mutex)->pth_mutex); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_cond_wait: error = {}", result); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_condattr_destroy(OrbisPthreadCondattr* attr) { + int result = pthread_condattr_destroy(&(*attr)->cond_attr); + delete *attr; + *attr = nullptr; + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_condattr_destroy: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_condattr_getclock() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_condattr_getpshared() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_condattr_init(OrbisPthreadCondattr* attr) { + *attr = new PthreadCondAttrInternal{}; + int result = pthread_condattr_init(&(*attr)->cond_attr); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_condattr_init: error = {}", result); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_condattr_setclock() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_condattr_setpshared() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadCondattrDestroy(OrbisPthreadCondattr* attr) { + int result = pthread_condattr_destroy(&(*attr)->cond_attr); + delete *attr; + *attr = nullptr; + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondattrDestroy: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI scePthreadCondattrGetclock() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadCondattrGetpshared() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadCondattrInit(OrbisPthreadCondattr* attr) { + *attr = new PthreadCondAttrInternal{}; + int result = pthread_condattr_init(&(*attr)->cond_attr); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondattrInit: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI scePthreadCondattrSetclock() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadCondattrSetpshared() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadCondBroadcast(OrbisPthreadCond* cond) { + if (cond == nullptr) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondBroadcast: cond = nullptr"); + return SCE_KERNEL_ERROR_EINVAL; + } + int result = pthread_cond_broadcast(&(*cond)->cond); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondBroadcast: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI scePthreadCondDestroy(OrbisPthreadCond* cond) { + if (cond == nullptr) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondDestroy: cond = nullptr"); + return SCE_KERNEL_ERROR_EINVAL; + } + int result = pthread_cond_destroy(&(*cond)->cond); + delete *cond; + *cond = nullptr; + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondDestroy: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI scePthreadCondInit(OrbisPthreadCond* cond, const OrbisPthreadCondattr* attr, + const char* name) { + *cond = new PthreadCondInternal{}; + if (cond == nullptr || *cond == nullptr) { + return ORBIS_KERNEL_ERROR_EINVAL; + } + if (attr == nullptr) { + attr = g_pthread_cxt->getDefaultCondattr(); + } + + (*cond)->name = name; + + int result = pthread_cond_init(&(*cond)->cond, &(*attr)->cond_attr); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondInit: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI scePthreadCondSignal(OrbisPthreadCond* cond) { + if (cond == nullptr) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondSignal cond==nullptr"); + return SCE_KERNEL_ERROR_EINVAL; + } + + int result = pthread_cond_signal(&(*cond)->cond); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondSignal: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI scePthreadCondSignalto() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadCondTimedwait(OrbisPthreadCond* cond, ScePthreadMutex* mutex, u64 usec) { + if (cond == nullptr) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondTimedwait cond==nullptr"); + return SCE_KERNEL_ERROR_EINVAL; + } + if (mutex == nullptr || *mutex == nullptr) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondTimedwait mutex==nullptr"); + return SCE_KERNEL_ERROR_EINVAL; + } + timespec time{}; + time.tv_sec = usec / 1000000; + time.tv_nsec = ((usec % 1000000) * 1000); + int result = pthread_cond_timedwait(&(*cond)->cond, &(*mutex)->pth_mutex, &time); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondTimedwait: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI scePthreadCondWait(OrbisPthreadCond* cond, ScePthreadMutex* mutex) { + if (cond == nullptr) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondWait cond==nullptr"); + return SCE_KERNEL_ERROR_EINVAL; + } + if (mutex == nullptr || *mutex == nullptr) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondWait mutex==nullptr"); + return SCE_KERNEL_ERROR_EINVAL; + } + int result = pthread_cond_wait(&(*cond)->cond, &(*mutex)->pth_mutex); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadCondWait: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +void ThreadsCondSymbolsRegister(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("mkx2fVhNMsg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast); + LIB_FUNCTION("RXXqi4CtF8w", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_destroy); + LIB_FUNCTION("0TyVk4MSLt0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_init); + LIB_FUNCTION("K953PF5u6Pc", "libkernel", 1, "libkernel", 1, 1, + posix_pthread_cond_reltimedwait_np); + LIB_FUNCTION("EZ8h70dtFLg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_setname_np); + LIB_FUNCTION("2MOy+rUfuhQ", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_signal); + LIB_FUNCTION("CI6Qy73ae10", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_signalto_np); + LIB_FUNCTION("27bAgiJmOh0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_timedwait); + LIB_FUNCTION("Op8TBGY5KHg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_wait); + LIB_FUNCTION("dJcuQVn6-Iw", "libkernel", 1, "libkernel", 1, 1, posix_pthread_condattr_destroy); + LIB_FUNCTION("cTDYxTUNPhM", "libkernel", 1, "libkernel", 1, 1, posix_pthread_condattr_getclock); + LIB_FUNCTION("h0qUqSuOmC8", "libkernel", 1, "libkernel", 1, 1, + posix_pthread_condattr_getpshared); + LIB_FUNCTION("mKoTx03HRWA", "libkernel", 1, "libkernel", 1, 1, posix_pthread_condattr_init); + LIB_FUNCTION("EjllaAqAPZo", "libkernel", 1, "libkernel", 1, 1, posix_pthread_condattr_setclock); + LIB_FUNCTION("3BpP850hBT4", "libkernel", 1, "libkernel", 1, 1, + posix_pthread_condattr_setpshared); + LIB_FUNCTION("waPcxYiR3WA", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrDestroy); + LIB_FUNCTION("6qM3kO5S3Oo", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrGetclock); + LIB_FUNCTION("Dn-DRWi9t54", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrGetpshared); + LIB_FUNCTION("m5-2bsNfv7s", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrInit); + LIB_FUNCTION("c-bxj027czs", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrSetclock); + LIB_FUNCTION("6xMew9+rZwI", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrSetpshared); + LIB_FUNCTION("JGgj7Uvrl+A", "libkernel", 1, "libkernel", 1, 1, scePthreadCondBroadcast); + LIB_FUNCTION("g+PZd2hiacg", "libkernel", 1, "libkernel", 1, 1, scePthreadCondDestroy); + LIB_FUNCTION("2Tb92quprl0", "libkernel", 1, "libkernel", 1, 1, scePthreadCondInit); + LIB_FUNCTION("kDh-NfxgMtE", "libkernel", 1, "libkernel", 1, 1, scePthreadCondSignal); + LIB_FUNCTION("o69RpYO-Mu0", "libkernel", 1, "libkernel", 1, 1, scePthreadCondSignalto); + LIB_FUNCTION("BmMjYxmew1w", "libkernel", 1, "libkernel", 1, 1, scePthreadCondTimedwait); + LIB_FUNCTION("WKAXJ4XBPQ4", "libkernel", 1, "libkernel", 1, 1, scePthreadCondWait); + LIB_FUNCTION("EZ8h70dtFLg", "libkernel_psmkit", 1, "libkernel", 1, 1, + posix_pthread_cond_setname_np); + LIB_FUNCTION("mkx2fVhNMsg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast); + LIB_FUNCTION("RXXqi4CtF8w", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_destroy); + LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init); + LIB_FUNCTION("2MOy+rUfuhQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_signal); + LIB_FUNCTION("CI6Qy73ae10", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_cond_signalto_np); + LIB_FUNCTION("27bAgiJmOh0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_timedwait); + LIB_FUNCTION("Op8TBGY5KHg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_wait); + LIB_FUNCTION("dJcuQVn6-Iw", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_condattr_destroy); + LIB_FUNCTION("cTDYxTUNPhM", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_condattr_getclock); + LIB_FUNCTION("h0qUqSuOmC8", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_condattr_getpshared); + LIB_FUNCTION("mKoTx03HRWA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_condattr_init); + LIB_FUNCTION("EjllaAqAPZo", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_condattr_setclock); + LIB_FUNCTION("3BpP850hBT4", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_condattr_setpshared); +} +} // namespace Libraries::Kernel \ No newline at end of file