From 2500080773ca1154b3806c8284dacf8c72fc8c7e Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 7 Jun 2024 09:15:34 +0300 Subject: [PATCH] implemented part of rwlock functions (WIP) --- src/core/libraries/error_codes.h | 1 + src/core/libraries/kernel/thread_management.h | 22 ++++ .../libraries/kernel/threads/kernel_threads.h | 20 ++-- .../kernel/threads/kernel_threads_rwlock.cpp | 103 +++++++++++++----- 4 files changed, 108 insertions(+), 38 deletions(-) diff --git a/src/core/libraries/error_codes.h b/src/core/libraries/error_codes.h index 42731de2..d4ae7edc 100644 --- a/src/core/libraries/error_codes.h +++ b/src/core/libraries/error_codes.h @@ -251,6 +251,7 @@ constexpr int ORBIS_OK = 0x00000000; constexpr int ORBIS_FAIL = 0xFFFFFFFF; // Libkernel library +constexpr int ORBIS_KERNEL_ERROR_UNKNOWN = 0x80020000; constexpr int ORBIS_KERNEL_ERROR_EPERM = 0x80020001; constexpr int ORBIS_KERNEL_ERROR_ENOENT = 0x80020002; constexpr int ORBIS_KERNEL_ERROR_ESRCH = 0x80020003; diff --git a/src/core/libraries/kernel/thread_management.h b/src/core/libraries/kernel/thread_management.h index b086a7e4..0b14777e 100644 --- a/src/core/libraries/kernel/thread_management.h +++ b/src/core/libraries/kernel/thread_management.h @@ -23,6 +23,8 @@ struct PthreadMutexInternal; struct PthreadMutexattrInternal; struct PthreadCondInternal; struct PthreadCondAttrInternal; +struct PthreadRwInternal; +struct PthreadRwLockAttrInernal; using SceKernelSchedParam = ::sched_param; using ScePthread = PthreadInternal*; @@ -31,6 +33,8 @@ using ScePthreadMutex = PthreadMutexInternal*; using ScePthreadMutexattr = PthreadMutexattrInternal*; using ScePthreadCond = PthreadCondInternal*; using ScePthreadCondattr = PthreadCondAttrInternal*; +using OrbisPthreadRwlock = PthreadRwInternal*; +using OrbisPthreadRwlockattr = PthreadRwLockAttrInernal*; using pthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*); @@ -84,6 +88,17 @@ struct PthreadCondAttrInternal { pthread_condattr_t cond_attr; }; +struct PthreadRwLockAttrInernal { + u8 reserved[64]; + pthread_rwlockattr_t attr_rwlock; + int type; +}; + +struct PthreadRwInternal { + pthread_rwlock_t pth_rwlock; + std::string name; +}; + class PThreadPool { public: ScePthread Create(); @@ -119,12 +134,19 @@ public: void SetPthreadPool(PThreadPool* pool) { m_pthread_pool = pool; } + OrbisPthreadRwlockattr* getDefaultRwattr() { + return &m_default_Rwattr; + } + void setDefaultRwattr(OrbisPthreadRwlockattr attr) { + m_default_Rwattr = attr; + } private: ScePthreadMutexattr m_default_mutexattr = nullptr; ScePthreadCondattr m_default_condattr = nullptr; ScePthreadAttr m_default_attr = nullptr; PThreadPool* m_pthread_pool = nullptr; + OrbisPthreadRwlockattr m_default_Rwattr = nullptr; }; void init_pthreads(); diff --git a/src/core/libraries/kernel/threads/kernel_threads.h b/src/core/libraries/kernel/threads/kernel_threads.h index 24d60133..26c55e4b 100644 --- a/src/core/libraries/kernel/threads/kernel_threads.h +++ b/src/core/libraries/kernel/threads/kernel_threads.h @@ -21,10 +21,10 @@ int PS4_SYSV_ABI posix_pthread_rwlock_reltimedwrlock_np(); int PS4_SYSV_ABI posix_pthread_rwlock_setname_np(); int PS4_SYSV_ABI posix_pthread_rwlock_timedrdlock(); int PS4_SYSV_ABI posix_pthread_rwlock_timedwrlock(); -int PS4_SYSV_ABI posix_pthread_rwlock_tryrdlock(); -int PS4_SYSV_ABI posix_pthread_rwlock_trywrlock(); -int PS4_SYSV_ABI posix_pthread_rwlock_unlock(); -int PS4_SYSV_ABI posix_pthread_rwlock_wrlock(); +int PS4_SYSV_ABI posix_pthread_rwlock_tryrdlock(OrbisPthreadRwlock* rwlock); +int PS4_SYSV_ABI posix_pthread_rwlock_trywrlock(OrbisPthreadRwlock* rwlock); +int PS4_SYSV_ABI posix_pthread_rwlock_unlock(OrbisPthreadRwlock* rwlock); +int PS4_SYSV_ABI posix_pthread_rwlock_wrlock(OrbisPthreadRwlock* rwlock); int PS4_SYSV_ABI posix_pthread_rwlockattr_destroy(); int PS4_SYSV_ABI posix_pthread_rwlockattr_getpshared(); int PS4_SYSV_ABI posix_pthread_rwlockattr_gettype_np(); @@ -37,15 +37,15 @@ int PS4_SYSV_ABI scePthreadRwlockattrGettype(); int PS4_SYSV_ABI scePthreadRwlockattrInit(); int PS4_SYSV_ABI scePthreadRwlockattrSetpshared(); int PS4_SYSV_ABI scePthreadRwlockattrSettype(); -int PS4_SYSV_ABI scePthreadRwlockDestroy(); +int PS4_SYSV_ABI scePthreadRwlockDestroy(OrbisPthreadRwlock* rwlock); int PS4_SYSV_ABI scePthreadRwlockInit(); -int PS4_SYSV_ABI scePthreadRwlockRdlock(); +int PS4_SYSV_ABI scePthreadRwlockRdlock(OrbisPthreadRwlock* rwlock); int PS4_SYSV_ABI scePthreadRwlockTimedrdlock(); int PS4_SYSV_ABI scePthreadRwlockTimedwrlock(); -int PS4_SYSV_ABI scePthreadRwlockTryrdlock(); -int PS4_SYSV_ABI scePthreadRwlockTrywrlock(); -int PS4_SYSV_ABI scePthreadRwlockUnlock(); -int PS4_SYSV_ABI scePthreadRwlockWrlock(); +int PS4_SYSV_ABI scePthreadRwlockTryrdlock(OrbisPthreadRwlock* rwlock); +int PS4_SYSV_ABI scePthreadRwlockTrywrlock(OrbisPthreadRwlock* rwlock); +int PS4_SYSV_ABI scePthreadRwlockUnlock(OrbisPthreadRwlock* rwlock); +int PS4_SYSV_ABI scePthreadRwlockWrlock(OrbisPthreadRwlock* rwlock); 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_rwlock.cpp b/src/core/libraries/kernel/threads/kernel_threads_rwlock.cpp index d5e81a1d..89c4ccdb 100644 --- a/src/core/libraries/kernel/threads/kernel_threads_rwlock.cpp +++ b/src/core/libraries/kernel/threads/kernel_threads_rwlock.cpp @@ -48,24 +48,36 @@ int PS4_SYSV_ABI posix_pthread_rwlock_timedwrlock() { return ORBIS_OK; } -int PS4_SYSV_ABI posix_pthread_rwlock_tryrdlock() { - LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI posix_pthread_rwlock_tryrdlock(OrbisPthreadRwlock* rwlock) { + int result = pthread_rwlock_tryrdlock(&(*rwlock)->pth_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_rwlock_tryrdlock: error = {}", result); + } + return result; } -int PS4_SYSV_ABI posix_pthread_rwlock_trywrlock() { - LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI posix_pthread_rwlock_trywrlock(OrbisPthreadRwlock* rwlock) { + int result = pthread_rwlock_trywrlock(&(*rwlock)->pth_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_rwlock_trywrlock: error = {}", result); + } + return result; } -int PS4_SYSV_ABI posix_pthread_rwlock_unlock() { - LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI posix_pthread_rwlock_unlock(OrbisPthreadRwlock* rwlock) { + int result = pthread_rwlock_unlock(&(*rwlock)->pth_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_rwlock_unlock: error = {}", result); + } + return result; } -int PS4_SYSV_ABI posix_pthread_rwlock_wrlock() { - LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI posix_pthread_rwlock_wrlock(OrbisPthreadRwlock* rwlock) { + int result = pthread_rwlock_wrlock(&(*rwlock)->pth_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadRwlockWrlock: error = {}", result); + } + return result; } int PS4_SYSV_ABI posix_pthread_rwlockattr_destroy() { @@ -128,7 +140,7 @@ int PS4_SYSV_ABI scePthreadRwlockattrSettype() { return ORBIS_OK; } -int PS4_SYSV_ABI scePthreadRwlockDestroy() { +int PS4_SYSV_ABI scePthreadRwlockDestroy(OrbisPthreadRwlock* rwlock) { LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); return ORBIS_OK; } @@ -138,9 +150,16 @@ int PS4_SYSV_ABI scePthreadRwlockInit() { return ORBIS_OK; } -int PS4_SYSV_ABI scePthreadRwlockRdlock() { - LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI scePthreadRwlockRdlock(OrbisPthreadRwlock* rwlock) { + if (rwlock == nullptr || *rwlock == nullptr) { + return SCE_KERNEL_ERROR_EINVAL; + } + int result = pthread_rwlock_rdlock(&(*rwlock)->pth_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadRwlockRdlock: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; } int PS4_SYSV_ABI scePthreadRwlockTimedrdlock() { @@ -153,24 +172,52 @@ int PS4_SYSV_ABI scePthreadRwlockTimedwrlock() { return ORBIS_OK; } -int PS4_SYSV_ABI scePthreadRwlockTryrdlock() { - LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI scePthreadRwlockTryrdlock(OrbisPthreadRwlock* rwlock) { + if (rwlock == nullptr || *rwlock == nullptr) { + return SCE_KERNEL_ERROR_EINVAL; + } + int result = pthread_rwlock_tryrdlock(&(*rwlock)->pth_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadRwlockTryrdlock: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; } -int PS4_SYSV_ABI scePthreadRwlockTrywrlock() { - LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI scePthreadRwlockTrywrlock(OrbisPthreadRwlock* rwlock) { + if (rwlock == nullptr || *rwlock == nullptr) { + return SCE_KERNEL_ERROR_EINVAL; + } + int result = pthread_rwlock_trywrlock(&(*rwlock)->pth_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadRwlockTrywrlock: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; } -int PS4_SYSV_ABI scePthreadRwlockUnlock() { - LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI scePthreadRwlockUnlock(OrbisPthreadRwlock* rwlock) { + if (rwlock == nullptr || *rwlock == nullptr) { + return SCE_KERNEL_ERROR_EINVAL; + } + int result = pthread_rwlock_unlock(&(*rwlock)->pth_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadRwlockUnlock: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; } -int PS4_SYSV_ABI scePthreadRwlockWrlock() { - LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI scePthreadRwlockWrlock(OrbisPthreadRwlock* rwlock) { + if (rwlock == nullptr || *rwlock == nullptr) { + return SCE_KERNEL_ERROR_EINVAL; + } + int result = pthread_rwlock_wrlock(&(*rwlock)->pth_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadRwlockWrlock: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; } void ThreadsRwlockSymbolsRegister(Core::Loader::SymbolsResolver* sym) {