diff --git a/CMakeLists.txt b/CMakeLists.txt index 2542f19e..a8bbe36b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -531,6 +531,8 @@ set(CORE src/core/aerolib/stubs.cpp src/core/platform.h src/core/signals.cpp src/core/signals.h + src/core/thread.cpp + src/core/thread.h src/core/tls.cpp src/core/tls.h src/core/virtual_memory.cpp diff --git a/src/core/libraries/kernel/threads/exception.cpp b/src/core/libraries/kernel/threads/exception.cpp index 1cb792ae..fe10a739 100644 --- a/src/core/libraries/kernel/threads/exception.cpp +++ b/src/core/libraries/kernel/threads/exception.cpp @@ -108,7 +108,7 @@ int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) { #ifdef _WIN64 UNREACHABLE_MSG("Missing exception implementation"); #else - pthread_t pthr = *reinterpret_cast(thread->native_handle); + pthread_t pthr = *reinterpret_cast(thread->native_thr.GetHandle()); pthread_kill(pthr, SIGUSR2); #endif return 0; diff --git a/src/core/libraries/kernel/threads/pthread.cpp b/src/core/libraries/kernel/threads/pthread.cpp index 8b620788..8d6f2413 100644 --- a/src/core/libraries/kernel/threads/pthread.cpp +++ b/src/core/libraries/kernel/threads/pthread.cpp @@ -11,8 +11,6 @@ #include "core/libraries/libs.h" #include "core/memory.h" -#include - namespace Libraries::Kernel { constexpr int PthreadInheritSched = 4; @@ -62,7 +60,7 @@ static void ExitThread() { curthread->tid.store(TidTerminated); curthread->tid.notify_all(); - pthread_exit(nullptr); + curthread->native_thr.Exit(); UNREACHABLE(); /* Never reach! */ } @@ -201,7 +199,8 @@ int PS4_SYSV_ABI posix_pthread_detach(PthreadT pthread) { return 0; } -static void RunThread(Pthread* curthread) { +static void RunThread(void* arg) { + Pthread* curthread = (Pthread*)arg; g_curthread = curthread; Common::SetCurrentThreadName(curthread->name.c_str()); DebugState.AddCurrentThreadToGuestList(); @@ -281,12 +280,8 @@ int PS4_SYSV_ABI posix_pthread_create_name_np(PthreadT* thread, const PthreadAtt (*thread) = new_thread; /* Create thread */ - 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); - int ret = pthread_create(pthr, &pattr, (PthreadEntryFunc)RunThread, new_thread); + new_thread->native_thr = Core::Thread(); + int ret = new_thread->native_thr.Create(RunThread, new_thread); ASSERT_MSG(ret == 0, "Failed to create thread with error {}", ret); if (ret) { *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; auto state = PthreadOnceState::InProgress; if (once_control->state.compare_exchange_strong(state, PthreadOnceState::NeverDone, diff --git a/src/core/libraries/kernel/threads/pthread.h b/src/core/libraries/kernel/threads/pthread.h index 035f6f02..07fe642f 100644 --- a/src/core/libraries/kernel/threads/pthread.h +++ b/src/core/libraries/kernel/threads/pthread.h @@ -13,6 +13,7 @@ #include "common/enum.h" #include "core/libraries/kernel/time.h" +#include "core/thread.h" #include "core/tls.h" namespace Core::Loader { @@ -258,7 +259,7 @@ struct Pthread { int refcount; PthreadEntryFunc start_routine; void* arg; - uintptr_t native_handle; + Core::Thread native_thr; PthreadAttr attr; bool cancel_enable; bool cancel_pending; diff --git a/src/core/libraries/kernel/threads/pthread_spec.cpp b/src/core/libraries/kernel/threads/pthread_spec.cpp index 5c274291..c7476600 100644 --- a/src/core/libraries/kernel/threads/pthread_spec.cpp +++ b/src/core/libraries/kernel/threads/pthread_spec.cpp @@ -85,7 +85,7 @@ void _thread_cleanupspecific() { * destructor: */ lk.unlock(); - destructor(data); + Core::ExecuteGuest(destructor, data); lk.lock(); } } diff --git a/src/core/libraries/videoout/driver.cpp b/src/core/libraries/videoout/driver.cpp index c1989226..2e97da81 100644 --- a/src/core/libraries/videoout/driver.cpp +++ b/src/core/libraries/videoout/driver.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include #include "common/assert.h" #include "common/config.h" diff --git a/src/core/thread.cpp b/src/core/thread.cpp new file mode 100644 index 00000000..81d156dd --- /dev/null +++ b/src/core/thread.cpp @@ -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 +#else +#include +#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(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 \ No newline at end of file diff --git a/src/core/thread.h b/src/core/thread.h new file mode 100644 index 00000000..cdb34c84 --- /dev/null +++ b/src/core/thread.h @@ -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 \ No newline at end of file