From 8c5b3f5f381d18b1054384d6d9a2096608e3b460 Mon Sep 17 00:00:00 2001 From: "Daniel R." <47796739+polybiusproxy@users.noreply.github.com> Date: Fri, 25 Oct 2024 16:36:38 +0300 Subject: [PATCH] kernel: Pthread rewrite touchups for Windows --- src/core/libraries/ime/ime.cpp | 12 +++---- src/core/libraries/kernel/threads.h | 2 +- src/core/libraries/kernel/threads/condvar.cpp | 4 +-- .../libraries/kernel/threads/exception.cpp | 17 ++++----- src/core/libraries/kernel/threads/pthread.cpp | 11 +++--- src/core/libraries/kernel/threads/pthread.h | 10 +++--- .../libraries/kernel/threads/pthread_attr.cpp | 35 ++++++++++++------- .../libraries/kernel/threads/pthread_spec.cpp | 4 +-- src/core/libraries/kernel/threads/rwlock.cpp | 4 +-- .../libraries/kernel/threads/semaphore.cpp | 12 +++---- src/core/libraries/kernel/threads/stack.cpp | 6 ++-- 11 files changed, 63 insertions(+), 54 deletions(-) diff --git a/src/core/libraries/ime/ime.cpp b/src/core/libraries/ime/ime.cpp index 0310c515..efb988c7 100644 --- a/src/core/libraries/ime/ime.cpp +++ b/src/core/libraries/ime/ime.cpp @@ -70,21 +70,19 @@ public: } void Execute(OrbisImeEventHandler handler, OrbisImeEvent* event, bool use_param_handler) { - const auto* linker = Common::Singleton::Instance(); - if (m_ime_mode) { OrbisImeParam param = m_param.ime; if (use_param_handler) { - linker->ExecuteGuest(param.handler, param.arg, event); + Core::ExecuteGuest(param.handler, param.arg, event); } else { - linker->ExecuteGuest(handler, param.arg, event); + Core::ExecuteGuest(handler, param.arg, event); } } else { OrbisImeKeyboardParam param = m_param.key; if (use_param_handler) { - linker->ExecuteGuest(param.handler, param.arg, event); + Core::ExecuteGuest(param.handler, param.arg, event); } 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); }; -} // namespace Libraries::Ime \ No newline at end of file +} // namespace Libraries::Ime diff --git a/src/core/libraries/kernel/threads.h b/src/core/libraries/kernel/threads.h index a022b3a0..ad139359 100644 --- a/src/core/libraries/kernel/threads.h +++ b/src/core/libraries/kernel/threads.h @@ -57,7 +57,7 @@ public: } } - static void* RunWrapper(void* arg) { + static void* PS4_SYSV_ABI RunWrapper(void* arg) { Thread* thr = (Thread*)arg; thr->func(thr->stop.get_token()); return nullptr; diff --git a/src/core/libraries/kernel/threads/condvar.cpp b/src/core/libraries/kernel/threads/condvar.cpp index 1cd3a3d0..161d1703 100644 --- a/src/core/libraries/kernel/threads/condvar.cpp +++ b/src/core/libraries/kernel/threads/condvar.cpp @@ -203,7 +203,7 @@ int PS4_SYSV_ABI posix_pthread_condattr_getpshared(const PthreadCondAttrT* attr, if (attr == nullptr || *attr == nullptr) { return POSIX_EINVAL; } - *pshared = PTHREAD_PROCESS_PRIVATE; + *pshared = 0; return 0; } @@ -211,7 +211,7 @@ int PS4_SYSV_ABI posix_pthread_condattr_setpshared(PthreadCondAttrT* attr, int p if (attr == nullptr || *attr == nullptr) { return POSIX_EINVAL; } - if (pshared != PTHREAD_PROCESS_PRIVATE) { + if (pshared != 0) { return POSIX_EINVAL; } return 0; diff --git a/src/core/libraries/kernel/threads/exception.cpp b/src/core/libraries/kernel/threads/exception.cpp index b305e266..1cb792ae 100644 --- a/src/core/libraries/kernel/threads/exception.cpp +++ b/src/core/libraries/kernel/threads/exception.cpp @@ -15,6 +15,7 @@ namespace Libraries::Kernel { static std::array Handlers{}; +#ifndef _WIN64 void SigactionHandler(int signum, siginfo_t* inf, ucontext_t* raw_context) { const auto handler = Handlers[POSIX_SIGUSR1]; if (handler) { @@ -63,12 +64,14 @@ void SigactionHandler(int signum, siginfo_t* inf, ucontext_t* raw_context) { handler(POSIX_SIGUSR1, &ctx); } } +#endif 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; } - ASSERT_MSG(signum == POSIX_SIGUSR1 && !Handlers[POSIX_SIGUSR1], "Invalid parameters"); + ASSERT_MSG(!Handlers[POSIX_SIGUSR1], "Invalid parameters"); Handlers[POSIX_SIGUSR1] = handler; #ifdef _WIN64 UNREACHABLE_MSG("Missing exception implementation"); @@ -82,10 +85,11 @@ int PS4_SYSV_ABI sceKernelInstallExceptionHandler(s32 signum, SceKernelException } 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; } - ASSERT_MSG(signum == POSIX_SIGUSR1 && Handlers[POSIX_SIGUSR1], "Invalid parameters"); + ASSERT_MSG(Handlers[POSIX_SIGUSR1], "Invalid parameters"); Handlers[POSIX_SIGUSR1] = nullptr; #ifdef _WIN64 UNREACHABLE_MSG("Missing exception implementation"); @@ -98,14 +102,11 @@ int PS4_SYSV_ABI sceKernelRemoveExceptionHandler(s32 signum) { return 0; } -static std::mutex mtx; - int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) { - std::scoped_lock lk{mtx}; LOG_ERROR(Lib_Kernel, "Raising exception"); ASSERT_MSG(signum == POSIX_SIGUSR1, "Attempting to raise non user defined signal!"); #ifdef _WIN64 - UNREACHABLE("Missing exception implementation"); + UNREACHABLE_MSG("Missing exception implementation"); #else pthread_t pthr = *reinterpret_cast(thread->native_handle); pthread_kill(pthr, SIGUSR2); diff --git a/src/core/libraries/kernel/threads/pthread.cpp b/src/core/libraries/kernel/threads/pthread.cpp index a81ae77c..8b620788 100644 --- a/src/core/libraries/kernel/threads/pthread.cpp +++ b/src/core/libraries/kernel/threads/pthread.cpp @@ -127,7 +127,7 @@ static int JoinThread(PthreadT pthread, void** thread_return, const OrbisKernelT pthread->joiner = curthread; pthread->lock.unlock(); - const auto backout_join = [](void* arg) { + const auto backout_join = [](void* arg) PS4_SYSV_ABI { Pthread* pthread = (Pthread*)arg; std::scoped_lock lk{pthread->lock}; 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->cancel_enable = 1; new_thread->cancel_async = 0; - static std::atomic counter = 0; - new_thread->name = fmt::format("NoName{}", counter++); auto* memory = Core::Memory::Instance(); if (name && memory->IsValidAddress(name)) { new_thread->name = name; + } else { + new_thread->name = fmt::format("Thread{}", new_thread->tid.load()); } 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(&new_thread->native_handle); pthread_attr_t 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); ASSERT_MSG(ret == 0, "Failed to create thread with error {}", 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) { - std::memcpy(name, thread->name.data(), std::min(thread->name.size(), 32UL)); + std::memcpy(name, thread->name.data(), std::min(thread->name.size(), 32)); return 0; } diff --git a/src/core/libraries/kernel/threads/pthread.h b/src/core/libraries/kernel/threads/pthread.h index ee8def99..035f6f02 100644 --- a/src/core/libraries/kernel/threads/pthread.h +++ b/src/core/libraries/kernel/threads/pthread.h @@ -194,10 +194,12 @@ struct PthreadSpecificElem { int seqno; }; +using PthreadKeyDestructor = void PS4_SYSV_ABI (*)(const void*); + struct PthreadKey { int allocated; int seqno; - void PS4_SYSV_ABI (*destructor)(const void*); + PthreadKeyDestructor destructor; }; using PthreadKeyT = s32; @@ -227,7 +229,7 @@ enum class ThreadListFlags : u32 { InGcList = 4, }; -using PthreadEntryFunc = void* (*)(void*); +using PthreadEntryFunc = void* PS4_SYSV_ABI (*)(void*); constexpr u32 TidTerminated = 1; @@ -254,7 +256,7 @@ struct Pthread { int critical_count; int sigblock; int refcount; - void* PS4_SYSV_ABI (*start_routine)(void*); + PthreadEntryFunc start_routine; void* arg; uintptr_t native_handle; PthreadAttr attr; @@ -264,7 +266,7 @@ struct Pthread { bool no_cancel; bool cancel_async; bool cancelling; - sigset_t sigmask; + Cpuset sigmask; bool unblock_sigcancel; bool in_sigsuspend; bool force_exit; diff --git a/src/core/libraries/kernel/threads/pthread_attr.cpp b/src/core/libraries/kernel/threads/pthread_attr.cpp index 06da92bc..b01532d1 100644 --- a/src/core/libraries/kernel/threads/pthread_attr.cpp +++ b/src/core/libraries/kernel/threads/pthread_attr.cpp @@ -25,7 +25,7 @@ static constexpr std::array ThrPriorities = {{ PthreadAttr PthreadAttrDefault = { .sched_policy = SchedPolicy::Fifo, - .sched_inherit = PTHREAD_INHERIT_SCHED, + .sched_inherit = 0, .prio = 0, .suspend = false, .flags = PthreadAttrFlags::ScopeSystem, @@ -69,8 +69,7 @@ int PS4_SYSV_ABI posix_pthread_attr_getinheritsched(const PthreadAttrT* attr, in return 0; } -int PS4_SYSV_ABI posix_pthread_attr_getschedparam(const PthreadAttrT* attr, - struct sched_param* param) { +int PS4_SYSV_ABI posix_pthread_attr_getschedparam(const PthreadAttrT* attr, SchedParam* param) { if (attr == nullptr || *attr == nullptr || param == nullptr) { return POSIX_EINVAL; } @@ -172,7 +171,7 @@ int PS4_SYSV_ABI posix_pthread_attr_setdetachstate(PthreadAttrT* attr, int detac 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) { return POSIX_EINVAL; } @@ -248,15 +247,6 @@ int PS4_SYSV_ABI posix_pthread_attr_getaffinity_np(const PthreadAttrT* pattr, si 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, const Cpuset* cpusetp) { if (pattr == nullptr) { @@ -282,6 +272,24 @@ int PS4_SYSV_ABI posix_pthread_attr_setaffinity_np(PthreadAttrT* pattr, size_t c 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) { // Posix 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)); LIB_FUNCTION("8+s5BzZjxSg", "libkernel", 1, "libkernel", 1, 1, ORBIS(scePthreadAttrGetaffinity)); + LIB_FUNCTION("bt3CTBKmGyI", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetaffinity); } } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads/pthread_spec.cpp b/src/core/libraries/kernel/threads/pthread_spec.cpp index 8647b4f4..5c274291 100644 --- a/src/core/libraries/kernel/threads/pthread_spec.cpp +++ b/src/core/libraries/kernel/threads/pthread_spec.cpp @@ -15,7 +15,7 @@ static constexpr u32 PthreadDestructorIterations = 4; static std::array ThreadKeytable{}; 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}; const auto it = std::ranges::find(ThreadKeytable, 0, &PthreadKey::allocated); if (it != ThreadKeytable.end()) { @@ -44,7 +44,7 @@ int PS4_SYSV_ABI posix_pthread_key_delete(PthreadKeyT key) { void _thread_cleanupspecific() { Pthread* curthread = g_curthread; - void (*destructor)(const void*); + PthreadKeyDestructor destructor; const void* data = NULL; if (curthread->specific == nullptr) { diff --git a/src/core/libraries/kernel/threads/rwlock.cpp b/src/core/libraries/kernel/threads/rwlock.cpp index 4e327920..2d5a4cdb 100644 --- a/src/core/libraries/kernel/threads/rwlock.cpp +++ b/src/core/libraries/kernel/threads/rwlock.cpp @@ -218,14 +218,14 @@ int PS4_SYSV_ABI posix_pthread_rwlockattr_init(PthreadRwlockAttrT* rwlockattr) { return POSIX_ENOMEM; } - prwlockattr->pshared = PTHREAD_PROCESS_PRIVATE; + prwlockattr->pshared = 0; *rwlockattr = prwlockattr; return 0; } int PS4_SYSV_ABI posix_pthread_rwlockattr_setpshared(PthreadRwlockAttrT* rwlockattr, int pshared) { /* Only PTHREAD_PROCESS_PRIVATE is supported. */ - if (pshared != PTHREAD_PROCESS_PRIVATE) { + if (pshared != 0) { return POSIX_EINVAL; } diff --git a/src/core/libraries/kernel/threads/semaphore.cpp b/src/core/libraries/kernel/threads/semaphore.cpp index 2ce51da1..b8537d86 100644 --- a/src/core/libraries/kernel/threads/semaphore.cpp +++ b/src/core/libraries/kernel/threads/semaphore.cpp @@ -5,10 +5,10 @@ #include #include #include -#include "common/assert.h" #include "common/logging/log.h" #include "core/libraries/error_codes.h" #include "core/libraries/kernel/kernel.h" +#include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/kernel/time.h" #include "core/libraries/libs.h" @@ -110,14 +110,10 @@ public: bool was_cancled{}; 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. - s32 policy; - sched_param param; - pthread_getschedparam(pthread_self(), &policy, ¶m); - priority = param.sched_priority; + if (!is_fifo) { + priority = g_curthread->attr.prio; + } } int GetResult(bool timed_out) { diff --git a/src/core/libraries/kernel/threads/stack.cpp b/src/core/libraries/kernel/threads/stack.cpp index 3c8061de..33a83b67 100644 --- a/src/core/libraries/kernel/threads/stack.cpp +++ b/src/core/libraries/kernel/threads/stack.cpp @@ -105,8 +105,10 @@ int ThreadState::CreateStack(PthreadAttr* attr) { Core::MemoryMapFlags::NoFlags, Core::VMAType::Stack); ASSERT_MSG(ret == 0, "Unable to map stack memory"); - ret = memory->Protect(stackaddr, guardsize, Core::MemoryProt::NoAccess); - ASSERT_MSG(ret == 0, "Unable to protect guard page"); + if (guardsize != 0) { + ret = memory->Protect(stackaddr, guardsize, Core::MemoryProt::NoAccess); + ASSERT_MSG(ret == 0, "Unable to protect guard page"); + } stackaddr += guardsize; attr->stackaddr_attr = (void*)stackaddr;