mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-04 08:06:20 +00:00
kernel: Multiplatform thread implementation
This commit is contained in:
parent
8c5b3f5f38
commit
c9063a644e
8 changed files with 84 additions and 15 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -85,7 +85,7 @@ void _thread_cleanupspecific() {
|
||||||
* destructor:
|
* destructor:
|
||||||
*/
|
*/
|
||||||
lk.unlock();
|
lk.unlock();
|
||||||
destructor(data);
|
Core::ExecuteGuest(destructor, data);
|
||||||
lk.lock();
|
lk.lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
46
src/core/thread.cpp
Normal 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
26
src/core/thread.h
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue