mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-26 20:15:03 +00:00
draft pthreads keys implementation
This commit is contained in:
parent
9ccc8786eb
commit
a660a94f3b
@ -107,6 +107,7 @@ set(KERNEL_LIB
|
|||||||
src/core/libraries/kernel/event_flag/event_flag_obj.h
|
src/core/libraries/kernel/event_flag/event_flag_obj.h
|
||||||
src/core/libraries/kernel/threads/rwlock.cpp
|
src/core/libraries/kernel/threads/rwlock.cpp
|
||||||
src/core/libraries/kernel/threads/semaphore.cpp
|
src/core/libraries/kernel/threads/semaphore.cpp
|
||||||
|
src/core/libraries/kernel/threads/keys.cpp
|
||||||
src/core/libraries/kernel/threads/threads.h
|
src/core/libraries/kernel/threads/threads.h
|
||||||
src/core/libraries/kernel/cpu_management.cpp
|
src/core/libraries/kernel/cpu_management.cpp
|
||||||
src/core/libraries/kernel/cpu_management.h
|
src/core/libraries/kernel/cpu_management.h
|
||||||
|
@ -41,6 +41,7 @@ void init_pthreads() {
|
|||||||
scePthreadRwlockattrInit(&default_rwattr);
|
scePthreadRwlockattrInit(&default_rwattr);
|
||||||
g_pthread_cxt->setDefaultRwattr(default_rwattr);
|
g_pthread_cxt->setDefaultRwattr(default_rwattr);
|
||||||
|
|
||||||
|
g_pthread_cxt->setPthreadKeys(new PthreadKeys);
|
||||||
g_pthread_cxt->SetPthreadPool(new PThreadPool);
|
g_pthread_cxt->SetPthreadPool(new PThreadPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1323,4 +1324,6 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
|||||||
SemaphoreSymbolsRegister(sym);
|
SemaphoreSymbolsRegister(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace Core::Loader {
|
namespace Core::Loader {
|
||||||
class SymbolsResolver;
|
class SymbolsResolver;
|
||||||
@ -28,6 +29,7 @@ struct PthreadCondInternal;
|
|||||||
struct PthreadCondAttrInternal;
|
struct PthreadCondAttrInternal;
|
||||||
struct PthreadRwInternal;
|
struct PthreadRwInternal;
|
||||||
struct PthreadRwLockAttrInernal;
|
struct PthreadRwLockAttrInernal;
|
||||||
|
class PthreadKeys;
|
||||||
|
|
||||||
using SceKernelSchedParam = ::sched_param;
|
using SceKernelSchedParam = ::sched_param;
|
||||||
using ScePthread = PthreadInternal*;
|
using ScePthread = PthreadInternal*;
|
||||||
@ -38,6 +40,9 @@ using ScePthreadCond = PthreadCondInternal*;
|
|||||||
using ScePthreadCondattr = PthreadCondAttrInternal*;
|
using ScePthreadCondattr = PthreadCondAttrInternal*;
|
||||||
using OrbisPthreadRwlock = PthreadRwInternal*;
|
using OrbisPthreadRwlock = PthreadRwInternal*;
|
||||||
using OrbisPthreadRwlockattr = PthreadRwLockAttrInernal*;
|
using OrbisPthreadRwlockattr = PthreadRwLockAttrInernal*;
|
||||||
|
using OrbisPthreadKey = int;
|
||||||
|
|
||||||
|
using PthreadKeyDestructor = PS4_SYSV_ABI void (*)(void*);
|
||||||
|
|
||||||
using pthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*);
|
using pthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*);
|
||||||
|
|
||||||
@ -106,6 +111,30 @@ private:
|
|||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PthreadKeys {
|
||||||
|
public:
|
||||||
|
PthreadKeys() {}
|
||||||
|
virtual ~PthreadKeys() {}
|
||||||
|
|
||||||
|
bool CreateKey(int* key, PthreadKeyDestructor destructor);
|
||||||
|
bool GetKey(int key, int thread_id, void** data);
|
||||||
|
bool SetKey(int key, int thread_id, void* data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Map {
|
||||||
|
int thread_id = -1;
|
||||||
|
void* data = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Key {
|
||||||
|
bool used = false;
|
||||||
|
PthreadKeyDestructor destructor = nullptr;
|
||||||
|
std::vector<Map> specific_values;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
Key m_keys[256];
|
||||||
|
};
|
||||||
class PThreadCxt {
|
class PThreadCxt {
|
||||||
public:
|
public:
|
||||||
ScePthreadMutexattr* getDefaultMutexattr() {
|
ScePthreadMutexattr* getDefaultMutexattr() {
|
||||||
@ -138,6 +167,12 @@ public:
|
|||||||
void setDefaultRwattr(OrbisPthreadRwlockattr attr) {
|
void setDefaultRwattr(OrbisPthreadRwlockattr attr) {
|
||||||
m_default_Rwattr = attr;
|
m_default_Rwattr = attr;
|
||||||
}
|
}
|
||||||
|
PthreadKeys* getPthreadKeys() {
|
||||||
|
return m_pthread_keys;
|
||||||
|
}
|
||||||
|
void setPthreadKeys(PthreadKeys* keys) {
|
||||||
|
m_pthread_keys = keys;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ScePthreadMutexattr m_default_mutexattr = nullptr;
|
ScePthreadMutexattr m_default_mutexattr = nullptr;
|
||||||
@ -145,6 +180,7 @@ private:
|
|||||||
ScePthreadAttr m_default_attr = nullptr;
|
ScePthreadAttr m_default_attr = nullptr;
|
||||||
PThreadPool* m_pthread_pool = nullptr;
|
PThreadPool* m_pthread_pool = nullptr;
|
||||||
OrbisPthreadRwlockattr m_default_Rwattr = nullptr;
|
OrbisPthreadRwlockattr m_default_Rwattr = nullptr;
|
||||||
|
PthreadKeys* m_pthread_keys = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
void init_pthreads();
|
void init_pthreads();
|
||||||
|
102
src/core/libraries/kernel/threads/keys.cpp
Normal file
102
src/core/libraries/kernel/threads/keys.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "core/libraries/error_codes.h"
|
||||||
|
#include "core/libraries/libs.h"
|
||||||
|
#include "threads.h"
|
||||||
|
|
||||||
|
namespace Libraries::Kernel {
|
||||||
|
|
||||||
|
extern PThreadCxt* g_pthread_cxt;
|
||||||
|
|
||||||
|
bool PthreadKeys::CreateKey(int* key, PthreadKeyDestructor destructor) {
|
||||||
|
std::scoped_lock lk{m_mutex};
|
||||||
|
|
||||||
|
for (int index = 0; index < 256; index++) {
|
||||||
|
if (!m_keys[index].used) {
|
||||||
|
*key = index;
|
||||||
|
m_keys[index].used = true;
|
||||||
|
m_keys[index].destructor = destructor;
|
||||||
|
m_keys[index].specific_values.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool PthreadKeys::GetKey(int key, int thread_id, void** data) {
|
||||||
|
std::scoped_lock lk{m_mutex};
|
||||||
|
|
||||||
|
if (key < 0 || key >= 256 || !m_keys[key].used) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& v : m_keys[key].specific_values) {
|
||||||
|
if (v.thread_id == thread_id) {
|
||||||
|
*data = v.data;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*data = nullptr;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool PthreadKeys::SetKey(int key, int thread_id, void* data) {
|
||||||
|
std::scoped_lock lk{m_mutex};
|
||||||
|
|
||||||
|
if (key < 0 || key >= 256 || !m_keys[key].used) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& v : m_keys[key].specific_values) {
|
||||||
|
if (v.thread_id == thread_id) {
|
||||||
|
v.data = data;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map keymap = {thread_id, data};
|
||||||
|
m_keys[key].specific_values.push_back(keymap);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI scePthreadKeyCreate(OrbisPthreadKey* key, PthreadKeyDestructor destructor) {
|
||||||
|
if (key == nullptr) {
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_pthread_cxt->getPthreadKeys()->CreateKey(key, destructor)) {
|
||||||
|
return SCE_KERNEL_ERROR_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SCE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* PS4_SYSV_ABI scePthreadGetspecific(OrbisPthreadKey key) {
|
||||||
|
auto id = std::this_thread::get_id();
|
||||||
|
int thread_id = *(unsigned*)&id;
|
||||||
|
|
||||||
|
void* value = nullptr;
|
||||||
|
if (!g_pthread_cxt->getPthreadKeys()->GetKey(key, thread_id, &value)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI scePthreadSetspecific(OrbisPthreadKey key, /* const*/ void* value) {
|
||||||
|
|
||||||
|
auto id = std::this_thread::get_id();
|
||||||
|
int thread_id = *(unsigned*)&id;
|
||||||
|
|
||||||
|
if (!g_pthread_cxt->getPthreadKeys()->SetKey(key, thread_id, value)) {
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SCE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Libraries::Kernel
|
Loading…
Reference in New Issue
Block a user