rewrote threadCond functions

This commit is contained in:
georgemoralis 2024-06-09 11:39:04 +03:00
parent 9db200e773
commit 4c0e24b076
5 changed files with 393 additions and 243 deletions

View File

@ -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.cpp
src/core/libraries/kernel/event_flag/event_flag_obj.h 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.h
src/core/libraries/kernel/threads/kernel_threads_cond.cpp
src/core/libraries/kernel/threads/kernel_threads_rwlock.cpp src/core/libraries/kernel/threads/kernel_threads_rwlock.cpp
src/core/libraries/kernel/cpu_management.cpp src/core/libraries/kernel/cpu_management.cpp
src/core/libraries/kernel/cpu_management.h src/core/libraries/kernel/cpu_management.h

View File

@ -28,13 +28,17 @@ void init_pthreads() {
scePthreadMutexattrInit(&default_mutexattr); scePthreadMutexattrInit(&default_mutexattr);
g_pthread_cxt->setDefaultMutexattr(default_mutexattr); g_pthread_cxt->setDefaultMutexattr(default_mutexattr);
// default cond init // default cond init
ScePthreadCondattr default_condattr = nullptr; OrbisPthreadCondattr default_condattr = nullptr;
scePthreadCondattrInit(&default_condattr); scePthreadCondattrInit(&default_condattr);
g_pthread_cxt->setDefaultCondattr(default_condattr); g_pthread_cxt->setDefaultCondattr(default_condattr);
// default attr init // default attr init
ScePthreadAttr default_attr = nullptr; ScePthreadAttr default_attr = nullptr;
scePthreadAttrInit(&default_attr); scePthreadAttrInit(&default_attr);
g_pthread_cxt->SetDefaultAttr(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); 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<ScePthreadCond*>(addr) != nullptr) {
return addr;
}
auto vaddr = reinterpret_cast<u64>(addr);
std::string name = fmt::format("cond{:#x}", vaddr);
scePthreadCondInit(static_cast<ScePthreadCond*>(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<ScePthreadCond*>(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<ScePthreadCond*>(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) { int PS4_SYSV_ABI posix_pthread_mutex_init(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr) {
// LOG_INFO(Kernel_Pthread, "posix pthread_mutex_init redirect to scePthreadMutexInit"); // LOG_INFO(Kernel_Pthread, "posix pthread_mutex_init redirect to scePthreadMutexInit");
int result = scePthreadMutexInit(mutex, attr, nullptr); int result = scePthreadMutexInit(mutex, attr, nullptr);
@ -754,27 +632,6 @@ int PS4_SYSV_ABI posix_pthread_mutex_destroy(ScePthreadMutex* mutex) {
return result; 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) { int PS4_SYSV_ABI posix_pthread_mutexattr_init(ScePthreadMutexattr* attr) {
// LOG_INFO(Kernel_Pthread, "posix pthread_mutexattr_init redirect to scePthreadMutexattrInit"); // LOG_INFO(Kernel_Pthread, "posix pthread_mutexattr_init redirect to scePthreadMutexattrInit");
int result = scePthreadMutexattrInit(attr); int result = scePthreadMutexattrInit(attr);
@ -1064,67 +921,6 @@ ScePthread PS4_SYSV_ABI posix_pthread_self() {
return g_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<ScePthreadCond*>(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) { int PS4_SYSV_ABI scePthreadMutexTrylock(ScePthreadMutex* mutex) {
if (mutex == nullptr) { if (mutex == nullptr) {
@ -1229,13 +1025,6 @@ int PS4_SYSV_ABI posix_pthread_create(ScePthread* thread, const ScePthreadAttr*
return result; 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) { void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy); LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy);
LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate); 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_equal);
LIB_FUNCTION("7Xl257M4VNI", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_join); 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("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("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSelf);
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self); 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("9UK1vLZQft4", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexLock);
LIB_FUNCTION("tn3VlD0hG60", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexUnlock); LIB_FUNCTION("tn3VlD0hG60", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexUnlock);
LIB_FUNCTION("upoVrzMHFeE", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexTrylock); 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 // posix calls
LIB_FUNCTION("wtkt-teR1so", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_init); 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("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("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("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("dQHWEsJtoE4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutexattr_init);
LIB_FUNCTION("mDmgMOGVUqg", "libScePosix", 1, "libkernel", 1, 1, LIB_FUNCTION("mDmgMOGVUqg", "libScePosix", 1, "libkernel", 1, 1,
posix_pthread_mutexattr_settype); posix_pthread_mutexattr_settype);
@ -1310,7 +1087,7 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
// openorbis weird functions // openorbis weird functions
LIB_FUNCTION("7H0iTOciTLo", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_lock); 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("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("K-jXhbt2gn4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_trylock);
LIB_FUNCTION("E+tyo3lp5Lw", "libScePosix", 1, "libkernel", 1, 1, LIB_FUNCTION("E+tyo3lp5Lw", "libScePosix", 1, "libkernel", 1, 1,
posix_pthread_attr_setdetachstate); 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); LIB_FUNCTION("m0iS6jNsXds", "libScePosix", 1, "libkernel", 1, 1, posix_sched_get_priority_min);
// libs // libs
ThreadsRwlockSymbolsRegister(sym); ThreadsRwlockSymbolsRegister(sym);
ThreadsCondSymbolsRegister(sym);
} }
} // namespace Libraries::Kernel } // namespace Libraries::Kernel

View File

@ -34,8 +34,8 @@ using ScePthread = PthreadInternal*;
using ScePthreadAttr = PthreadAttrInternal*; using ScePthreadAttr = PthreadAttrInternal*;
using ScePthreadMutex = PthreadMutexInternal*; using ScePthreadMutex = PthreadMutexInternal*;
using ScePthreadMutexattr = PthreadMutexattrInternal*; using ScePthreadMutexattr = PthreadMutexattrInternal*;
using ScePthreadCond = PthreadCondInternal*; using OrbisPthreadCond = PthreadCondInternal*;
using ScePthreadCondattr = PthreadCondAttrInternal*; using OrbisPthreadCondattr = PthreadCondAttrInternal*;
using OrbisPthreadRwlock = PthreadRwInternal*; using OrbisPthreadRwlock = PthreadRwInternal*;
using OrbisPthreadRwlockattr = PthreadRwLockAttrInernal*; using OrbisPthreadRwlockattr = PthreadRwLockAttrInernal*;
@ -119,10 +119,10 @@ public:
void setDefaultMutexattr(ScePthreadMutexattr attr) { void setDefaultMutexattr(ScePthreadMutexattr attr) {
m_default_mutexattr = attr; m_default_mutexattr = attr;
} }
ScePthreadCondattr* getDefaultCondattr() { OrbisPthreadCondattr* getDefaultCondattr() {
return &m_default_condattr; return &m_default_condattr;
} }
void setDefaultCondattr(ScePthreadCondattr attr) { void setDefaultCondattr(OrbisPthreadCondattr attr) {
m_default_condattr = attr; m_default_condattr = attr;
} }
ScePthreadAttr* GetDefaultAttr() { ScePthreadAttr* GetDefaultAttr() {
@ -146,7 +146,7 @@ public:
private: private:
ScePthreadMutexattr m_default_mutexattr = nullptr; ScePthreadMutexattr m_default_mutexattr = nullptr;
ScePthreadCondattr m_default_condattr = nullptr; OrbisPthreadCondattr m_default_condattr = nullptr;
ScePthreadAttr m_default_attr = nullptr; ScePthreadAttr m_default_attr = nullptr;
PThreadPool* m_pthread_pool = nullptr; PThreadPool* m_pthread_pool = nullptr;
OrbisPthreadRwlockattr m_default_Rwattr = 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 scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int protocol);
int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex); int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex);
int PS4_SYSV_ABI scePthreadMutexUnlock(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 * Posix calls
*/ */
int PS4_SYSV_ABI posix_pthread_mutex_init(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr); 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_lock(ScePthreadMutex* mutex);
int PS4_SYSV_ABI posix_pthread_mutex_unlock(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); void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Kernel } // namespace Libraries::Kernel

View File

@ -10,6 +10,40 @@ class SymbolsResolver;
} }
namespace Libraries::Kernel { 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 * rwlock calls
*/ */
@ -49,5 +83,6 @@ int PS4_SYSV_ABI scePthreadRwlockTrywrlock(OrbisPthreadRwlock* rwlock);
int PS4_SYSV_ABI scePthreadRwlockUnlock(OrbisPthreadRwlock* rwlock); int PS4_SYSV_ABI scePthreadRwlockUnlock(OrbisPthreadRwlock* rwlock);
int PS4_SYSV_ABI scePthreadRwlockWrlock(OrbisPthreadRwlock* rwlock); int PS4_SYSV_ABI scePthreadRwlockWrlock(OrbisPthreadRwlock* rwlock);
void ThreadsCondSymbolsRegister(Core::Loader::SymbolsResolver* sym);
void ThreadsRwlockSymbolsRegister(Core::Loader::SymbolsResolver* sym); void ThreadsRwlockSymbolsRegister(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Kernel } // namespace Libraries::Kernel

View File

@ -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<OrbisPthreadCond*>(addr) != nullptr) {
return addr;
}
posix_pthread_cond_init(static_cast<OrbisPthreadCond*>(addr), nullptr);
return addr;
}
int PS4_SYSV_ABI posix_pthread_cond_broadcast(OrbisPthreadCond* cond) {
if (*cond == nullptr) {
cond = static_cast<OrbisPthreadCond*>(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<OrbisPthreadCond*>(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<OrbisPthreadCond*>(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<OrbisPthreadCond*>(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