thread keys implementation

This commit is contained in:
georgemoralis 2023-10-05 12:17:14 +03:00
parent ab76f33733
commit 0297a3952b
3 changed files with 246 additions and 66 deletions

View File

@ -3,16 +3,22 @@
#include <Core/PS4/HLE/ErrorCodes.h> #include <Core/PS4/HLE/ErrorCodes.h>
#include <debug.h> #include <debug.h>
#include "Util/Singleton.h"
#include <inttypes.h>
namespace HLE::Libs::LibKernel::ThreadManagement { namespace HLE::Libs::LibKernel::ThreadManagement {
thread_local PthreadInternal* g_pthread_self = nullptr; thread_local PthreadInternal* g_pthread_self = nullptr;
PThreadCxt* g_pthread_cxt = nullptr;
void Pthread_Init_Self_MainThread() { void Pthread_Init_Self_MainThread() {
g_pthread_self = new PthreadInternal{}; g_pthread_self = new PthreadInternal{};
scePthreadAttrInit(&g_pthread_self->attr); scePthreadAttrInit(&g_pthread_self->attr);
g_pthread_self->pth = pthread_self(); g_pthread_self->pth = pthread_self();
g_pthread_self->name = "Main_Thread"; g_pthread_self->name = "Main_Thread";
// temp!
auto* threadCtx = Singleton<PThreadCxt>::Instance();
threadCtx->setPthreadKeys(new PthreadKeys);
} }
int PS4_SYSV_ABI scePthreadAttrInit(ScePthreadAttr* attr) { int PS4_SYSV_ABI scePthreadAttrInit(ScePthreadAttr* attr) {
@ -193,6 +199,7 @@ int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMut
} }
int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex) { int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex) {
printf("scePthreadMutexLock\n");
static int count = 0; static int count = 0;
std::string name = "internal mutex "; std::string name = "internal mutex ";
name += std::to_string(count); name += std::to_string(count);
@ -211,6 +218,7 @@ int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex) {
} }
} }
int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex) { int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex) {
printf("scePthreadMutexUnlock\n");
if (mutex == nullptr) { if (mutex == nullptr) {
return SCE_KERNEL_ERROR_EINVAL; return SCE_KERNEL_ERROR_EINVAL;
} }
@ -227,7 +235,6 @@ int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex) {
} }
int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr) { int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr) {
*attr = new PthreadCondAttrInternal{}; *attr = new PthreadCondAttrInternal{};
int result = pthread_condattr_init(&(*attr)->cond_attr); int result = pthread_condattr_init(&(*attr)->cond_attr);
@ -267,7 +274,6 @@ int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondat
} }
} }
int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond) { int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond) {
static int count = 0; static int count = 0;
std::string name = "internal cond "; std::string name = "internal cond ";
name += std::to_string(count); name += std::to_string(count);
@ -286,4 +292,109 @@ int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond) {
return (result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL); return (result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL);
} }
bool PthreadKeys::createKey(int* key, PthreadKeyDestructor destructor) {
Lib::LockMutexGuard lock(m_mutex);
for (int index = 0; index < 256; index++) {
if (!m_keys[index].used) {
*key = index;
m_keys[index].used = true;
m_keys[index].destructor = destructor;
m_keys[index].specific_values.clear();
return true;
}
}
return false;
}
bool PthreadKeys::getKey(int key, int thread_id, void** data) {
Lib::LockMutexGuard lock(m_mutex);
if (key < 0 || key >= 256 || !m_keys[key].used) {
return false;
}
for (auto& v : m_keys[key].specific_values) {
if (v.thread_id == thread_id) {
*data = v.data;
return true;
}
}
*data = nullptr;
return true;
}
bool PthreadKeys::setKey(int key, int thread_id, void* data) {
Lib::LockMutexGuard lock(m_mutex);
if (key < 0 || key >= 256 || !m_keys[key].used) {
return false;
}
for (auto& v : m_keys[key].specific_values) {
if (v.thread_id == thread_id) {
v.data = data;
return true;
}
}
m_keys[key].specific_values.push_back(Map({thread_id, data}));
return true;
}
int PS4_SYSV_ABI scePthreadKeyCreate(ScePthreadKey* key, PthreadKeyDestructor destructor) {
if (key == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
auto* threadCtx = Singleton<PThreadCxt>::Instance();
if (!threadCtx->getPthreadKeys()->createKey(key, destructor)) {
return SCE_KERNEL_ERROR_EAGAIN;
}
printf("scePthreadKeyCreate\n");
printf("destructor = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(destructor));
printf("key = %d\n", *key);
return SCE_OK;
}
void* PS4_SYSV_ABI scePthreadGetspecific(ScePthreadKey key) {
int thread_id = Lib::Thread::GetThreadIdUnique();
printf("scePthreadGetspecific\n");
printf("key = %d\n", key);
printf("thread_id = %d\n", thread_id);
void* value = nullptr;
auto* threadCtx = Singleton<PThreadCxt>::Instance();
if (!threadCtx->getPthreadKeys()->getKey(key, thread_id, &value)) {
return nullptr;
}
printf("value = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(value));
return value;
}
int PS4_SYSV_ABI scePthreadSetspecific(ScePthreadKey key, /* const*/ void* value) {
int thread_id = Lib::Thread::GetThreadIdUnique();
printf("scePthreadSetspecific\n");
printf("key = %d\n", key);
printf("thread_id = %d\n", thread_id);
printf("value = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(value));
auto* threadCtx = Singleton<PThreadCxt>::Instance();
if (!threadCtx->getPthreadKeys()->setKey(key, thread_id, value)) {
return SCE_KERNEL_ERROR_EINVAL;
}
return SCE_OK;
}
}; // namespace HLE::Libs::LibKernel::ThreadManagement }; // namespace HLE::Libs::LibKernel::ThreadManagement

View File

@ -3,8 +3,9 @@
#include <pthread.h> #include <pthread.h>
#include <sched.h> #include <sched.h>
#include <types.h> #include <types.h>
#include <vector>
#include <string> #include <string>
#include "Lib/Threads.h"
namespace HLE::Libs::LibKernel::ThreadManagement { namespace HLE::Libs::LibKernel::ThreadManagement {
@ -14,6 +15,7 @@ struct PthreadMutexAttrInternal;
struct PthreadCondAttrInternal; struct PthreadCondAttrInternal;
struct PthreadCondInternal; struct PthreadCondInternal;
struct PtheadOnceInternal; struct PtheadOnceInternal;
class PthreadKeys;
using SceKernelSchedParam = ::sched_param; using SceKernelSchedParam = ::sched_param;
using ScePthreadAttr = PthreadAttrInternal*; using ScePthreadAttr = PthreadAttrInternal*;
@ -22,6 +24,9 @@ using ScePthreadMutexattr = PthreadMutexAttrInternal*;
using ScePthreadCondattr = PthreadCondAttrInternal*; using ScePthreadCondattr = PthreadCondAttrInternal*;
using ScePthreadCond = PthreadCondInternal*; using ScePthreadCond = PthreadCondInternal*;
using ScePthreadOnce = PtheadOnceInternal*; using ScePthreadOnce = PtheadOnceInternal*;
using ScePthreadKey = int;
using PthreadKeyDestructor = PS4_SYSV_ABI void (*)(void*);
struct PthreadInternal { struct PthreadInternal {
u08 reserved[4096]; u08 reserved[4096];
@ -66,7 +71,38 @@ struct PtheadOnceInternal {
pthread_once_t pthreadOnce; pthread_once_t pthreadOnce;
}; };
class PThreadCxt {}; class PThreadCxt {
public:
PthreadKeys* getPthreadKeys() { return m_pthread_keys; }
void setPthreadKeys(PthreadKeys* keys) { m_pthread_keys = keys; }
private:
PthreadKeys* m_pthread_keys = nullptr;
};
class PthreadKeys {
public:
PthreadKeys() { }
virtual ~PthreadKeys() { }
bool createKey(int* key, PthreadKeyDestructor destructor);
bool getKey(int key, int thread_id, void** data);
bool setKey(int key, int thread_id, void* data);
private:
struct Map {
int thread_id = -1;
void* data = nullptr;
};
struct Key {
bool used = false;
PthreadKeyDestructor destructor = nullptr;
std::vector<Map> specific_values;
};
Lib::Mutex m_mutex;
Key m_keys[256];
};
void Pthread_Init_Self_MainThread(); void Pthread_Init_Self_MainThread();
@ -86,4 +122,8 @@ int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr);
int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond); int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond);
int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondattr* attr, const char* name); int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondattr* attr, const char* name);
int PS4_SYSV_ABI scePthreadOnce(ScePthreadOnce* once_control, void (*init_routine)(void)); int PS4_SYSV_ABI scePthreadOnce(ScePthreadOnce* once_control, void (*init_routine)(void));
int PS4_SYSV_ABI scePthreadKeyCreate(ScePthreadKey* key, PthreadKeyDestructor destructor);
void* PS4_SYSV_ABI scePthreadGetspecific(ScePthreadKey key);
int PS4_SYSV_ABI scePthreadSetspecific(ScePthreadKey key, /* const*/ void* value);
} // namespace HLE::Libs::LibKernel::ThreadManagement } // namespace HLE::Libs::LibKernel::ThreadManagement

View File

@ -2,6 +2,9 @@
#include <Util/log.h> #include <Util/log.h>
#include <debug.h> #include <debug.h>
#include <io.h>
#include <sys/types.h>
#include <windows.h>
#include "../../../Util/Singleton.h" #include "../../../Util/Singleton.h"
#include "../Loader/Elf.h" #include "../Loader/Elf.h"
@ -11,9 +14,6 @@
#include "Kernel/event_queues.h" #include "Kernel/event_queues.h"
#include "Kernel/memory_management.h" #include "Kernel/memory_management.h"
#include "Libs.h" #include "Libs.h"
#include <io.h>
#include <windows.h>
#include <sys/types.h>
namespace HLE::Libs::LibKernel { namespace HLE::Libs::LibKernel {
@ -41,6 +41,8 @@ PS4_SYSV_ABI void _write() { BREAKPOINT(); }
PS4_SYSV_ABI void sigaction() { BREAKPOINT(); } PS4_SYSV_ABI void sigaction() { BREAKPOINT(); }
PS4_SYSV_ABI void _exit() { BREAKPOINT(); } PS4_SYSV_ABI void _exit() { BREAKPOINT(); }
namespace POSIX {
PS4_SYSV_ABI int pthread_cond_broadcast(ThreadManagement::ScePthreadCond* cond) { PS4_SYSV_ABI int pthread_cond_broadcast(ThreadManagement::ScePthreadCond* cond) {
// posix call the difference is that there is a different behaviour when it doesn't return 0 or SCE_OK // posix call the difference is that there is a different behaviour when it doesn't return 0 or SCE_OK
int result = ThreadManagement::scePthreadCondBroadcast(cond); int result = ThreadManagement::scePthreadCondBroadcast(cond);
@ -53,7 +55,15 @@ PS4_SYSV_ABI void pthread_rwlock_wrlock() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_cond_destroy() { BREAKPOINT(); } PS4_SYSV_ABI void pthread_cond_destroy() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_rwlock_rdlock() { BREAKPOINT(); } PS4_SYSV_ABI void pthread_rwlock_rdlock() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_setspecific() { BREAKPOINT(); }
PS4_SYSV_ABI int pthread_setspecific(ThreadManagement::ScePthreadKey key, /* const*/ void* value) {
// posix call the difference is that there is a different behaviour when it doesn't return 0 or SCE_OK
int result = ThreadManagement::scePthreadSetspecific(key, value);
if (result != 0) {
BREAKPOINT();
}
return result;
}
PS4_SYSV_ABI void pthread_equal() { BREAKPOINT(); } PS4_SYSV_ABI void pthread_equal() { BREAKPOINT(); }
PS4_SYSV_ABI int pthread_mutex_unlock(ThreadManagement::ScePthreadMutex* mutex) { PS4_SYSV_ABI int pthread_mutex_unlock(ThreadManagement::ScePthreadMutex* mutex) {
// posix call the difference is that there is a different behaviour when it doesn't return 0 or SCE_OK // posix call the difference is that there is a different behaviour when it doesn't return 0 or SCE_OK
@ -63,8 +73,8 @@ PS4_SYSV_ABI int pthread_mutex_unlock(ThreadManagement::ScePthreadMutex* mutex)
} }
return result; return result;
} }
PS4_SYSV_ABI void pthread_cond_timedwait() { BREAKPOINT(); } PS4_SYSV_ABI void pthread_cond_timedwait() { BREAKPOINT(); }
PS4_SYSV_ABI void poll() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_rwlock_unlock() { BREAKPOINT(); } PS4_SYSV_ABI void pthread_rwlock_unlock() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_detach() { BREAKPOINT(); } PS4_SYSV_ABI void pthread_detach() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_mutexattr_init() { BREAKPOINT(); } PS4_SYSV_ABI void pthread_mutexattr_init() { BREAKPOINT(); }
@ -76,10 +86,45 @@ int PS4_SYSV_ABI pthread_mutex_lock(ThreadManagement::ScePthreadMutex* mutex) {
} }
return result; return result;
} }
PS4_SYSV_ABI void munmap() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_mutex_destroy() { BREAKPOINT(); } PS4_SYSV_ABI void pthread_mutex_destroy() { BREAKPOINT(); }
PS4_SYSV_ABI void sceKernelUsleep() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_mutex_trylock() { BREAKPOINT(); } PS4_SYSV_ABI void pthread_mutex_trylock() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_join() { BREAKPOINT(); }
PS4_SYSV_ABI void* pthread_getspecific(ThreadManagement::ScePthreadKey key) {
return HLE::Libs::LibKernel::ThreadManagement::scePthreadGetspecific(key);
}
PS4_SYSV_ABI void pthread_mutexattr_destroy() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_self() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_mutex_init() { BREAKPOINT(); }
PS4_SYSV_ABI int _pthread_once(ThreadManagement::ScePthreadOnce* once_control, void (*init_routine)(void)) {
// posix call the difference is that there is a different behaviour when it doesn't return 0 or SCE_OK
HLE::Libs::LibKernel::ThreadManagement::ScePthreadOnce o1nce_control = 0;
*once_control = new HLE::Libs::LibKernel::ThreadManagement::PtheadOnceInternal{};
(*once_control)->pthreadOnce = 0;
int result = pthread_once(&(*once_control)->pthreadOnce, init_routine);
if (result != 0) {
BREAKPOINT();
}
return result;
}
PS4_SYSV_ABI void pthread_cond_wait() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_mutexattr_settype() { BREAKPOINT(); }
int PS4_SYSV_ABI pthread_key_create(ThreadManagement::ScePthreadKey* key, ThreadManagement::PthreadKeyDestructor destructor) {
int result = HLE::Libs::LibKernel::ThreadManagement::scePthreadKeyCreate(key, destructor);
if (result != 0) {
BREAKPOINT();
}
return result;
}
PS4_SYSV_ABI void pthread_cond_signal() { BREAKPOINT(); }
}; // namespace POSIX
PS4_SYSV_ABI void poll() { BREAKPOINT(); }
PS4_SYSV_ABI void munmap() { BREAKPOINT(); }
PS4_SYSV_ABI void sceKernelUsleep() { BREAKPOINT(); }
#define PROT_READ 0x1 #define PROT_READ 0x1
#define PROT_WRITE 0x2 #define PROT_WRITE 0x2
@ -122,37 +167,21 @@ PS4_SYSV_ABI int mmap(void* addr, u64 len, int prot, int flags, int fd, u64 offs
} }
return result; return result;
} }
PS4_SYSV_ABI void pthread_join() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_getspecific() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_mutexattr_destroy() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_self() { BREAKPOINT(); }
PS4_SYSV_ABI void close() { BREAKPOINT(); } PS4_SYSV_ABI void close() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_mutexattr_settype() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_key_create() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_mutex_init() { BREAKPOINT(); }
PS4_SYSV_ABI void madvise() { BREAKPOINT(); } PS4_SYSV_ABI void madvise() { BREAKPOINT(); }
PS4_SYSV_ABI void _writev() { BREAKPOINT(); } PS4_SYSV_ABI void _writev() { BREAKPOINT(); }
PS4_SYSV_ABI void lseek() { BREAKPOINT(); } PS4_SYSV_ABI void lseek() { BREAKPOINT(); }
PS4_SYSV_ABI int* __error() { return _errno(); } PS4_SYSV_ABI int* __error() { return _errno(); }
PS4_SYSV_ABI int _pthread_once(ThreadManagement::ScePthreadOnce* once_control, void (*init_routine)(void)) {
// posix call the difference is that there is a different behaviour when it doesn't return 0 or SCE_OK
HLE::Libs::LibKernel::ThreadManagement::ScePthreadOnce o1nce_control = 0;
*once_control = new HLE::Libs::LibKernel::ThreadManagement::PtheadOnceInternal{};
(*once_control)->pthreadOnce = 0;
int result = pthread_once(&(*once_control)->pthreadOnce, init_routine);
if (result != 0) {
BREAKPOINT();
}
return result;
}
PS4_SYSV_ABI void pthread_cond_wait() { BREAKPOINT(); }
PS4_SYSV_ABI void raise() { BREAKPOINT(); } PS4_SYSV_ABI void raise() { BREAKPOINT(); }
PS4_SYSV_ABI void pthread_cond_signal() { BREAKPOINT(); }
PS4_SYSV_ABI void _ioctl() { BREAKPOINT(); } PS4_SYSV_ABI void _ioctl() { BREAKPOINT(); }
PS4_SYSV_ABI void fstat() { BREAKPOINT(); } PS4_SYSV_ABI void fstat() { BREAKPOINT(); }
void LibKernel_Register(SymbolsResolver* sym) { void LibKernel_Register(SymbolsResolver* sym) {
// obj // obj
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &HLE::Libs::LibKernel::g_stack_chk_guard); LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &HLE::Libs::LibKernel::g_stack_chk_guard);
@ -191,40 +220,40 @@ void LibKernel_Register(SymbolsResolver* sym) {
LIB_FUNCTION("FxVZqBAA7ks", "libkernel", 1, "libkernel", 1, 1, _write); LIB_FUNCTION("FxVZqBAA7ks", "libkernel", 1, "libkernel", 1, 1, _write);
LIB_FUNCTION("KiJEPEWRyUY", "libkernel", 1, "libkernel", 1, 1, sigaction); LIB_FUNCTION("KiJEPEWRyUY", "libkernel", 1, "libkernel", 1, 1, sigaction);
LIB_FUNCTION("6Z83sYWFlA8", "libkernel", 1, "libkernel", 1, 1, _exit); LIB_FUNCTION("6Z83sYWFlA8", "libkernel", 1, "libkernel", 1, 1, _exit);
LIB_FUNCTION("mkx2fVhNMsg", "libkernel", 1, "libkernel", 1, 1, pthread_cond_broadcast); LIB_FUNCTION("mkx2fVhNMsg", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_cond_broadcast);
LIB_FUNCTION("sIlRvQqsN2Y", "libkernel", 1, "libkernel", 1, 1, pthread_rwlock_wrlock); LIB_FUNCTION("sIlRvQqsN2Y", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_rwlock_wrlock);
LIB_FUNCTION("RXXqi4CtF8w", "libkernel", 1, "libkernel", 1, 1, pthread_cond_destroy); LIB_FUNCTION("RXXqi4CtF8w", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_cond_destroy);
LIB_FUNCTION("iGjsr1WAtI0", "libkernel", 1, "libkernel", 1, 1, pthread_rwlock_rdlock); LIB_FUNCTION("iGjsr1WAtI0", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_rwlock_rdlock);
LIB_FUNCTION("WrOLvHU0yQM", "libkernel", 1, "libkernel", 1, 1, pthread_setspecific); LIB_FUNCTION("WrOLvHU0yQM", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_setspecific);
LIB_FUNCTION("7Xl257M4VNI", "libkernel", 1, "libkernel", 1, 1, pthread_equal); LIB_FUNCTION("7Xl257M4VNI", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_equal);
LIB_FUNCTION("2Z+PpY6CaJg", "libkernel", 1, "libkernel", 1, 1, pthread_mutex_unlock); LIB_FUNCTION("2Z+PpY6CaJg", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_mutex_unlock);
LIB_FUNCTION("27bAgiJmOh0", "libkernel", 1, "libkernel", 1, 1, pthread_cond_timedwait); LIB_FUNCTION("27bAgiJmOh0", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_cond_timedwait);
LIB_FUNCTION("ku7D4q1Y9PI", "libkernel", 1, "libkernel", 1, 1, poll); LIB_FUNCTION("ku7D4q1Y9PI", "libkernel", 1, "libkernel", 1, 1, poll);
LIB_FUNCTION("EgmLo6EWgso", "libkernel", 1, "libkernel", 1, 1, pthread_rwlock_unlock); LIB_FUNCTION("EgmLo6EWgso", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_rwlock_unlock);
LIB_FUNCTION("+U1R4WtXvoc", "libkernel", 1, "libkernel", 1, 1, pthread_detach); LIB_FUNCTION("+U1R4WtXvoc", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_detach);
LIB_FUNCTION("dQHWEsJtoE4", "libkernel", 1, "libkernel", 1, 1, pthread_mutexattr_init); LIB_FUNCTION("dQHWEsJtoE4", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_mutexattr_init);
LIB_FUNCTION("7H0iTOciTLo", "libkernel", 1, "libkernel", 1, 1, pthread_mutex_lock); LIB_FUNCTION("7H0iTOciTLo", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_mutex_lock);
LIB_FUNCTION("UqDGjXA5yUM", "libkernel", 1, "libkernel", 1, 1, munmap); LIB_FUNCTION("UqDGjXA5yUM", "libkernel", 1, "libkernel", 1, 1, munmap);
LIB_FUNCTION("ltCfaGr2JGE", "libkernel", 1, "libkernel", 1, 1, pthread_mutex_destroy); LIB_FUNCTION("ltCfaGr2JGE", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_mutex_destroy);
LIB_FUNCTION("1jfXLRVzisc", "libkernel", 1, "libkernel", 1, 1, sceKernelUsleep); LIB_FUNCTION("1jfXLRVzisc", "libkernel", 1, "libkernel", 1, 1, sceKernelUsleep);
LIB_FUNCTION("K-jXhbt2gn4", "libkernel", 1, "libkernel", 1, 1, pthread_mutex_trylock); LIB_FUNCTION("K-jXhbt2gn4", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_mutex_trylock);
LIB_FUNCTION("BPE9s9vQQXo", "libkernel", 1, "libkernel", 1, 1, mmap); LIB_FUNCTION("BPE9s9vQQXo", "libkernel", 1, "libkernel", 1, 1, mmap);
LIB_FUNCTION("h9CcP3J0oVM", "libkernel", 1, "libkernel", 1, 1, pthread_join); LIB_FUNCTION("h9CcP3J0oVM", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_join);
LIB_FUNCTION("0-KXaS70xy4", "libkernel", 1, "libkernel", 1, 1, pthread_getspecific); LIB_FUNCTION("0-KXaS70xy4", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_getspecific);
LIB_FUNCTION("HF7lK46xzjY", "libkernel", 1, "libkernel", 1, 1, pthread_mutexattr_destroy); LIB_FUNCTION("HF7lK46xzjY", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_mutexattr_destroy);
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, pthread_self); LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_self);
LIB_FUNCTION("bY-PO6JhzhQ", "libkernel", 1, "libkernel", 1, 1, close); LIB_FUNCTION("bY-PO6JhzhQ", "libkernel", 1, "libkernel", 1, 1, close);
LIB_FUNCTION("mDmgMOGVUqg", "libkernel", 1, "libkernel", 1, 1, pthread_mutexattr_settype); LIB_FUNCTION("mDmgMOGVUqg", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_mutexattr_settype);
LIB_FUNCTION("mqULNdimTn0", "libkernel", 1, "libkernel", 1, 1, pthread_key_create); LIB_FUNCTION("mqULNdimTn0", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_key_create);
LIB_FUNCTION("ttHNfU+qDBU", "libkernel", 1, "libkernel", 1, 1, pthread_mutex_init); LIB_FUNCTION("ttHNfU+qDBU", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_mutex_init);
LIB_FUNCTION("Jahsnh4KKkg", "libkernel", 1, "libkernel", 1, 1, madvise); LIB_FUNCTION("Jahsnh4KKkg", "libkernel", 1, "libkernel", 1, 1, madvise);
LIB_FUNCTION("YSHRBRLn2pI", "libkernel", 1, "libkernel", 1, 1, _writev); LIB_FUNCTION("YSHRBRLn2pI", "libkernel", 1, "libkernel", 1, 1, _writev);
LIB_FUNCTION("Oy6IpwgtYOk", "libkernel", 1, "libkernel", 1, 1, lseek); LIB_FUNCTION("Oy6IpwgtYOk", "libkernel", 1, "libkernel", 1, 1, lseek);
LIB_FUNCTION("9BcDykPmo1I", "libkernel", 1, "libkernel", 1, 1, __error); LIB_FUNCTION("9BcDykPmo1I", "libkernel", 1, "libkernel", 1, 1, __error);
LIB_FUNCTION("Z4QosVuAsA0", "libkernel", 1, "libkernel", 1, 1, _pthread_once); LIB_FUNCTION("Z4QosVuAsA0", "libkernel", 1, "libkernel", 1, 1, POSIX::_pthread_once);
LIB_FUNCTION("Op8TBGY5KHg", "libkernel", 1, "libkernel", 1, 1, pthread_cond_wait); LIB_FUNCTION("Op8TBGY5KHg", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_cond_wait);
LIB_FUNCTION("0t0-MxQNwK4", "libkernel", 1, "libkernel", 1, 1, raise); LIB_FUNCTION("0t0-MxQNwK4", "libkernel", 1, "libkernel", 1, 1, raise);
LIB_FUNCTION("2MOy+rUfuhQ", "libkernel", 1, "libkernel", 1, 1, pthread_cond_signal); LIB_FUNCTION("2MOy+rUfuhQ", "libkernel", 1, "libkernel", 1, 1, POSIX::pthread_cond_signal);
LIB_FUNCTION("wW+k21cmbwQ", "libkernel", 1, "libkernel", 1, 1, _ioctl); LIB_FUNCTION("wW+k21cmbwQ", "libkernel", 1, "libkernel", 1, 1, _ioctl);
} }