kernel: Pthread rewrite touchups for Windows

This commit is contained in:
Daniel R. 2024-10-25 16:36:38 +03:00 committed by IndecisiveTurtle
parent 4639998a19
commit 8c5b3f5f38
11 changed files with 63 additions and 54 deletions

View file

@ -70,21 +70,19 @@ public:
} }
void Execute(OrbisImeEventHandler handler, OrbisImeEvent* event, bool use_param_handler) { void Execute(OrbisImeEventHandler handler, OrbisImeEvent* event, bool use_param_handler) {
const auto* linker = Common::Singleton<Core::Linker>::Instance();
if (m_ime_mode) { if (m_ime_mode) {
OrbisImeParam param = m_param.ime; OrbisImeParam param = m_param.ime;
if (use_param_handler) { if (use_param_handler) {
linker->ExecuteGuest(param.handler, param.arg, event); Core::ExecuteGuest(param.handler, param.arg, event);
} else { } else {
linker->ExecuteGuest(handler, param.arg, event); Core::ExecuteGuest(handler, param.arg, event);
} }
} else { } else {
OrbisImeKeyboardParam param = m_param.key; OrbisImeKeyboardParam param = m_param.key;
if (use_param_handler) { if (use_param_handler) {
linker->ExecuteGuest(param.handler, param.arg, event); Core::ExecuteGuest(param.handler, param.arg, event);
} else { } else {
linker->ExecuteGuest(handler, param.arg, event); Core::ExecuteGuest(handler, param.arg, event);
} }
} }
} }
@ -503,4 +501,4 @@ void RegisterlibSceIme(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("fwcPR7+7Rks", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshUpdateContext2); LIB_FUNCTION("fwcPR7+7Rks", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshUpdateContext2);
}; };
} // namespace Libraries::Ime } // namespace Libraries::Ime

View file

@ -57,7 +57,7 @@ public:
} }
} }
static void* RunWrapper(void* arg) { static void* PS4_SYSV_ABI RunWrapper(void* arg) {
Thread* thr = (Thread*)arg; Thread* thr = (Thread*)arg;
thr->func(thr->stop.get_token()); thr->func(thr->stop.get_token());
return nullptr; return nullptr;

View file

@ -203,7 +203,7 @@ int PS4_SYSV_ABI posix_pthread_condattr_getpshared(const PthreadCondAttrT* attr,
if (attr == nullptr || *attr == nullptr) { if (attr == nullptr || *attr == nullptr) {
return POSIX_EINVAL; return POSIX_EINVAL;
} }
*pshared = PTHREAD_PROCESS_PRIVATE; *pshared = 0;
return 0; return 0;
} }
@ -211,7 +211,7 @@ int PS4_SYSV_ABI posix_pthread_condattr_setpshared(PthreadCondAttrT* attr, int p
if (attr == nullptr || *attr == nullptr) { if (attr == nullptr || *attr == nullptr) {
return POSIX_EINVAL; return POSIX_EINVAL;
} }
if (pshared != PTHREAD_PROCESS_PRIVATE) { if (pshared != 0) {
return POSIX_EINVAL; return POSIX_EINVAL;
} }
return 0; return 0;

View file

@ -15,6 +15,7 @@ namespace Libraries::Kernel {
static std::array<SceKernelExceptionHandler, 32> Handlers{}; static std::array<SceKernelExceptionHandler, 32> Handlers{};
#ifndef _WIN64
void SigactionHandler(int signum, siginfo_t* inf, ucontext_t* raw_context) { void SigactionHandler(int signum, siginfo_t* inf, ucontext_t* raw_context) {
const auto handler = Handlers[POSIX_SIGUSR1]; const auto handler = Handlers[POSIX_SIGUSR1];
if (handler) { if (handler) {
@ -63,12 +64,14 @@ void SigactionHandler(int signum, siginfo_t* inf, ucontext_t* raw_context) {
handler(POSIX_SIGUSR1, &ctx); handler(POSIX_SIGUSR1, &ctx);
} }
} }
#endif
int PS4_SYSV_ABI sceKernelInstallExceptionHandler(s32 signum, SceKernelExceptionHandler handler) { int PS4_SYSV_ABI sceKernelInstallExceptionHandler(s32 signum, SceKernelExceptionHandler handler) {
if (signum == POSIX_SIGSEGV) { if (signum != POSIX_SIGUSR1) {
LOG_ERROR(Lib_Kernel, "Installing non-supported exception handler for signal {}", signum);
return 0; return 0;
} }
ASSERT_MSG(signum == POSIX_SIGUSR1 && !Handlers[POSIX_SIGUSR1], "Invalid parameters"); ASSERT_MSG(!Handlers[POSIX_SIGUSR1], "Invalid parameters");
Handlers[POSIX_SIGUSR1] = handler; Handlers[POSIX_SIGUSR1] = handler;
#ifdef _WIN64 #ifdef _WIN64
UNREACHABLE_MSG("Missing exception implementation"); UNREACHABLE_MSG("Missing exception implementation");
@ -82,10 +85,11 @@ int PS4_SYSV_ABI sceKernelInstallExceptionHandler(s32 signum, SceKernelException
} }
int PS4_SYSV_ABI sceKernelRemoveExceptionHandler(s32 signum) { int PS4_SYSV_ABI sceKernelRemoveExceptionHandler(s32 signum) {
if (signum == 8) { if (signum != POSIX_SIGUSR1) {
LOG_ERROR(Lib_Kernel, "Installing non-supported exception handler for signal {}", signum);
return 0; return 0;
} }
ASSERT_MSG(signum == POSIX_SIGUSR1 && Handlers[POSIX_SIGUSR1], "Invalid parameters"); ASSERT_MSG(Handlers[POSIX_SIGUSR1], "Invalid parameters");
Handlers[POSIX_SIGUSR1] = nullptr; Handlers[POSIX_SIGUSR1] = nullptr;
#ifdef _WIN64 #ifdef _WIN64
UNREACHABLE_MSG("Missing exception implementation"); UNREACHABLE_MSG("Missing exception implementation");
@ -98,14 +102,11 @@ int PS4_SYSV_ABI sceKernelRemoveExceptionHandler(s32 signum) {
return 0; return 0;
} }
static std::mutex mtx;
int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) { int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) {
std::scoped_lock lk{mtx};
LOG_ERROR(Lib_Kernel, "Raising exception"); LOG_ERROR(Lib_Kernel, "Raising exception");
ASSERT_MSG(signum == POSIX_SIGUSR1, "Attempting to raise non user defined signal!"); ASSERT_MSG(signum == POSIX_SIGUSR1, "Attempting to raise non user defined signal!");
#ifdef _WIN64 #ifdef _WIN64
UNREACHABLE("Missing exception implementation"); UNREACHABLE_MSG("Missing exception implementation");
#else #else
pthread_t pthr = *reinterpret_cast<pthread_t*>(thread->native_handle); pthread_t pthr = *reinterpret_cast<pthread_t*>(thread->native_handle);
pthread_kill(pthr, SIGUSR2); pthread_kill(pthr, SIGUSR2);

View file

@ -127,7 +127,7 @@ static int JoinThread(PthreadT pthread, void** thread_return, const OrbisKernelT
pthread->joiner = curthread; pthread->joiner = curthread;
pthread->lock.unlock(); pthread->lock.unlock();
const auto backout_join = [](void* arg) { const auto backout_join = [](void* arg) PS4_SYSV_ABI {
Pthread* pthread = (Pthread*)arg; Pthread* pthread = (Pthread*)arg;
std::scoped_lock lk{pthread->lock}; std::scoped_lock lk{pthread->lock};
pthread->joiner = nullptr; pthread->joiner = nullptr;
@ -258,12 +258,12 @@ int PS4_SYSV_ABI posix_pthread_create_name_np(PthreadT* thread, const PthreadAtt
new_thread->arg = arg; new_thread->arg = arg;
new_thread->cancel_enable = 1; new_thread->cancel_enable = 1;
new_thread->cancel_async = 0; new_thread->cancel_async = 0;
static std::atomic<int> counter = 0;
new_thread->name = fmt::format("NoName{}", counter++);
auto* memory = Core::Memory::Instance(); auto* memory = Core::Memory::Instance();
if (name && memory->IsValidAddress(name)) { if (name && memory->IsValidAddress(name)) {
new_thread->name = name; new_thread->name = name;
} else {
new_thread->name = fmt::format("Thread{}", new_thread->tid.load());
} }
ASSERT(new_thread->attr.suspend == 0); ASSERT(new_thread->attr.suspend == 0);
@ -284,7 +284,8 @@ int PS4_SYSV_ABI posix_pthread_create_name_np(PthreadT* thread, const PthreadAtt
pthread_t* pthr = reinterpret_cast<pthread_t*>(&new_thread->native_handle); pthread_t* pthr = reinterpret_cast<pthread_t*>(&new_thread->native_handle);
pthread_attr_t pattr; pthread_attr_t pattr;
pthread_attr_init(&pattr); pthread_attr_init(&pattr);
pthread_attr_setstack(&pattr, new_thread->attr.stackaddr_attr, new_thread->attr.stacksize_attr); // pthread_attr_setstack(&pattr, new_thread->attr.stackaddr_attr,
// new_thread->attr.stacksize_attr);
int ret = pthread_create(pthr, &pattr, (PthreadEntryFunc)RunThread, new_thread); int ret = pthread_create(pthr, &pattr, (PthreadEntryFunc)RunThread, new_thread);
ASSERT_MSG(ret == 0, "Failed to create thread with error {}", ret); ASSERT_MSG(ret == 0, "Failed to create thread with error {}", ret);
if (ret) { if (ret) {
@ -303,7 +304,7 @@ int PS4_SYSV_ABI posix_pthread_getthreadid_np() {
} }
int PS4_SYSV_ABI posix_pthread_getname_np(PthreadT thread, char* name) { int PS4_SYSV_ABI posix_pthread_getname_np(PthreadT thread, char* name) {
std::memcpy(name, thread->name.data(), std::min(thread->name.size(), 32UL)); std::memcpy(name, thread->name.data(), std::min<size_t>(thread->name.size(), 32));
return 0; return 0;
} }

View file

@ -194,10 +194,12 @@ struct PthreadSpecificElem {
int seqno; int seqno;
}; };
using PthreadKeyDestructor = void PS4_SYSV_ABI (*)(const void*);
struct PthreadKey { struct PthreadKey {
int allocated; int allocated;
int seqno; int seqno;
void PS4_SYSV_ABI (*destructor)(const void*); PthreadKeyDestructor destructor;
}; };
using PthreadKeyT = s32; using PthreadKeyT = s32;
@ -227,7 +229,7 @@ enum class ThreadListFlags : u32 {
InGcList = 4, InGcList = 4,
}; };
using PthreadEntryFunc = void* (*)(void*); using PthreadEntryFunc = void* PS4_SYSV_ABI (*)(void*);
constexpr u32 TidTerminated = 1; constexpr u32 TidTerminated = 1;
@ -254,7 +256,7 @@ struct Pthread {
int critical_count; int critical_count;
int sigblock; int sigblock;
int refcount; int refcount;
void* PS4_SYSV_ABI (*start_routine)(void*); PthreadEntryFunc start_routine;
void* arg; void* arg;
uintptr_t native_handle; uintptr_t native_handle;
PthreadAttr attr; PthreadAttr attr;
@ -264,7 +266,7 @@ struct Pthread {
bool no_cancel; bool no_cancel;
bool cancel_async; bool cancel_async;
bool cancelling; bool cancelling;
sigset_t sigmask; Cpuset sigmask;
bool unblock_sigcancel; bool unblock_sigcancel;
bool in_sigsuspend; bool in_sigsuspend;
bool force_exit; bool force_exit;

View file

@ -25,7 +25,7 @@ static constexpr std::array<PthreadPrio, 3> ThrPriorities = {{
PthreadAttr PthreadAttrDefault = { PthreadAttr PthreadAttrDefault = {
.sched_policy = SchedPolicy::Fifo, .sched_policy = SchedPolicy::Fifo,
.sched_inherit = PTHREAD_INHERIT_SCHED, .sched_inherit = 0,
.prio = 0, .prio = 0,
.suspend = false, .suspend = false,
.flags = PthreadAttrFlags::ScopeSystem, .flags = PthreadAttrFlags::ScopeSystem,
@ -69,8 +69,7 @@ int PS4_SYSV_ABI posix_pthread_attr_getinheritsched(const PthreadAttrT* attr, in
return 0; return 0;
} }
int PS4_SYSV_ABI posix_pthread_attr_getschedparam(const PthreadAttrT* attr, int PS4_SYSV_ABI posix_pthread_attr_getschedparam(const PthreadAttrT* attr, SchedParam* param) {
struct sched_param* param) {
if (attr == nullptr || *attr == nullptr || param == nullptr) { if (attr == nullptr || *attr == nullptr || param == nullptr) {
return POSIX_EINVAL; return POSIX_EINVAL;
} }
@ -172,7 +171,7 @@ int PS4_SYSV_ABI posix_pthread_attr_setdetachstate(PthreadAttrT* attr, int detac
return 0; return 0;
} }
int PS4_SYSV_ABI posix_pthread_attr_setschedparam(PthreadAttrT* attr, const sched_param* param) { int PS4_SYSV_ABI posix_pthread_attr_setschedparam(PthreadAttrT* attr, SchedParam* param) {
if (attr == nullptr || *attr == nullptr) { if (attr == nullptr || *attr == nullptr) {
return POSIX_EINVAL; return POSIX_EINVAL;
} }
@ -248,15 +247,6 @@ int PS4_SYSV_ABI posix_pthread_attr_getaffinity_np(const PthreadAttrT* pattr, si
return 0; return 0;
} }
int PS4_SYSV_ABI scePthreadAttrGetaffinity(PthreadAttrT* param_1, Cpuset* mask) {
Cpuset cpuset;
const int ret = posix_pthread_attr_getaffinity_np(param_1, 0x10, &cpuset);
if (ret == 0) {
*mask = cpuset;
}
return ret;
}
int PS4_SYSV_ABI posix_pthread_attr_setaffinity_np(PthreadAttrT* pattr, size_t cpusetsize, int PS4_SYSV_ABI posix_pthread_attr_setaffinity_np(PthreadAttrT* pattr, size_t cpusetsize,
const Cpuset* cpusetp) { const Cpuset* cpusetp) {
if (pattr == nullptr) { if (pattr == nullptr) {
@ -282,6 +272,24 @@ int PS4_SYSV_ABI posix_pthread_attr_setaffinity_np(PthreadAttrT* pattr, size_t c
return 0; return 0;
} }
int PS4_SYSV_ABI scePthreadAttrGetaffinity(PthreadAttrT* param_1, Cpuset* mask) {
Cpuset cpuset;
const int ret = posix_pthread_attr_getaffinity_np(param_1, 0x10, &cpuset);
if (ret == 0) {
*mask = cpuset;
}
return ret;
}
int PS4_SYSV_ABI scePthreadAttrSetaffinity(PthreadAttrT* attr, const Cpuset mask) {
if (attr == nullptr) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
// posix_pthread_attr_setaffinity_np(attr, 0x10, &mask);
return ORBIS_OK;
}
void RegisterThreadAttr(Core::Loader::SymbolsResolver* sym) { void RegisterThreadAttr(Core::Loader::SymbolsResolver* sym) {
// Posix // Posix
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);
@ -335,6 +343,7 @@ void RegisterThreadAttr(Core::Loader::SymbolsResolver* sym) {
ORBIS(posix_pthread_attr_setguardsize)); ORBIS(posix_pthread_attr_setguardsize));
LIB_FUNCTION("8+s5BzZjxSg", "libkernel", 1, "libkernel", 1, 1, LIB_FUNCTION("8+s5BzZjxSg", "libkernel", 1, "libkernel", 1, 1,
ORBIS(scePthreadAttrGetaffinity)); ORBIS(scePthreadAttrGetaffinity));
LIB_FUNCTION("bt3CTBKmGyI", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetaffinity);
} }
} // namespace Libraries::Kernel } // namespace Libraries::Kernel

View file

@ -15,7 +15,7 @@ static constexpr u32 PthreadDestructorIterations = 4;
static std::array<PthreadKey, PthreadKeysMax> ThreadKeytable{}; static std::array<PthreadKey, PthreadKeysMax> ThreadKeytable{};
static std::mutex KeytableLock; static std::mutex KeytableLock;
int PS4_SYSV_ABI posix_pthread_key_create(PthreadKeyT* key, void (*destructor)(const void*)) { int PS4_SYSV_ABI posix_pthread_key_create(PthreadKeyT* key, PthreadKeyDestructor destructor) {
std::scoped_lock lk{KeytableLock}; std::scoped_lock lk{KeytableLock};
const auto it = std::ranges::find(ThreadKeytable, 0, &PthreadKey::allocated); const auto it = std::ranges::find(ThreadKeytable, 0, &PthreadKey::allocated);
if (it != ThreadKeytable.end()) { if (it != ThreadKeytable.end()) {
@ -44,7 +44,7 @@ int PS4_SYSV_ABI posix_pthread_key_delete(PthreadKeyT key) {
void _thread_cleanupspecific() { void _thread_cleanupspecific() {
Pthread* curthread = g_curthread; Pthread* curthread = g_curthread;
void (*destructor)(const void*); PthreadKeyDestructor destructor;
const void* data = NULL; const void* data = NULL;
if (curthread->specific == nullptr) { if (curthread->specific == nullptr) {

View file

@ -218,14 +218,14 @@ int PS4_SYSV_ABI posix_pthread_rwlockattr_init(PthreadRwlockAttrT* rwlockattr) {
return POSIX_ENOMEM; return POSIX_ENOMEM;
} }
prwlockattr->pshared = PTHREAD_PROCESS_PRIVATE; prwlockattr->pshared = 0;
*rwlockattr = prwlockattr; *rwlockattr = prwlockattr;
return 0; return 0;
} }
int PS4_SYSV_ABI posix_pthread_rwlockattr_setpshared(PthreadRwlockAttrT* rwlockattr, int pshared) { int PS4_SYSV_ABI posix_pthread_rwlockattr_setpshared(PthreadRwlockAttrT* rwlockattr, int pshared) {
/* Only PTHREAD_PROCESS_PRIVATE is supported. */ /* Only PTHREAD_PROCESS_PRIVATE is supported. */
if (pshared != PTHREAD_PROCESS_PRIVATE) { if (pshared != 0) {
return POSIX_EINVAL; return POSIX_EINVAL;
} }

View file

@ -5,10 +5,10 @@
#include <list> #include <list>
#include <mutex> #include <mutex>
#include <semaphore> #include <semaphore>
#include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/libraries/error_codes.h" #include "core/libraries/error_codes.h"
#include "core/libraries/kernel/kernel.h" #include "core/libraries/kernel/kernel.h"
#include "core/libraries/kernel/threads/pthread.h"
#include "core/libraries/kernel/time.h" #include "core/libraries/kernel/time.h"
#include "core/libraries/libs.h" #include "core/libraries/libs.h"
@ -110,14 +110,10 @@ public:
bool was_cancled{}; bool was_cancled{};
explicit WaitingThread(s32 need_count, bool is_fifo) : need_count{need_count} { explicit WaitingThread(s32 need_count, bool is_fifo) : need_count{need_count} {
if (is_fifo) {
return;
}
// Retrieve calling thread priority for sorting into waiting threads list. // Retrieve calling thread priority for sorting into waiting threads list.
s32 policy; if (!is_fifo) {
sched_param param; priority = g_curthread->attr.prio;
pthread_getschedparam(pthread_self(), &policy, &param); }
priority = param.sched_priority;
} }
int GetResult(bool timed_out) { int GetResult(bool timed_out) {

View file

@ -105,8 +105,10 @@ int ThreadState::CreateStack(PthreadAttr* attr) {
Core::MemoryMapFlags::NoFlags, Core::VMAType::Stack); Core::MemoryMapFlags::NoFlags, Core::VMAType::Stack);
ASSERT_MSG(ret == 0, "Unable to map stack memory"); ASSERT_MSG(ret == 0, "Unable to map stack memory");
ret = memory->Protect(stackaddr, guardsize, Core::MemoryProt::NoAccess); if (guardsize != 0) {
ASSERT_MSG(ret == 0, "Unable to protect guard page"); ret = memory->Protect(stackaddr, guardsize, Core::MemoryProt::NoAccess);
ASSERT_MSG(ret == 0, "Unable to protect guard page");
}
stackaddr += guardsize; stackaddr += guardsize;
attr->stackaddr_attr = (void*)stackaddr; attr->stackaddr_attr = (void*)stackaddr;