From 5d24a961cb23ae102e25c2056c4d4226a0a1a6c2 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 7 Jun 2024 21:30:26 +0300 Subject: [PATCH] RWLocks implementation (#171) * added dummy rwlock * implemented part of rwlock functions (WIP) * implemented the most important functions for rwlocks --- CMakeLists.txt | 2 + src/core/libraries/error_codes.h | 1 + .../libraries/kernel/thread_management.cpp | 4 + src/core/libraries/kernel/thread_management.h | 22 ++ .../libraries/kernel/threads/kernel_threads.h | 53 +++ .../kernel/threads/kernel_threads_rwlock.cpp | 351 ++++++++++++++++++ 6 files changed, 433 insertions(+) create mode 100644 src/core/libraries/kernel/threads/kernel_threads.h create mode 100644 src/core/libraries/kernel/threads/kernel_threads_rwlock.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 357476d4..17ca8ec0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,6 +105,8 @@ set(KERNEL_LIB src/core/libraries/kernel/event_flag/event_flag.h 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_rwlock.cpp src/core/libraries/kernel/cpu_management.cpp src/core/libraries/kernel/cpu_management.h src/core/libraries/kernel/event_queue.cpp 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.cpp b/src/core/libraries/kernel/thread_management.cpp index aa51c635..be2eeaee 100644 --- a/src/core/libraries/kernel/thread_management.cpp +++ b/src/core/libraries/kernel/thread_management.cpp @@ -14,6 +14,7 @@ #ifdef _WIN64 #include #endif +#include "core/libraries/kernel/threads/kernel_threads.h" namespace Libraries::Kernel { @@ -1091,6 +1092,9 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { 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); + + // libs + ThreadsRwlockSymbolsRegister(sym); } } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/thread_management.h b/src/core/libraries/kernel/thread_management.h index b086a7e4..be45dedf 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 new file mode 100644 index 00000000..a2a2eb48 --- /dev/null +++ b/src/core/libraries/kernel/threads/kernel_threads.h @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/kernel/thread_management.h" + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::Kernel { +/**** + * rwlock calls + */ +int PS4_SYSV_ABI posix_pthread_rwlock_destroy(OrbisPthreadRwlock* rwlock); +int PS4_SYSV_ABI posix_pthread_rwlock_init(OrbisPthreadRwlock* rwlock, + const OrbisPthreadRwlockattr* attr, const char* name); +int PS4_SYSV_ABI posix_pthread_rwlock_rdlock(OrbisPthreadRwlock* rwlock); +int PS4_SYSV_ABI posix_pthread_rwlock_reltimedrdlock_np(); +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(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(OrbisPthreadRwlockattr* attr); +int PS4_SYSV_ABI posix_pthread_rwlockattr_getpshared(); +int PS4_SYSV_ABI posix_pthread_rwlockattr_gettype_np(); +int PS4_SYSV_ABI posix_pthread_rwlockattr_init(OrbisPthreadRwlockattr* attr); +int PS4_SYSV_ABI posix_pthread_rwlockattr_setpshared(); +int PS4_SYSV_ABI posix_pthread_rwlockattr_settype_np(); +int PS4_SYSV_ABI scePthreadRwlockattrDestroy(OrbisPthreadRwlockattr* attr); +int PS4_SYSV_ABI scePthreadRwlockattrGetpshared(); +int PS4_SYSV_ABI scePthreadRwlockattrGettype(); +int PS4_SYSV_ABI scePthreadRwlockattrInit(OrbisPthreadRwlockattr* attr); +int PS4_SYSV_ABI scePthreadRwlockattrSetpshared(); +int PS4_SYSV_ABI scePthreadRwlockattrSettype(); +int PS4_SYSV_ABI scePthreadRwlockDestroy(OrbisPthreadRwlock* rwlock); +int PS4_SYSV_ABI scePthreadRwlockInit(OrbisPthreadRwlock* rwlock, + const OrbisPthreadRwlockattr* attr, const char* name); +int PS4_SYSV_ABI scePthreadRwlockRdlock(OrbisPthreadRwlock* rwlock); +int PS4_SYSV_ABI scePthreadRwlockTimedrdlock(); +int PS4_SYSV_ABI scePthreadRwlockTimedwrlock(); +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 new file mode 100644 index 00000000..cbedb7cb --- /dev/null +++ b/src/core/libraries/kernel/threads/kernel_threads_rwlock.cpp @@ -0,0 +1,351 @@ +// 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; + +int PS4_SYSV_ABI posix_pthread_rwlock_destroy(OrbisPthreadRwlock* rwlock) { + int result = pthread_rwlock_destroy(&(*rwlock)->pth_rwlock); + delete *rwlock; + *rwlock = nullptr; + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_rwlock_destroy: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_rwlock_init(OrbisPthreadRwlock* rwlock, + const OrbisPthreadRwlockattr* attr, const char* name) { + *rwlock = new PthreadRwInternal{}; + if (attr == nullptr || *attr == nullptr) { + attr = g_pthread_cxt->getDefaultRwattr(); + } + int result = pthread_rwlock_init(&(*rwlock)->pth_rwlock, &(*attr)->attr_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_rwlock_init: error = {}", result); + } + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_rwlock_rdlock(OrbisPthreadRwlock* rwlock) { + int result = pthread_rwlock_rdlock(&(*rwlock)->pth_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_rwlock_rdlock: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_rwlock_reltimedrdlock_np() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_rwlock_reltimedwrlock_np() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_rwlock_setname_np() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_rwlock_timedrdlock() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_rwlock_timedwrlock() { + 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(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(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(OrbisPthreadRwlock* rwlock) { + int result = pthread_rwlock_wrlock(&(*rwlock)->pth_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_rwlock_wrlock: error = {}", result); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_rwlockattr_destroy(OrbisPthreadRwlockattr* attr) { + int result = pthread_rwlockattr_destroy(&(*attr)->attr_rwlock); + delete *attr; + *attr = nullptr; + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_rwlockattr_destroy: error = {}", result); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_rwlockattr_getpshared() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_rwlockattr_gettype_np() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_rwlockattr_init(OrbisPthreadRwlockattr* attr) { + *attr = new PthreadRwLockAttrInernal{}; + int result = pthread_rwlockattr_init(&(*attr)->attr_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "posix_pthread_rwlockattr_init: error = {}", result); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_rwlockattr_setpshared() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_rwlockattr_settype_np() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadRwlockattrDestroy(OrbisPthreadRwlockattr* attr) { + int result = pthread_rwlockattr_destroy(&(*attr)->attr_rwlock); + delete *attr; + *attr = nullptr; + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadRwlockattrDestroy: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI scePthreadRwlockattrGetpshared() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadRwlockattrGettype() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadRwlockattrInit(OrbisPthreadRwlockattr* attr) { + *attr = new PthreadRwLockAttrInernal{}; + int result = pthread_rwlockattr_init(&(*attr)->attr_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadRwlockattrInit: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI scePthreadRwlockattrSetpshared() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadRwlockattrSettype() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadRwlockDestroy(OrbisPthreadRwlock* rwlock) { + int result = pthread_rwlock_destroy(&(*rwlock)->pth_rwlock); + delete *rwlock; + *rwlock = nullptr; + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadRwlockDestroy: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return result; +} + +int PS4_SYSV_ABI scePthreadRwlockInit(OrbisPthreadRwlock* rwlock, + const OrbisPthreadRwlockattr* attr, const char* name) { + *rwlock = new PthreadRwInternal{}; + if (rwlock == nullptr || *rwlock == nullptr) { + return ORBIS_KERNEL_ERROR_EINVAL; + } + + if (attr == nullptr || *attr == nullptr) { + attr = g_pthread_cxt->getDefaultRwattr(); + } + (*rwlock)->name = name; + int result = pthread_rwlock_init(&(*rwlock)->pth_rwlock, &(*attr)->attr_rwlock); + if (result != 0) { + LOG_ERROR(Kernel_Pthread, "scePthreadRwlockInit: error = {}", result); + result += ORBIS_KERNEL_ERROR_UNKNOWN; + } + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadRwlockRdlock(OrbisPthreadRwlock* rwlock) { + if (rwlock == nullptr || *rwlock == nullptr) { + return ORBIS_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() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadRwlockTimedwrlock() { + LOG_ERROR(Kernel_Pthread, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI scePthreadRwlockTryrdlock(OrbisPthreadRwlock* rwlock) { + if (rwlock == nullptr || *rwlock == nullptr) { + return ORBIS_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(OrbisPthreadRwlock* rwlock) { + if (rwlock == nullptr || *rwlock == nullptr) { + return ORBIS_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(OrbisPthreadRwlock* rwlock) { + if (rwlock == nullptr || *rwlock == nullptr) { + return ORBIS_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(OrbisPthreadRwlock* rwlock) { + if (rwlock == nullptr || *rwlock == nullptr) { + return ORBIS_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) { + LIB_FUNCTION("1471ajPzxh0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlock_destroy); + LIB_FUNCTION("ytQULN-nhL4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlock_init); + LIB_FUNCTION("iGjsr1WAtI0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlock_rdlock); + LIB_FUNCTION("dYv-+If2GPk", "libkernel", 1, "libkernel", 1, 1, + posix_pthread_rwlock_reltimedrdlock_np); + LIB_FUNCTION("RRnSj8h8VR4", "libkernel", 1, "libkernel", 1, 1, + posix_pthread_rwlock_reltimedwrlock_np); + LIB_FUNCTION("Uwxgnsi3xeM", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlock_setname_np); + LIB_FUNCTION("lb8lnYo-o7k", "libkernel", 1, "libkernel", 1, 1, + posix_pthread_rwlock_timedrdlock); + LIB_FUNCTION("9zklzAl9CGM", "libkernel", 1, "libkernel", 1, 1, + posix_pthread_rwlock_timedwrlock); + LIB_FUNCTION("SFxTMOfuCkE", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlock_tryrdlock); + LIB_FUNCTION("XhWHn6P5R7U", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlock_trywrlock); + LIB_FUNCTION("EgmLo6EWgso", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlock_unlock); + LIB_FUNCTION("sIlRvQqsN2Y", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlock_wrlock); + LIB_FUNCTION("qsdmgXjqSgk", "libkernel", 1, "libkernel", 1, 1, + posix_pthread_rwlockattr_destroy); + LIB_FUNCTION("VqEMuCv-qHY", "libkernel", 1, "libkernel", 1, 1, + posix_pthread_rwlockattr_getpshared); + LIB_FUNCTION("l+bG5fsYkhg", "libkernel", 1, "libkernel", 1, 1, + posix_pthread_rwlockattr_gettype_np); + LIB_FUNCTION("xFebsA4YsFI", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlockattr_init); + LIB_FUNCTION("OuKg+kRDD7U", "libkernel", 1, "libkernel", 1, 1, + posix_pthread_rwlockattr_setpshared); + LIB_FUNCTION("8NuOHiTr1Vw", "libkernel", 1, "libkernel", 1, 1, + posix_pthread_rwlockattr_settype_np); + LIB_FUNCTION("1471ajPzxh0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_rwlock_destroy); + LIB_FUNCTION("ytQULN-nhL4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_rwlock_init); + LIB_FUNCTION("iGjsr1WAtI0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_rwlock_rdlock); + LIB_FUNCTION("lb8lnYo-o7k", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_rwlock_timedrdlock); + LIB_FUNCTION("9zklzAl9CGM", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_rwlock_timedwrlock); + LIB_FUNCTION("SFxTMOfuCkE", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_rwlock_tryrdlock); + LIB_FUNCTION("XhWHn6P5R7U", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_rwlock_trywrlock); + LIB_FUNCTION("EgmLo6EWgso", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_rwlock_unlock); + LIB_FUNCTION("sIlRvQqsN2Y", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_rwlock_wrlock); + LIB_FUNCTION("qsdmgXjqSgk", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_rwlockattr_destroy); + LIB_FUNCTION("VqEMuCv-qHY", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_rwlockattr_getpshared); + LIB_FUNCTION("l+bG5fsYkhg", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_rwlockattr_gettype_np); + LIB_FUNCTION("xFebsA4YsFI", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_rwlockattr_init); + LIB_FUNCTION("OuKg+kRDD7U", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_rwlockattr_setpshared); + LIB_FUNCTION("8NuOHiTr1Vw", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_rwlockattr_settype_np); + LIB_FUNCTION("i2ifZ3fS2fo", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockattrDestroy); + LIB_FUNCTION("LcOZBHGqbFk", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockattrGetpshared); + LIB_FUNCTION("Kyls1ChFyrc", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockattrGettype); + LIB_FUNCTION("yOfGg-I1ZII", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockattrInit); + LIB_FUNCTION("-ZvQH18j10c", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockattrSetpshared); + LIB_FUNCTION("h-OifiouBd8", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockattrSettype); + LIB_FUNCTION("BB+kb08Tl9A", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockDestroy); + LIB_FUNCTION("6ULAa0fq4jA", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockInit); + LIB_FUNCTION("Ox9i0c7L5w0", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockRdlock); + LIB_FUNCTION("iPtZRWICjrM", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockTimedrdlock); + LIB_FUNCTION("adh--6nIqTk", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockTimedwrlock); + LIB_FUNCTION("XD3mDeybCnk", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockTryrdlock); + LIB_FUNCTION("bIHoZCTomsI", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockTrywrlock); + LIB_FUNCTION("+L98PIbGttk", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockUnlock); + LIB_FUNCTION("mqdNorrB+gI", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockWrlock); +} +} // namespace Libraries::Kernel \ No newline at end of file