kernel: Multiplatform thread implementation
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions

This commit is contained in:
Daniel R. 2024-10-26 21:52:33 +02:00
parent 22430546dc
commit 48a7bb1dac
No known key found for this signature in database
GPG Key ID: B8ADC8F57BA18DBA
8 changed files with 84 additions and 15 deletions

View File

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

View File

@ -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<pthread_t*>(thread->native_handle);
pthread_t pthr = *reinterpret_cast<pthread_t*>(thread->native_thr.GetHandle());
pthread_kill(pthr, SIGUSR2);
#endif
return 0;

View File

@ -11,8 +11,6 @@
#include "core/libraries/libs.h"
#include "core/memory.h"
#include <pthread.h>
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<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);
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,

View File

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

View File

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

View File

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