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) {
const auto* linker = Common::Singleton<Core::Linker>::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
} // 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;
thr->func(thr->stop.get_token());
return nullptr;

View file

@ -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;

View file

@ -15,6 +15,7 @@ namespace Libraries::Kernel {
static std::array<SceKernelExceptionHandler, 32> 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<pthread_t*>(thread->native_handle);
pthread_kill(pthr, SIGUSR2);

View file

@ -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<int> 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<pthread_t*>(&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<size_t>(thread->name.size(), 32));
return 0;
}

View file

@ -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;

View file

@ -25,7 +25,7 @@ static constexpr std::array<PthreadPrio, 3> 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

View file

@ -15,7 +15,7 @@ static constexpr u32 PthreadDestructorIterations = 4;
static std::array<PthreadKey, PthreadKeysMax> 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) {

View file

@ -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;
}

View file

@ -5,10 +5,10 @@
#include <list>
#include <mutex>
#include <semaphore>
#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, &param);
priority = param.sched_priority;
if (!is_fifo) {
priority = g_curthread->attr.prio;
}
}
int GetResult(bool timed_out) {

View file

@ -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;