diff --git a/src/common/thread.cpp b/src/common/thread.cpp index 7cc54821f..17f955fec 100644 --- a/src/common/thread.cpp +++ b/src/common/thread.cpp @@ -217,7 +217,7 @@ void SetThreadName(void* thread, const char* name) { #endif #if defined(_WIN32) -void SetCurrentThreadName(const char*) { +void SetCurrentThreadName(const char* name) { if (Libraries::Kernel::g_curthread) { Libraries::Kernel::g_curthread->name = name; } diff --git a/src/core/libraries/kernel/threads/condvar.cpp b/src/core/libraries/kernel/threads/condvar.cpp index e347abe0e..d36533186 100644 --- a/src/core/libraries/kernel/threads/condvar.cpp +++ b/src/core/libraries/kernel/threads/condvar.cpp @@ -7,6 +7,7 @@ #include "core/libraries/kernel/posix_error.h" #include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/kernel/threads/sleepq.h" +#include "core/libraries/kernel/threads/thread_state.h" #include "core/libraries/libs.h" namespace Libraries::Kernel { @@ -179,6 +180,14 @@ int PS4_SYSV_ABI posix_pthread_cond_reltimedwait_np(PthreadCondT* cond, PthreadM int PthreadCond::Signal(Pthread* thread) { Pthread* curthread = g_curthread; + if (thread) { + auto* thread_state = ThrState::Instance(); + int ret = thread_state->FindThread(thread, false); + if (ret != ORBIS_OK) { + return ret; + } + thread->lock.unlock(); + } SleepqLock(this); SleepQueue* sq = SleepqLookup(this); @@ -339,37 +348,55 @@ int PS4_SYSV_ABI posix_pthread_condattr_setpshared(PthreadCondAttrT* attr, int p void RegisterCond(Core::Loader::SymbolsResolver* sym) { // Posix LIB_FUNCTION("mKoTx03HRWA", "libScePosix", 1, "libkernel", posix_pthread_condattr_init); - LIB_FUNCTION("dJcuQVn6-Iw", "libScePosix", 1, "libkernel", posix_pthread_condattr_destroy); + LIB_FUNCTION("3BpP850hBT4", "libScePosix", 1, "libkernel", posix_pthread_condattr_setpshared); LIB_FUNCTION("EjllaAqAPZo", "libScePosix", 1, "libkernel", posix_pthread_condattr_setclock); + LIB_FUNCTION("h0qUqSuOmC8", "libScePosix", 1, "libkernel", posix_pthread_condattr_getpshared); + LIB_FUNCTION("cTDYxTUNPhM", "libScePosix", 1, "libkernel", posix_pthread_condattr_getclock); + LIB_FUNCTION("dJcuQVn6-Iw", "libScePosix", 1, "libkernel", posix_pthread_condattr_destroy); LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", posix_pthread_cond_init); - LIB_FUNCTION("2MOy+rUfuhQ", "libScePosix", 1, "libkernel", posix_pthread_cond_signal); - LIB_FUNCTION("RXXqi4CtF8w", "libScePosix", 1, "libkernel", posix_pthread_cond_destroy); - LIB_FUNCTION("Op8TBGY5KHg", "libScePosix", 1, "libkernel", posix_pthread_cond_wait); + LIB_FUNCTION("K953PF5u6Pc", "libScePosix", 1, "libkernel", posix_pthread_cond_reltimedwait_np); LIB_FUNCTION("27bAgiJmOh0", "libScePosix", 1, "libkernel", posix_pthread_cond_timedwait); + LIB_FUNCTION("Op8TBGY5KHg", "libScePosix", 1, "libkernel", posix_pthread_cond_wait); + LIB_FUNCTION("2MOy+rUfuhQ", "libScePosix", 1, "libkernel", posix_pthread_cond_signal); + LIB_FUNCTION("CI6Qy73ae10", "libScePosix", 1, "libkernel", posix_pthread_cond_signalto_np); LIB_FUNCTION("mkx2fVhNMsg", "libScePosix", 1, "libkernel", posix_pthread_cond_broadcast); + LIB_FUNCTION("RXXqi4CtF8w", "libScePosix", 1, "libkernel", posix_pthread_cond_destroy); // Posix-Kernel - LIB_FUNCTION("0TyVk4MSLt0", "libkernel", 1, "libkernel", posix_pthread_cond_init); - LIB_FUNCTION("EjllaAqAPZo", "libkernel", 1, "libkernel", posix_pthread_condattr_setclock); - LIB_FUNCTION("Op8TBGY5KHg", "libkernel", 1, "libkernel", posix_pthread_cond_wait); - LIB_FUNCTION("mkx2fVhNMsg", "libkernel", 1, "libkernel", posix_pthread_cond_broadcast); - LIB_FUNCTION("2MOy+rUfuhQ", "libkernel", 1, "libkernel", posix_pthread_cond_signal); - LIB_FUNCTION("RXXqi4CtF8w", "libkernel", 1, "libkernel", posix_pthread_cond_destroy); - LIB_FUNCTION("27bAgiJmOh0", "libkernel", 1, "libkernel", posix_pthread_cond_timedwait); LIB_FUNCTION("mKoTx03HRWA", "libkernel", 1, "libkernel", posix_pthread_condattr_init); + LIB_FUNCTION("3BpP850hBT4", "libkernel", 1, "libkernel", posix_pthread_condattr_setpshared); + LIB_FUNCTION("EjllaAqAPZo", "libkernel", 1, "libkernel", posix_pthread_condattr_setclock); + LIB_FUNCTION("h0qUqSuOmC8", "libkernel", 1, "libkernel", posix_pthread_condattr_getpshared); + LIB_FUNCTION("cTDYxTUNPhM", "libkernel", 1, "libkernel", posix_pthread_condattr_getclock); LIB_FUNCTION("dJcuQVn6-Iw", "libkernel", 1, "libkernel", posix_pthread_condattr_destroy); + LIB_FUNCTION("0TyVk4MSLt0", "libkernel", 1, "libkernel", posix_pthread_cond_init); + LIB_FUNCTION("K953PF5u6Pc", "libkernel", 1, "libkernel", posix_pthread_cond_reltimedwait_np); + LIB_FUNCTION("27bAgiJmOh0", "libkernel", 1, "libkernel", posix_pthread_cond_timedwait); + LIB_FUNCTION("Op8TBGY5KHg", "libkernel", 1, "libkernel", posix_pthread_cond_wait); + LIB_FUNCTION("2MOy+rUfuhQ", "libkernel", 1, "libkernel", posix_pthread_cond_signal); + LIB_FUNCTION("CI6Qy73ae10", "libkernel", 1, "libkernel", posix_pthread_cond_signalto_np); + LIB_FUNCTION("mkx2fVhNMsg", "libkernel", 1, "libkernel", posix_pthread_cond_broadcast); + LIB_FUNCTION("RXXqi4CtF8w", "libkernel", 1, "libkernel", posix_pthread_cond_destroy); // Orbis - LIB_FUNCTION("2Tb92quprl0", "libkernel", 1, "libkernel", ORBIS(scePthreadCondInit)); LIB_FUNCTION("m5-2bsNfv7s", "libkernel", 1, "libkernel", ORBIS(posix_pthread_condattr_init)); - LIB_FUNCTION("JGgj7Uvrl+A", "libkernel", 1, "libkernel", ORBIS(posix_pthread_cond_broadcast)); - LIB_FUNCTION("WKAXJ4XBPQ4", "libkernel", 1, "libkernel", ORBIS(posix_pthread_cond_wait)); + LIB_FUNCTION("6xMew9+rZwI", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_condattr_setpshared)); + LIB_FUNCTION("c-bxj027czs", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_condattr_setclock)); + LIB_FUNCTION("Dn-DRWi9t54", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_condattr_getpshared)); + LIB_FUNCTION("6qM3kO5S3Oo", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_condattr_getclock)); LIB_FUNCTION("waPcxYiR3WA", "libkernel", 1, "libkernel", ORBIS(posix_pthread_condattr_destroy)); - LIB_FUNCTION("kDh-NfxgMtE", "libkernel", 1, "libkernel", ORBIS(posix_pthread_cond_signal)); + LIB_FUNCTION("2Tb92quprl0", "libkernel", 1, "libkernel", ORBIS(scePthreadCondInit)); LIB_FUNCTION("BmMjYxmew1w", "libkernel", 1, "libkernel", ORBIS(posix_pthread_cond_reltimedwait_np)); - LIB_FUNCTION("g+PZd2hiacg", "libkernel", 1, "libkernel", ORBIS(posix_pthread_cond_destroy)); + LIB_FUNCTION("WKAXJ4XBPQ4", "libkernel", 1, "libkernel", ORBIS(posix_pthread_cond_wait)); + LIB_FUNCTION("kDh-NfxgMtE", "libkernel", 1, "libkernel", ORBIS(posix_pthread_cond_signal)); LIB_FUNCTION("o69RpYO-Mu0", "libkernel", 1, "libkernel", ORBIS(posix_pthread_cond_signalto_np)); + LIB_FUNCTION("JGgj7Uvrl+A", "libkernel", 1, "libkernel", ORBIS(posix_pthread_cond_broadcast)); + LIB_FUNCTION("g+PZd2hiacg", "libkernel", 1, "libkernel", ORBIS(posix_pthread_cond_destroy)); } } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads/mutex.cpp b/src/core/libraries/kernel/threads/mutex.cpp index 65b13f799..b04000021 100644 --- a/src/core/libraries/kernel/threads/mutex.cpp +++ b/src/core/libraries/kernel/threads/mutex.cpp @@ -376,6 +376,61 @@ s32 PS4_SYSV_ABI posix_pthread_mutexattr_getkind_np(PthreadMutexAttrT attr) { return static_cast(attr->m_type); } +s32 PS4_SYSV_ABI posix_pthread_mutexattr_setprioceiling(PthreadMutexAttrT* attr, int prioceiling) { + if (attr == nullptr || *attr == nullptr || (*attr)->m_protocol != PthreadMutexProt::Protect || + prioceiling > ORBIS_KERNEL_PRIO_FIFO_HIGHEST || + prioceiling < ORBIS_KERNEL_PRIO_FIFO_LOWEST) { + return POSIX_EINVAL; + } + (*attr)->m_ceiling = prioceiling; + return 0; +} + +s32 PS4_SYSV_ABI posix_pthread_mutexattr_getprioceiling(PthreadMutexAttrT* attr, int* prioceiling) { + if (attr == nullptr || *attr == nullptr || (*attr)->m_protocol != PthreadMutexProt::Protect) { + return POSIX_EINVAL; + } + *prioceiling = (*attr)->m_ceiling; + return 0; +} + +s32 PS4_SYSV_ABI posix_pthread_mutexattr_setprotocol(PthreadMutexAttrT* mattr, + PthreadMutexProt protocol) { + if (mattr == nullptr || *mattr == nullptr || (protocol < PthreadMutexProt::None) || + (protocol > PthreadMutexProt::Protect)) { + return POSIX_EINVAL; + } + (*mattr)->m_protocol = protocol; + (*mattr)->m_ceiling = ORBIS_KERNEL_PRIO_RR_HIGHEST; + return 0; +} + +s32 PS4_SYSV_ABI posix_pthread_mutexattr_getprotocol(PthreadMutexAttrT* mattr, + PthreadMutexProt* protocol) { + if (mattr == nullptr || *mattr == nullptr) { + return POSIX_EINVAL; + } + *protocol = (*mattr)->m_protocol; + return 0; +} + +s32 PS4_SYSV_ABI posix_pthread_mutexattr_setpshared(PthreadMutexAttrT* attr, s32 pshared) { + constexpr s32 POSIX_PTHREAD_PROCESS_PRIVATE = 0; + constexpr s32 POSIX_PTHREAD_PROCESS_SHARED = 1; + if (!attr || !*attr || pshared != POSIX_PTHREAD_PROCESS_PRIVATE) { + return POSIX_EINVAL; + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI posix_pthread_mutexattr_getpshared(PthreadMutexAttrT* attr, s32* pshared) { + if (!attr || !*attr) { + return POSIX_EINVAL; + } + *pshared = 0; + return ORBIS_OK; +} + s32 PS4_SYSV_ABI posix_pthread_mutexattr_settype(PthreadMutexAttrT* attr, PthreadMutexType type) { if (attr == nullptr || *attr == nullptr || type < PthreadMutexType::ErrorCheck || type >= PthreadMutexType::Max) { @@ -402,77 +457,105 @@ s32 PS4_SYSV_ABI posix_pthread_mutexattr_destroy(PthreadMutexAttrT* attr) { return 0; } -s32 PS4_SYSV_ABI posix_pthread_mutexattr_getprotocol(PthreadMutexAttrT* mattr, - PthreadMutexProt* protocol) { - if (mattr == nullptr || *mattr == nullptr) { - return POSIX_EINVAL; - } - *protocol = (*mattr)->m_protocol; - return 0; -} - -s32 PS4_SYSV_ABI posix_pthread_mutexattr_setprotocol(PthreadMutexAttrT* mattr, - PthreadMutexProt protocol) { - if (mattr == nullptr || *mattr == nullptr || (protocol < PthreadMutexProt::None) || - (protocol > PthreadMutexProt::Protect)) { - return POSIX_EINVAL; - } - (*mattr)->m_protocol = protocol; - //(*mattr)->m_ceiling = THR_MAX_RR_PRIORITY; - return 0; -} - -s32 PS4_SYSV_ABI posix_pthread_mutexattr_setpshared(PthreadMutexAttrT* attr, s32 pshared) { - constexpr s32 POSIX_PTHREAD_PROCESS_PRIVATE = 0; - constexpr s32 POSIX_PTHREAD_PROCESS_SHARED = 1; - if (!attr || !*attr || pshared != POSIX_PTHREAD_PROCESS_PRIVATE) { - return POSIX_EINVAL; - } - return ORBIS_OK; -} - void RegisterMutex(Core::Loader::SymbolsResolver* sym) { // Posix LIB_FUNCTION("ttHNfU+qDBU", "libScePosix", 1, "libkernel", posix_pthread_mutex_init); + LIB_FUNCTION("gKqzW-zWhvY", "libScePosix", 1, "libkernel", posix_pthread_mutex_isowned_np); LIB_FUNCTION("7H0iTOciTLo", "libScePosix", 1, "libkernel", posix_pthread_mutex_lock); LIB_FUNCTION("Io9+nTKXZtA", "libScePosix", 1, "libkernel", posix_pthread_mutex_timedlock); + LIB_FUNCTION("K-jXhbt2gn4", "libScePosix", 1, "libkernel", posix_pthread_mutex_trylock); LIB_FUNCTION("2Z+PpY6CaJg", "libScePosix", 1, "libkernel", posix_pthread_mutex_unlock); + LIB_FUNCTION("x4vQj3JKKmc", "libScePosix", 1, "libkernel", posix_pthread_mutex_getspinloops_np); + LIB_FUNCTION("OxEIUqkByy4", "libScePosix", 1, "libkernel", + posix_pthread_mutex_getyieldloops_np); + LIB_FUNCTION("5-ncLMtL5+g", "libScePosix", 1, "libkernel", posix_pthread_mutex_setspinloops_np); + LIB_FUNCTION("frFuGprJmPc", "libScePosix", 1, "libkernel", + posix_pthread_mutex_setyieldloops_np); LIB_FUNCTION("ltCfaGr2JGE", "libScePosix", 1, "libkernel", posix_pthread_mutex_destroy); LIB_FUNCTION("dQHWEsJtoE4", "libScePosix", 1, "libkernel", posix_pthread_mutexattr_init); - LIB_FUNCTION("mDmgMOGVUqg", "libScePosix", 1, "libkernel", posix_pthread_mutexattr_settype); + LIB_FUNCTION("U6SNV+RnyLQ", "libScePosix", 1, "libkernel", posix_pthread_mutexattr_getkind_np); + LIB_FUNCTION("+m8+quqOwhM", "libScePosix", 1, "libkernel", + posix_pthread_mutexattr_getprioceiling); + LIB_FUNCTION("yDaWxUE50s0", "libScePosix", 1, "libkernel", posix_pthread_mutexattr_getprotocol); + LIB_FUNCTION("PmL-TwKUzXI", "libScePosix", 1, "libkernel", posix_pthread_mutexattr_getpshared); + LIB_FUNCTION("GZFlI7RhuQo", "libScePosix", 1, "libkernel", posix_pthread_mutexattr_gettype); + LIB_FUNCTION("J9rlRuQ8H5s", "libScePosix", 1, "libkernel", posix_pthread_mutexattr_setkind_np); + LIB_FUNCTION("ZLvf6lVAc4M", "libScePosix", 1, "libkernel", + posix_pthread_mutexattr_setprioceiling); LIB_FUNCTION("5txKfcMUAok", "libScePosix", 1, "libkernel", posix_pthread_mutexattr_setprotocol); - LIB_FUNCTION("HF7lK46xzjY", "libScePosix", 1, "libkernel", posix_pthread_mutexattr_destroy); - LIB_FUNCTION("K-jXhbt2gn4", "libScePosix", 1, "libkernel", posix_pthread_mutex_trylock); LIB_FUNCTION("EXv3ztGqtDM", "libScePosix", 1, "libkernel", posix_pthread_mutexattr_setpshared); + LIB_FUNCTION("mDmgMOGVUqg", "libScePosix", 1, "libkernel", posix_pthread_mutexattr_settype); + LIB_FUNCTION("HF7lK46xzjY", "libScePosix", 1, "libkernel", posix_pthread_mutexattr_destroy); // Posix-Kernel LIB_FUNCTION("ttHNfU+qDBU", "libkernel", 1, "libkernel", posix_pthread_mutex_init); + LIB_FUNCTION("gKqzW-zWhvY", "libkernel", 1, "libkernel", posix_pthread_mutex_isowned_np); LIB_FUNCTION("7H0iTOciTLo", "libkernel", 1, "libkernel", posix_pthread_mutex_lock); + LIB_FUNCTION("Io9+nTKXZtA", "libkernel", 1, "libkernel", posix_pthread_mutex_timedlock); + LIB_FUNCTION("K-jXhbt2gn4", "libkernel", 1, "libkernel", posix_pthread_mutex_trylock); LIB_FUNCTION("2Z+PpY6CaJg", "libkernel", 1, "libkernel", posix_pthread_mutex_unlock); + LIB_FUNCTION("x4vQj3JKKmc", "libkernel", 1, "libkernel", posix_pthread_mutex_getspinloops_np); + LIB_FUNCTION("OxEIUqkByy4", "libkernel", 1, "libkernel", posix_pthread_mutex_getyieldloops_np); + LIB_FUNCTION("5-ncLMtL5+g", "libkernel", 1, "libkernel", posix_pthread_mutex_setspinloops_np); + LIB_FUNCTION("frFuGprJmPc", "libkernel", 1, "libkernel", posix_pthread_mutex_setyieldloops_np); LIB_FUNCTION("ltCfaGr2JGE", "libkernel", 1, "libkernel", posix_pthread_mutex_destroy); LIB_FUNCTION("dQHWEsJtoE4", "libkernel", 1, "libkernel", posix_pthread_mutexattr_init); + LIB_FUNCTION("U6SNV+RnyLQ", "libkernel", 1, "libkernel", posix_pthread_mutexattr_getkind_np); + LIB_FUNCTION("+m8+quqOwhM", "libkernel", 1, "libkernel", + posix_pthread_mutexattr_getprioceiling); + LIB_FUNCTION("yDaWxUE50s0", "libkernel", 1, "libkernel", posix_pthread_mutexattr_getprotocol); + LIB_FUNCTION("PmL-TwKUzXI", "libkernel", 1, "libkernel", posix_pthread_mutexattr_getpshared); + LIB_FUNCTION("GZFlI7RhuQo", "libkernel", 1, "libkernel", posix_pthread_mutexattr_gettype); + LIB_FUNCTION("J9rlRuQ8H5s", "libkernel", 1, "libkernel", posix_pthread_mutexattr_setkind_np); + LIB_FUNCTION("ZLvf6lVAc4M", "libkernel", 1, "libkernel", + posix_pthread_mutexattr_setprioceiling); + LIB_FUNCTION("5txKfcMUAok", "libkernel", 1, "libkernel", posix_pthread_mutexattr_setprotocol); + LIB_FUNCTION("EXv3ztGqtDM", "libkernel", 1, "libkernel", posix_pthread_mutexattr_setpshared); LIB_FUNCTION("mDmgMOGVUqg", "libkernel", 1, "libkernel", posix_pthread_mutexattr_settype); LIB_FUNCTION("HF7lK46xzjY", "libkernel", 1, "libkernel", posix_pthread_mutexattr_destroy); - LIB_FUNCTION("K-jXhbt2gn4", "libkernel", 1, "libkernel", posix_pthread_mutex_trylock); - LIB_FUNCTION("EXv3ztGqtDM", "libkernel", 1, "libkernel", posix_pthread_mutexattr_setpshared); // Orbis LIB_FUNCTION("cmo1RIYva9o", "libkernel", 1, "libkernel", ORBIS(scePthreadMutexInit)); - LIB_FUNCTION("2Of0f+3mhhE", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutex_destroy)); - LIB_FUNCTION("F8bUHwAG284", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutexattr_init)); - LIB_FUNCTION("smWEktiyyG0", "libkernel", 1, "libkernel", - ORBIS(posix_pthread_mutexattr_destroy)); - LIB_FUNCTION("iMp8QpE+XO4", "libkernel", 1, "libkernel", - ORBIS(posix_pthread_mutexattr_settype)); - LIB_FUNCTION("1FGvU0i9saQ", "libkernel", 1, "libkernel", - ORBIS(posix_pthread_mutexattr_setprotocol)); + LIB_FUNCTION("qH1gXoq71RY", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutex_init)); + LIB_FUNCTION("W6OrTBO95UY", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutex_isowned_np)); LIB_FUNCTION("9UK1vLZQft4", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutex_lock)); - LIB_FUNCTION("tn3VlD0hG60", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutex_unlock)); - LIB_FUNCTION("upoVrzMHFeE", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutex_trylock)); LIB_FUNCTION("IafI2PxcPnQ", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutex_reltimedlock_np)); - LIB_FUNCTION("qH1gXoq71RY", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutex_init)); + LIB_FUNCTION("upoVrzMHFeE", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutex_trylock)); + LIB_FUNCTION("tn3VlD0hG60", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutex_unlock)); + LIB_FUNCTION("pOmNmyRKlIE", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutex_getspinloops_np)); + LIB_FUNCTION("AWS3NyViL9o", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutex_getyieldloops_np)); + LIB_FUNCTION("42YkUouoMI0", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutex_setspinloops_np)); + LIB_FUNCTION("bP+cqFmBW+A", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutex_setyieldloops_np)); + LIB_FUNCTION("2Of0f+3mhhE", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutex_destroy)); LIB_FUNCTION("n2MMpvU8igI", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutexattr_init)); + LIB_FUNCTION("F8bUHwAG284", "libkernel", 1, "libkernel", ORBIS(posix_pthread_mutexattr_init)); + LIB_FUNCTION("rH2mWEndluc", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutexattr_getkind_np)); + LIB_FUNCTION("SgjMpyH9Z9I", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutexattr_getprioceiling)); + LIB_FUNCTION("GoTmFeui+hQ", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutexattr_getprotocol)); + LIB_FUNCTION("losEubHc64c", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutexattr_getpshared)); + LIB_FUNCTION("gquEhBrS2iw", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutexattr_gettype)); + LIB_FUNCTION("UWZbVSFze24", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutexattr_setkind_np)); + LIB_FUNCTION("532IaQguwMg", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutexattr_setprioceiling)); + LIB_FUNCTION("1FGvU0i9saQ", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutexattr_setprotocol)); + LIB_FUNCTION("mxKx9bxXF2I", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutexattr_setpshared)); + LIB_FUNCTION("iMp8QpE+XO4", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutexattr_settype)); + LIB_FUNCTION("smWEktiyyG0", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_mutexattr_destroy)); } } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads/pthread.cpp b/src/core/libraries/kernel/threads/pthread.cpp index bc0d1f295..b86536aec 100644 --- a/src/core/libraries/kernel/threads/pthread.cpp +++ b/src/core/libraries/kernel/threads/pthread.cpp @@ -21,10 +21,10 @@ extern PthreadAttr PthreadAttrDefault; void _thread_cleanupspecific(); -using ThreadDtor = void (*)(); -static ThreadDtor* ThreadDtors{}; +using ThreadDtor = void PS4_SYSV_ABI (*)(); +static ThreadDtor ThreadDtors{}; -void PS4_SYSV_ABI _sceKernelSetThreadDtors(ThreadDtor* dtor) { +void PS4_SYSV_ABI _sceKernelSetThreadDtors(ThreadDtor dtor) { ThreadDtors = dtor; } @@ -86,9 +86,9 @@ void PS4_SYSV_ABI posix_pthread_exit(void* status) { delete old; } } - /*if (ThreadDtors && *ThreadDtors) { - (*ThreadDtors)(); - }*/ + if (ThreadDtors) { + (ThreadDtors)(); + } ExitThread(); } @@ -322,8 +322,30 @@ int PS4_SYSV_ABI posix_pthread_getthreadid_np() { } int PS4_SYSV_ABI posix_pthread_getname_np(PthreadT thread, char* name) { - std::memcpy(name, thread->name.data(), std::min(thread->name.size(), 32)); - return 0; + if (thread == g_curthread) { + // Can skip locking and reference logic if thread is curthread. + std::memcpy(name, thread->name.data(), std::min(thread->name.size(), 32)); + return ORBIS_OK; + } + + // Find the thread in the list of active threads. + auto* thread_state = ThrState::Instance(); + if (int ret = thread_state->RefAdd(thread, false); ret != 0) { + return POSIX_ESRCH; + } + + // Lock the thread. + thread->lock.lock(); + + // Get the thread name + if (thread->state != PthreadState::Dead) { + std::memcpy(name, thread->name.data(), std::min(thread->name.size(), 32)); + } + + // Unlock and remove reference. + thread->lock.unlock(); + thread_state->RefDelete(thread); + return ORBIS_OK; } int PS4_SYSV_ABI posix_pthread_equal(PthreadT thread1, PthreadT thread2) { @@ -334,11 +356,6 @@ PthreadT PS4_SYSV_ABI posix_pthread_self() { return g_curthread; } -void PS4_SYSV_ABI posix_pthread_set_name_np(PthreadT thread, const char* name) { - LOG_INFO(Kernel_Pthread, "called, new name: {}", name); - Common::SetCurrentThreadName(name); -} - void PS4_SYSV_ABI posix_pthread_yield() { std::this_thread::yield(); } @@ -402,27 +419,66 @@ int PS4_SYSV_ABI posix_pthread_once(PthreadOnce* once_control, return 0; } -int PS4_SYSV_ABI posix_sched_get_priority_max() { +int PS4_SYSV_ABI posix_sched_get_priority_max(SchedPolicy policy) { + if (policy != SchedPolicy::Fifo && policy != SchedPolicy::RoundRobin) { + return POSIX_EINVAL; + } return ORBIS_KERNEL_PRIO_FIFO_HIGHEST; } -int PS4_SYSV_ABI posix_sched_get_priority_min() { +int PS4_SYSV_ABI posix_sched_get_priority_min(SchedPolicy policy) { + if (policy != SchedPolicy::Fifo && policy != SchedPolicy::RoundRobin) { + return POSIX_EINVAL; + } return ORBIS_KERNEL_PRIO_FIFO_LOWEST; } int PS4_SYSV_ABI posix_pthread_rename_np(PthreadT thread, const char* name) { - if (thread == nullptr) { - return POSIX_EINVAL; + LOG_INFO(Kernel_Pthread, "name = {}", name ? name : "(null)"); + auto* thread_state = ThrState::Instance(); + auto* memory = Core::Memory::Instance(); + + if (thread == g_curthread) { + // If the requested thread is curthread, skip locking and reference logic. + thread->name = name ? name : std::string{""}; + Common::SetThreadName(reinterpret_cast(thread->native_thr.GetHandle()), + thread->name.data()); + if (name && False(thread->attr.flags & PthreadAttrFlags::StackUser)) { + VAddr stack_addr = std::bit_cast(thread->attr.stackaddr_attr); + memory->NameVirtualRange(stack_addr, thread->attr.stacksize_attr, name); + } + return ORBIS_OK; } - if (name == nullptr) { - return 0; + + // Find the thread in the list of active threads. + if (int ret = thread_state->RefAdd(thread, false); ret != 0) { + return POSIX_ESRCH; } - LOG_INFO(Kernel_Pthread, "name = {}", name); - Common::SetThreadName(reinterpret_cast(thread->native_thr.GetHandle()), name); - thread->name = name; + + // Lock the thread. + thread->lock.lock(); + + // Set the thread and thread stack names. + if (thread->state != PthreadState::Dead) { + thread->name = name ? name : std::string{""}; + Common::SetThreadName(reinterpret_cast(thread->native_thr.GetHandle()), + thread->name.data()); + if (name && False(thread->attr.flags & PthreadAttrFlags::StackUser)) { + VAddr stack_addr = std::bit_cast(thread->attr.stackaddr_attr); + memory->NameVirtualRange(stack_addr, thread->attr.stacksize_attr, name); + } + } + + // Unlock and remove reference. + thread->lock.unlock(); + thread_state->RefDelete(thread); return ORBIS_OK; } +void PS4_SYSV_ABI posix_pthread_set_name_np(PthreadT thread, const char* name) { + posix_pthread_rename_np(thread, name); +} + int PS4_SYSV_ABI posix_pthread_getschedparam(PthreadT pthread, SchedPolicy* policy, SchedParam* param) { if (policy == nullptr || param == nullptr) { @@ -483,7 +539,10 @@ int PS4_SYSV_ABI scePthreadGetprio(PthreadT thread, int* priority) { SchedParam param; SchedPolicy policy; - posix_pthread_getschedparam(thread, &policy, ¶m); + int ret = posix_pthread_getschedparam(thread, &policy, ¶m); + if (ret != 0) { + return ORBIS_KERNEL_ERROR_ESRCH; + } *priority = param.sched_priority; return 0; } @@ -493,12 +552,14 @@ int PS4_SYSV_ABI posix_pthread_setprio(PthreadT thread, int prio) { param.sched_priority = prio; auto* thread_state = ThrState::Instance(); - if (thread == g_curthread) { - g_curthread->lock.lock(); - } else if (const int ret = thread_state->FindThread(thread, /*include dead*/ false); ret != 0) { - return ret; + if (thread != g_curthread) { + const int ret = thread_state->RefAdd(thread, /*include dead*/ false); + if (ret != 0) { + return ret; + } } + thread->lock.lock(); if (thread->attr.sched_policy == SchedPolicy::Other || thread->attr.prio == prio) { thread->attr.prio = prio; } else { @@ -507,6 +568,9 @@ int PS4_SYSV_ABI posix_pthread_setprio(PthreadT thread, int prio) { } thread->lock.unlock(); + if (thread != g_curthread) { + thread_state->RefDelete(thread); + } return 0; } diff --git a/src/core/libraries/kernel/threads/pthread.h b/src/core/libraries/kernel/threads/pthread.h index daec4bde5..0763c74a3 100644 --- a/src/core/libraries/kernel/threads/pthread.h +++ b/src/core/libraries/kernel/threads/pthread.h @@ -27,8 +27,14 @@ namespace Libraries::Kernel { constexpr int PthreadInheritSched = 4; constexpr int ORBIS_KERNEL_PRIO_FIFO_DEFAULT = 700; -constexpr int ORBIS_KERNEL_PRIO_FIFO_HIGHEST = 256; -constexpr int ORBIS_KERNEL_PRIO_FIFO_LOWEST = 767; +constexpr int ORBIS_KERNEL_PRIO_FIFO_LOWEST = 256; +constexpr int ORBIS_KERNEL_PRIO_FIFO_HIGHEST = 767; +constexpr int ORBIS_KERNEL_PRIO_OTHER_DEFAULT = 900; +constexpr int ORBIS_KERNEL_PRIO_OTHER_LOWEST = 768; +constexpr int ORBIS_KERNEL_PRIO_OTHER_HIGHEST = 959; +constexpr int ORBIS_KERNEL_PRIO_RR_DEFAULT = 700; +constexpr int ORBIS_KERNEL_PRIO_RR_LOWEST = 256; +constexpr int ORBIS_KERNEL_PRIO_RR_HIGHEST = 767; struct Pthread; @@ -150,6 +156,7 @@ struct PthreadCleanup { }; enum class PthreadAttrFlags : u32 { + ScopeProcess = 0, Detached = 1, ScopeSystem = 2, InheritSched = 4, @@ -159,7 +166,7 @@ enum class PthreadAttrFlags : u32 { DECLARE_ENUM_FLAG_OPERATORS(PthreadAttrFlags) enum class SchedPolicy : u32 { - Fifo = 0, + Fifo = 1, Other = 2, RoundRobin = 3, }; @@ -190,6 +197,7 @@ static constexpr u32 ThrGuardDefault = ThrPageSize; struct PthreadRwlockAttr { int pshared; + int type; }; using PthreadRwlockAttrT = PthreadRwlockAttr*; diff --git a/src/core/libraries/kernel/threads/pthread_attr.cpp b/src/core/libraries/kernel/threads/pthread_attr.cpp index 2f3f26049..eb1bca3e8 100644 --- a/src/core/libraries/kernel/threads/pthread_attr.cpp +++ b/src/core/libraries/kernel/threads/pthread_attr.cpp @@ -85,6 +85,17 @@ int PS4_SYSV_ABI posix_pthread_attr_getschedpolicy(const PthreadAttrT* attr, Sch return 0; } +int PS4_SYSV_ABI posix_pthread_attr_getscope(const PthreadAttrT* attr, + PthreadAttrFlags* contentionscope) { + if (attr == nullptr || *attr == nullptr || contentionscope == nullptr) { + return POSIX_EINVAL; + } + *contentionscope = True((*attr)->flags & PthreadAttrFlags::ScopeSystem) + ? PthreadAttrFlags::ScopeSystem + : PthreadAttrFlags::ScopeProcess; + return 0; +} + int PS4_SYSV_ABI posix_pthread_attr_getstack(const PthreadAttrT* attr, void** stackaddr, size_t* stacksize) { if (attr == nullptr || *attr == nullptr || stackaddr == nullptr || stacksize == nullptr) { @@ -121,6 +132,14 @@ int PS4_SYSV_ABI posix_pthread_attr_init(PthreadAttrT* attr) { return 0; } +int PS4_SYSV_ABI posix_pthread_attr_setcreatesuspend_np(PthreadAttrT* attr) { + if (attr == nullptr || *attr == nullptr) { + return POSIX_EINVAL; + } + (*attr)->suspend = 1; + return 0; +} + int PS4_SYSV_ABI posix_pthread_attr_setschedpolicy(PthreadAttrT* attr, SchedPolicy policy) { if (attr == nullptr || *attr == nullptr) { return POSIX_EINVAL; @@ -132,6 +151,22 @@ int PS4_SYSV_ABI posix_pthread_attr_setschedpolicy(PthreadAttrT* attr, SchedPoli return 0; } +int PS4_SYSV_ABI posix_pthread_attr_setscope(PthreadAttrT* attr, PthreadAttrFlags contentionscope) { + if (attr == nullptr || *attr == nullptr) { + return POSIX_EINVAL; + } + if (contentionscope != PthreadAttrFlags::ScopeProcess || + contentionscope != PthreadAttrFlags::ScopeSystem) { + return POSIX_EINVAL; + } + if (contentionscope == PthreadAttrFlags::ScopeSystem) { + (*attr)->flags |= contentionscope; + } else { + (*attr)->flags &= ~PthreadAttrFlags::ScopeSystem; + } + return 0; +} + int PS4_SYSV_ABI posix_pthread_attr_setstack(PthreadAttrT* attr, void* stackaddr, size_t stacksize) { if (attr == nullptr || *attr == nullptr || stackaddr == nullptr || @@ -180,7 +215,7 @@ int PS4_SYSV_ABI posix_pthread_attr_setschedparam(PthreadAttrT* attr, SchedParam } const auto policy = (*attr)->sched_policy; - if (policy == SchedPolicy::RoundRobin) { + if (policy == SchedPolicy::Fifo || policy == SchedPolicy::RoundRobin) { if (param->sched_priority < ThrPriorities[u32(policy) - 1].pri_min || param->sched_priority > ThrPriorities[u32(policy) - 1].pri_max) { return POSIX_ENOTSUP; @@ -287,66 +322,99 @@ int PS4_SYSV_ABI scePthreadAttrSetaffinity(PthreadAttrT* attr, const u64 mask) { void RegisterThreadAttr(Core::Loader::SymbolsResolver* sym) { // Posix LIB_FUNCTION("wtkt-teR1so", "libScePosix", 1, "libkernel", posix_pthread_attr_init); - LIB_FUNCTION("vQm4fDEsWi8", "libScePosix", 1, "libkernel", posix_pthread_attr_getstack); - LIB_FUNCTION("2Q0z6rnBrTE", "libScePosix", 1, "libkernel", posix_pthread_attr_setstacksize); + LIB_FUNCTION("wtkt-teR1so", "libScePosix", 1, "libkernel", posix_pthread_attr_init); LIB_FUNCTION("Ucsu-OK+els", "libScePosix", 1, "libkernel", posix_pthread_attr_get_np); - LIB_FUNCTION("RtLRV-pBTTY", "libScePosix", 1, "libkernel", posix_pthread_attr_getschedpolicy); - LIB_FUNCTION("JarMIy8kKEY", "libScePosix", 1, "libkernel", posix_pthread_attr_setschedpolicy); - LIB_FUNCTION("E+tyo3lp5Lw", "libScePosix", 1, "libkernel", posix_pthread_attr_setdetachstate); - LIB_FUNCTION("zHchY8ft5pk", "libScePosix", 1, "libkernel", posix_pthread_attr_destroy); - LIB_FUNCTION("euKRgm0Vn2M", "libScePosix", 1, "libkernel", posix_pthread_attr_setschedparam); - LIB_FUNCTION("7ZlAakEf0Qg", "libScePosix", 1, "libkernel", posix_pthread_attr_setinheritsched); - LIB_FUNCTION("0qOtCR-ZHck", "libScePosix", 1, "libkernel", posix_pthread_attr_getstacksize); + LIB_FUNCTION("-wzZ7dvA7UU", "libScePosix", 1, "libkernel", posix_pthread_attr_getaffinity_np); LIB_FUNCTION("VUT1ZSrHT0I", "libScePosix", 1, "libkernel", posix_pthread_attr_getdetachstate); - LIB_FUNCTION("JKyG3SWyA10", "libScePosix", 1, "libkernel", posix_pthread_attr_setguardsize); LIB_FUNCTION("JNkVVsVDmOk", "libScePosix", 1, "libkernel", posix_pthread_attr_getguardsize); + LIB_FUNCTION("oLjPqUKhzes", "libScePosix", 1, "libkernel", posix_pthread_attr_getinheritsched); LIB_FUNCTION("qlk9pSLsUmM", "libScePosix", 1, "libkernel", posix_pthread_attr_getschedparam); + LIB_FUNCTION("RtLRV-pBTTY", "libScePosix", 1, "libkernel", posix_pthread_attr_getschedpolicy); + LIB_FUNCTION("e2G+cdEkOmU", "libScePosix", 1, "libkernel", posix_pthread_attr_getscope); + LIB_FUNCTION("vQm4fDEsWi8", "libScePosix", 1, "libkernel", posix_pthread_attr_getstack); + LIB_FUNCTION("DxmIMUQ-wXY", "libScePosix", 1, "libkernel", posix_pthread_attr_getstackaddr); + LIB_FUNCTION("0qOtCR-ZHck", "libScePosix", 1, "libkernel", posix_pthread_attr_getstacksize); + LIB_FUNCTION("o8pd4juNbgc", "libScePosix", 1, "libkernel", posix_pthread_attr_setaffinity_np); + LIB_FUNCTION("Q2y5IqSDZGs", "libScePosix", 1, "libkernel", + posix_pthread_attr_setcreatesuspend_np); + LIB_FUNCTION("E+tyo3lp5Lw", "libScePosix", 1, "libkernel", posix_pthread_attr_setdetachstate); + LIB_FUNCTION("JKyG3SWyA10", "libScePosix", 1, "libkernel", posix_pthread_attr_setguardsize); + LIB_FUNCTION("7ZlAakEf0Qg", "libScePosix", 1, "libkernel", posix_pthread_attr_setinheritsched); + LIB_FUNCTION("euKRgm0Vn2M", "libScePosix", 1, "libkernel", posix_pthread_attr_setschedparam); + LIB_FUNCTION("JarMIy8kKEY", "libScePosix", 1, "libkernel", posix_pthread_attr_setschedpolicy); + LIB_FUNCTION("xesmlSI-KCI", "libScePosix", 1, "libkernel", posix_pthread_attr_setscope); + LIB_FUNCTION("-SrbXpGR1f0", "libScePosix", 1, "libkernel", posix_pthread_attr_setstack); + LIB_FUNCTION("suCrEbr0xIQ", "libScePosix", 1, "libkernel", posix_pthread_attr_setstackaddr); + LIB_FUNCTION("2Q0z6rnBrTE", "libScePosix", 1, "libkernel", posix_pthread_attr_setstacksize); + LIB_FUNCTION("zHchY8ft5pk", "libScePosix", 1, "libkernel", posix_pthread_attr_destroy); + // Posix-Kernel LIB_FUNCTION("wtkt-teR1so", "libkernel", 1, "libkernel", posix_pthread_attr_init); - LIB_FUNCTION("vQm4fDEsWi8", "libkernel", 1, "libkernel", posix_pthread_attr_getstack); - LIB_FUNCTION("2Q0z6rnBrTE", "libkernel", 1, "libkernel", posix_pthread_attr_setstacksize); LIB_FUNCTION("Ucsu-OK+els", "libkernel", 1, "libkernel", posix_pthread_attr_get_np); - LIB_FUNCTION("RtLRV-pBTTY", "libkernel", 1, "libkernel", posix_pthread_attr_getschedpolicy); - LIB_FUNCTION("E+tyo3lp5Lw", "libkernel", 1, "libkernel", posix_pthread_attr_setdetachstate); - LIB_FUNCTION("zHchY8ft5pk", "libkernel", 1, "libkernel", posix_pthread_attr_destroy); - LIB_FUNCTION("euKRgm0Vn2M", "libkernel", 1, "libkernel", posix_pthread_attr_setschedparam); - LIB_FUNCTION("7ZlAakEf0Qg", "libkernel", 1, "libkernel", posix_pthread_attr_setinheritsched); - LIB_FUNCTION("0qOtCR-ZHck", "libkernel", 1, "libkernel", posix_pthread_attr_getstacksize); + LIB_FUNCTION("-wzZ7dvA7UU", "libkernel", 1, "libkernel", posix_pthread_attr_getaffinity_np); LIB_FUNCTION("VUT1ZSrHT0I", "libkernel", 1, "libkernel", posix_pthread_attr_getdetachstate); - LIB_FUNCTION("JKyG3SWyA10", "libkernel", 1, "libkernel", posix_pthread_attr_setguardsize); LIB_FUNCTION("JNkVVsVDmOk", "libkernel", 1, "libkernel", posix_pthread_attr_getguardsize); + LIB_FUNCTION("oLjPqUKhzes", "libkernel", 1, "libkernel", posix_pthread_attr_getinheritsched); LIB_FUNCTION("qlk9pSLsUmM", "libkernel", 1, "libkernel", posix_pthread_attr_getschedparam); + LIB_FUNCTION("RtLRV-pBTTY", "libkernel", 1, "libkernel", posix_pthread_attr_getschedpolicy); + LIB_FUNCTION("e2G+cdEkOmU", "libkernel", 1, "libkernel", posix_pthread_attr_getscope); + LIB_FUNCTION("vQm4fDEsWi8", "libkernel", 1, "libkernel", posix_pthread_attr_getstack); + LIB_FUNCTION("DxmIMUQ-wXY", "libkernel", 1, "libkernel", posix_pthread_attr_getstackaddr); + LIB_FUNCTION("0qOtCR-ZHck", "libkernel", 1, "libkernel", posix_pthread_attr_getstacksize); + LIB_FUNCTION("o8pd4juNbgc", "libkernel", 1, "libkernel", posix_pthread_attr_setaffinity_np); + LIB_FUNCTION("Q2y5IqSDZGs", "libkernel", 1, "libkernel", + posix_pthread_attr_setcreatesuspend_np); + LIB_FUNCTION("E+tyo3lp5Lw", "libkernel", 1, "libkernel", posix_pthread_attr_setdetachstate); + LIB_FUNCTION("JKyG3SWyA10", "libkernel", 1, "libkernel", posix_pthread_attr_setguardsize); + LIB_FUNCTION("7ZlAakEf0Qg", "libkernel", 1, "libkernel", posix_pthread_attr_setinheritsched); + LIB_FUNCTION("euKRgm0Vn2M", "libkernel", 1, "libkernel", posix_pthread_attr_setschedparam); + LIB_FUNCTION("JarMIy8kKEY", "libkernel", 1, "libkernel", posix_pthread_attr_setschedpolicy); + LIB_FUNCTION("xesmlSI-KCI", "libkernel", 1, "libkernel", posix_pthread_attr_setscope); + LIB_FUNCTION("-SrbXpGR1f0", "libkernel", 1, "libkernel", posix_pthread_attr_setstack); + LIB_FUNCTION("suCrEbr0xIQ", "libkernel", 1, "libkernel", posix_pthread_attr_setstackaddr); + LIB_FUNCTION("2Q0z6rnBrTE", "libkernel", 1, "libkernel", posix_pthread_attr_setstacksize); + LIB_FUNCTION("zHchY8ft5pk", "libkernel", 1, "libkernel", posix_pthread_attr_destroy); // Orbis - LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", - ORBIS(posix_pthread_attr_setschedpolicy)); - LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", - ORBIS(posix_pthread_attr_setdetachstate)); + LIB_FUNCTION("nsYoNRywwNg", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_init)); + LIB_FUNCTION("x1X76arYMxU", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_get_np)); + LIB_FUNCTION("8+s5BzZjxSg", "libkernel", 1, "libkernel", ORBIS(scePthreadAttrGetaffinity)); LIB_FUNCTION("JaRMy+QcpeU", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_getdetachstate)); - LIB_FUNCTION("eXbUSpEaTsA", "libkernel", 1, "libkernel", - ORBIS(posix_pthread_attr_setinheritsched)); - LIB_FUNCTION("DzES9hQF4f4", "libkernel", 1, "libkernel", - ORBIS(posix_pthread_attr_setschedparam)); - LIB_FUNCTION("nsYoNRywwNg", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_init)); - LIB_FUNCTION("62KCwEMmzcM", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_destroy)); + LIB_FUNCTION("txHtngJ+eyc", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_attr_getguardsize)); + LIB_FUNCTION("lpMP8HhkBbg", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_attr_getinheritsched)); + LIB_FUNCTION("FXPWHNk8Of0", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_attr_getschedparam)); + LIB_FUNCTION("NMyIQ9WgWbU", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_attr_getschedpolicy)); + LIB_FUNCTION("+7B2AEKKns8", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_getscope)); LIB_FUNCTION("-quPa4SEJUw", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_getstack)); - LIB_FUNCTION("Bvn74vj6oLo", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_setstack)); LIB_FUNCTION("Ru36fiTtJzA", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_getstackaddr)); LIB_FUNCTION("-fA+7ZlGDQs", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_getstacksize)); - LIB_FUNCTION("x1X76arYMxU", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_get_np)); - LIB_FUNCTION("FXPWHNk8Of0", "libkernel", 1, "libkernel", - ORBIS(posix_pthread_attr_getschedparam)); - LIB_FUNCTION("UTXzJbWhhTE", "libkernel", 1, "libkernel", - ORBIS(posix_pthread_attr_setstacksize)); - LIB_FUNCTION("F+yfmduIBB8", "libkernel", 1, "libkernel", - ORBIS(posix_pthread_attr_setstackaddr)); + LIB_FUNCTION("3qxgM4ezETA", "libkernel", 1, "libkernel", ORBIS(scePthreadAttrSetaffinity)); + LIB_FUNCTION("GZSR0Ooae9Q", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_attr_setcreatesuspend_np)); + LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_attr_setdetachstate)); LIB_FUNCTION("El+cQ20DynU", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_setguardsize)); - LIB_FUNCTION("8+s5BzZjxSg", "libkernel", 1, "libkernel", ORBIS(scePthreadAttrGetaffinity)); - LIB_FUNCTION("3qxgM4ezETA", "libkernel", 1, "libkernel", ORBIS(scePthreadAttrSetaffinity)); + LIB_FUNCTION("eXbUSpEaTsA", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_attr_setinheritsched)); + LIB_FUNCTION("DzES9hQF4f4", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_attr_setschedparam)); + LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_attr_setschedpolicy)); + LIB_FUNCTION("YdZfEZfRnPk", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_setscope)); + LIB_FUNCTION("Bvn74vj6oLo", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_setstack)); + LIB_FUNCTION("F+yfmduIBB8", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_attr_setstackaddr)); + LIB_FUNCTION("UTXzJbWhhTE", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_attr_setstacksize)); + LIB_FUNCTION("62KCwEMmzcM", "libkernel", 1, "libkernel", ORBIS(posix_pthread_attr_destroy)); } } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads/rwlock.cpp b/src/core/libraries/kernel/threads/rwlock.cpp index 52109b58d..f1836c020 100644 --- a/src/core/libraries/kernel/threads/rwlock.cpp +++ b/src/core/libraries/kernel/threads/rwlock.cpp @@ -1,14 +1,17 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/elf_info.h" #include "core/libraries/kernel/kernel.h" #include "core/libraries/kernel/posix_error.h" +#include "core/libraries/kernel/process.h" #include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/libs.h" namespace Libraries::Kernel { static std::mutex RwlockStaticLock; +static s32 sdk_version; #define THR_RWLOCK_INITIALIZER ((PthreadRwlock*)NULL) #define THR_RWLOCK_DESTROYED ((PthreadRwlock*)1) @@ -31,6 +34,12 @@ static int RwlockInit(PthreadRwlockT* rwlock, const PthreadRwlockAttrT* attr) { if (prwlock == nullptr) { return POSIX_ENOMEM; } + if (attr != nullptr && sdk_version >= Common::ElfInfo::FW_45) { + if ((*attr)->type > 2) { + delete prwlock; + return POSIX_EINVAL; + } + } *rwlock = prwlock; return 0; } @@ -51,7 +60,11 @@ int PS4_SYSV_ABI posix_pthread_rwlock_destroy(PthreadRwlockT* rwlock) { static int InitStatic(Pthread* thread, PthreadRwlockT* rwlock) { std::scoped_lock lk{RwlockStaticLock}; if (*rwlock == THR_RWLOCK_INITIALIZER) { - return RwlockInit(rwlock, nullptr); + auto* prwlock = new (std::nothrow) PthreadRwlock{}; + if (prwlock == nullptr) { + return POSIX_ENOMEM; + } + *rwlock = prwlock; } return 0; } @@ -208,6 +221,15 @@ int PS4_SYSV_ABI posix_pthread_rwlockattr_getpshared(const PthreadRwlockAttrT* r return 0; } +int PS4_SYSV_ABI posix_pthread_rwlockattr_gettype_np(const PthreadRwlockAttrT* rwlockattr, + int* type) { + if (rwlockattr == nullptr || *rwlockattr == nullptr || (*rwlockattr)->type > 2) { + return POSIX_EINVAL; + } + *type = (*rwlockattr)->type; + return 0; +} + int PS4_SYSV_ABI posix_pthread_rwlockattr_init(PthreadRwlockAttrT* rwlockattr) { if (rwlockattr == nullptr) { return POSIX_EINVAL; @@ -223,6 +245,15 @@ int PS4_SYSV_ABI posix_pthread_rwlockattr_init(PthreadRwlockAttrT* rwlockattr) { return 0; } +int PS4_SYSV_ABI posix_pthread_rwlockattr_settype_np(const PthreadRwlockAttrT* rwlockattr, + int type) { + if (rwlockattr == nullptr || *rwlockattr == nullptr || (*rwlockattr)->type > 2) { + return POSIX_EINVAL; + } + (*rwlockattr)->type = type; + return 0; +} + int PS4_SYSV_ABI posix_pthread_rwlockattr_setpshared(PthreadRwlockAttrT* rwlockattr, int pshared) { /* Only PTHREAD_PROCESS_PRIVATE is supported. */ if (pshared != 0) { @@ -234,6 +265,8 @@ int PS4_SYSV_ABI posix_pthread_rwlockattr_setpshared(PthreadRwlockAttrT* rwlocka } void RegisterRwlock(Core::Loader::SymbolsResolver* sym) { + ASSERT_MSG(sceKernelGetCompiledSdkVersion(&sdk_version) == 0, "Failed to get SDK version"); + // Posix-Kernel LIB_FUNCTION("1471ajPzxh0", "libkernel", 1, "libkernel", posix_pthread_rwlock_destroy); LIB_FUNCTION("ytQULN-nhL4", "libkernel", 1, "libkernel", posix_pthread_rwlock_init); @@ -246,8 +279,10 @@ void RegisterRwlock(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("sIlRvQqsN2Y", "libkernel", 1, "libkernel", posix_pthread_rwlock_wrlock); LIB_FUNCTION("qsdmgXjqSgk", "libkernel", 1, "libkernel", posix_pthread_rwlockattr_destroy); LIB_FUNCTION("VqEMuCv-qHY", "libkernel", 1, "libkernel", posix_pthread_rwlockattr_getpshared); + LIB_FUNCTION("l+bG5fsYkhg", "libkernel", 1, "libkernel", posix_pthread_rwlockattr_gettype_np); LIB_FUNCTION("xFebsA4YsFI", "libkernel", 1, "libkernel", posix_pthread_rwlockattr_init); LIB_FUNCTION("OuKg+kRDD7U", "libkernel", 1, "libkernel", posix_pthread_rwlockattr_setpshared); + LIB_FUNCTION("8NuOHiTr1Vw", "libkernel", 1, "libkernel", posix_pthread_rwlockattr_settype_np); // Posix LIB_FUNCTION("1471ajPzxh0", "libScePosix", 1, "libkernel", posix_pthread_rwlock_destroy); @@ -261,17 +296,23 @@ void RegisterRwlock(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("sIlRvQqsN2Y", "libScePosix", 1, "libkernel", posix_pthread_rwlock_wrlock); LIB_FUNCTION("qsdmgXjqSgk", "libScePosix", 1, "libkernel", posix_pthread_rwlockattr_destroy); LIB_FUNCTION("VqEMuCv-qHY", "libScePosix", 1, "libkernel", posix_pthread_rwlockattr_getpshared); + LIB_FUNCTION("l+bG5fsYkhg", "libScePosix", 1, "libkernel", posix_pthread_rwlockattr_gettype_np); LIB_FUNCTION("xFebsA4YsFI", "libScePosix", 1, "libkernel", posix_pthread_rwlockattr_init); LIB_FUNCTION("OuKg+kRDD7U", "libScePosix", 1, "libkernel", posix_pthread_rwlockattr_setpshared); + LIB_FUNCTION("8NuOHiTr1Vw", "libScePosix", 1, "libkernel", posix_pthread_rwlockattr_settype_np); // Orbis LIB_FUNCTION("i2ifZ3fS2fo", "libkernel", 1, "libkernel", ORBIS(posix_pthread_rwlockattr_destroy)); LIB_FUNCTION("LcOZBHGqbFk", "libkernel", 1, "libkernel", ORBIS(posix_pthread_rwlockattr_getpshared)); + LIB_FUNCTION("Kyls1ChFyrc", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_rwlockattr_gettype_np)); LIB_FUNCTION("yOfGg-I1ZII", "libkernel", 1, "libkernel", ORBIS(posix_pthread_rwlockattr_init)); LIB_FUNCTION("-ZvQH18j10c", "libkernel", 1, "libkernel", ORBIS(posix_pthread_rwlockattr_setpshared)); + LIB_FUNCTION("h-OifiouBd8", "libkernel", 1, "libkernel", + ORBIS(posix_pthread_rwlockattr_settype_np)); LIB_FUNCTION("BB+kb08Tl9A", "libkernel", 1, "libkernel", ORBIS(posix_pthread_rwlock_destroy)); LIB_FUNCTION("6ULAa0fq4jA", "libkernel", 1, "libkernel", ORBIS(posix_pthread_rwlock_init)); LIB_FUNCTION("Ox9i0c7L5w0", "libkernel", 1, "libkernel", ORBIS(posix_pthread_rwlock_rdlock));