kernel: Multiplatform thread implementation

This commit is contained in:
Daniel R. 2024-10-26 21:52:33 +02:00 committed by IndecisiveTurtle
parent 8c5b3f5f38
commit c9063a644e
8 changed files with 84 additions and 15 deletions

View file

@ -550,6 +550,8 @@ set(CORE src/core/aerolib/stubs.cpp
src/core/platform.h src/core/platform.h
src/core/signals.cpp src/core/signals.cpp
src/core/signals.h src/core/signals.h
src/core/thread.cpp
src/core/thread.h
src/core/tls.cpp src/core/tls.cpp
src/core/tls.h src/core/tls.h
src/core/virtual_memory.cpp src/core/virtual_memory.cpp

View file

@ -108,7 +108,7 @@ int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) {
#ifdef _WIN64 #ifdef _WIN64
UNREACHABLE_MSG("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_thr.GetHandle());
pthread_kill(pthr, SIGUSR2); pthread_kill(pthr, SIGUSR2);
#endif #endif
return 0; return 0;

View file

@ -11,8 +11,6 @@
#include "core/libraries/libs.h" #include "core/libraries/libs.h"
#include "core/memory.h" #include "core/memory.h"
#include <pthread.h>
namespace Libraries::Kernel { namespace Libraries::Kernel {
constexpr int PthreadInheritSched = 4; constexpr int PthreadInheritSched = 4;
@ -62,7 +60,7 @@ static void ExitThread() {
curthread->tid.store(TidTerminated); curthread->tid.store(TidTerminated);
curthread->tid.notify_all(); curthread->tid.notify_all();
pthread_exit(nullptr); curthread->native_thr.Exit();
UNREACHABLE(); UNREACHABLE();
/* Never reach! */ /* Never reach! */
} }
@ -201,7 +199,8 @@ int PS4_SYSV_ABI posix_pthread_detach(PthreadT pthread) {
return 0; return 0;
} }
static void RunThread(Pthread* curthread) { static void RunThread(void* arg) {
Pthread* curthread = (Pthread*)arg;
g_curthread = curthread; g_curthread = curthread;
Common::SetCurrentThreadName(curthread->name.c_str()); Common::SetCurrentThreadName(curthread->name.c_str());
DebugState.AddCurrentThreadToGuestList(); DebugState.AddCurrentThreadToGuestList();
@ -281,12 +280,8 @@ int PS4_SYSV_ABI posix_pthread_create_name_np(PthreadT* thread, const PthreadAtt
(*thread) = new_thread; (*thread) = new_thread;
/* Create thread */ /* Create thread */
pthread_t* pthr = reinterpret_cast<pthread_t*>(&new_thread->native_handle); new_thread->native_thr = Core::Thread();
pthread_attr_t pattr; int ret = new_thread->native_thr.Create(RunThread, new_thread);
pthread_attr_init(&pattr);
// 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); ASSERT_MSG(ret == 0, "Failed to create thread with error {}", ret);
if (ret) { if (ret) {
*thread = nullptr; *thread = nullptr;
@ -343,7 +338,7 @@ int PS4_SYSV_ABI posix_pthread_once(PthreadOnce* once_control, void (*init_routi
} }
} }
const auto once_cancel_handler = [](void* arg) { const auto once_cancel_handler = [](void* arg) PS4_SYSV_ABI {
PthreadOnce* once_control = (PthreadOnce*)arg; PthreadOnce* once_control = (PthreadOnce*)arg;
auto state = PthreadOnceState::InProgress; auto state = PthreadOnceState::InProgress;
if (once_control->state.compare_exchange_strong(state, PthreadOnceState::NeverDone, if (once_control->state.compare_exchange_strong(state, PthreadOnceState::NeverDone,

View file

@ -13,6 +13,7 @@
#include "common/enum.h" #include "common/enum.h"
#include "core/libraries/kernel/time.h" #include "core/libraries/kernel/time.h"
#include "core/thread.h"
#include "core/tls.h" #include "core/tls.h"
namespace Core::Loader { namespace Core::Loader {
@ -258,7 +259,7 @@ struct Pthread {
int refcount; int refcount;
PthreadEntryFunc start_routine; PthreadEntryFunc start_routine;
void* arg; void* arg;
uintptr_t native_handle; Core::Thread native_thr;
PthreadAttr attr; PthreadAttr attr;
bool cancel_enable; bool cancel_enable;
bool cancel_pending; bool cancel_pending;

View file

@ -85,7 +85,7 @@ void _thread_cleanupspecific() {
* destructor: * destructor:
*/ */
lk.unlock(); lk.unlock();
destructor(data); Core::ExecuteGuest(destructor, data);
lk.lock(); lk.lock();
} }
} }

View file

@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <imgui.h> #include <imgui.h>
#include <pthread.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/config.h" #include "common/config.h"

46
src/core/thread.cpp Normal file
View file

@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "thread.h"
#ifdef _WIN64
#include <windows.h>
#else
#include <pthread.h>
#endif
namespace Core {
Thread::Thread() : native_handle{nullptr} {}
Thread::~Thread() {}
int Thread::Create(ThreadFunc func, void* arg) {
#ifdef _WIN64
native_handle = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, nullptr);
return native_handle ? 0 : -1;
#else
pthread_t* pthr = reinterpret_cast<pthread_t*>(native_handle);
pthread_attr_t pattr;
pthread_attr_init(&pattr);
return pthread_create(pthr, &pattr, func, arg);
#endif
}
void Thread::Exit() {
if (!native_handle) {
return;
}
#ifdef _WIN64
CloseHandle(native_handle);
native_handle = nullptr;
// We call this assuming the thread has finished execution.
ExitThread(0);
#else
pthread_exit(nullptr);
#endif
}
} // namespace Core

26
src/core/thread.h Normal file
View file

@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
namespace Core {
class Thread {
public:
using ThreadFunc = void (*)(void*);
Thread();
~Thread();
int Create(ThreadFunc func, void* arg);
void Exit();
void* GetHandle() {
return native_handle;
}
private:
void* native_handle;
};
} // namespace Core