mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-20 19:44:46 +00:00
kernel: Rework keys
This commit is contained in:
parent
1307be09db
commit
b7b1487d99
6 changed files with 40 additions and 100 deletions
|
@ -85,7 +85,7 @@ struct AddressSpace::Impl {
|
|||
}
|
||||
}
|
||||
|
||||
void* Map(VAddr virtual_addr, PAddr phys_addr, size_t size, ULONG prot, HANDLE fd = nullptr) {
|
||||
void* Map(VAddr virtual_addr, PAddr phys_addr, size_t size, ULONG prot, uintptr_t fd = 0) {
|
||||
const auto it = placeholders.find(virtual_addr);
|
||||
ASSERT_MSG(it != placeholders.end(), "Cannot map already mapped region");
|
||||
ASSERT_MSG(virtual_addr >= it->lower() && virtual_addr + size <= it->upper(),
|
||||
|
@ -117,7 +117,7 @@ struct AddressSpace::Impl {
|
|||
// Perform the map.
|
||||
void* ptr = nullptr;
|
||||
if (phys_addr != -1) {
|
||||
HANDLE backing = fd ? fd : backing_handle;
|
||||
HANDLE backing = fd ? reinterpret_cast<HANDLE>(fd) : backing_handle;
|
||||
ptr = MapViewOfFile3(backing, process, reinterpret_cast<PVOID>(virtual_addr), phys_addr,
|
||||
size, MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
||||
} else {
|
||||
|
|
|
@ -881,6 +881,11 @@ int PS4_SYSV_ABI scePthreadAttrGet(ScePthread thread, ScePthreadAttr* attr) {
|
|||
|
||||
static void cleanup_thread(void* arg) {
|
||||
auto* thread = static_cast<ScePthread>(arg);
|
||||
for (const auto& [key, destructor] : thread->key_destructors) {
|
||||
if (void* value = pthread_getspecific(key); value != nullptr) {
|
||||
destructor(value);
|
||||
}
|
||||
}
|
||||
thread->is_almost_done = true;
|
||||
}
|
||||
|
||||
|
@ -899,7 +904,7 @@ static void* run_thread(void* arg) {
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr,
|
||||
pthreadEntryFunc start_routine, void* arg, const char* name) {
|
||||
PthreadEntryFunc start_routine, void* arg, const char* name) {
|
||||
if (thread == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
@ -1161,7 +1166,7 @@ int PS4_SYSV_ABI posix_pthread_attr_setdetachstate(ScePthreadAttr* attr, int det
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_create_name_np(ScePthread* thread, const ScePthreadAttr* attr,
|
||||
pthreadEntryFunc start_routine, void* arg,
|
||||
PthreadEntryFunc start_routine, void* arg,
|
||||
const char* name) {
|
||||
LOG_INFO(Kernel_Pthread, "posix pthread_create redirect to scePthreadCreate: name = {}", name);
|
||||
|
||||
|
@ -1176,7 +1181,7 @@ int PS4_SYSV_ABI posix_pthread_create_name_np(ScePthread* thread, const ScePthre
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_create(ScePthread* thread, const ScePthreadAttr* attr,
|
||||
pthreadEntryFunc start_routine, void* arg) {
|
||||
PthreadEntryFunc start_routine, void* arg) {
|
||||
return posix_pthread_create_name_np(thread, attr, start_routine, arg, "NoName");
|
||||
}
|
||||
|
||||
|
@ -1240,19 +1245,7 @@ int PS4_SYSV_ABI scePthreadSetschedparam(ScePthread thread, int policy,
|
|||
int PS4_SYSV_ABI scePthreadOnce(int* once_control, void (*init_routine)(void)) {
|
||||
return pthread_once(reinterpret_cast<pthread_once_t*>(once_control), init_routine);
|
||||
}
|
||||
int PS4_SYSV_ABI posix_pthread_create(ScePthread* thread, const ScePthreadAttr* attr,
|
||||
pthreadEntryFunc start_routine, void* arg) {
|
||||
LOG_INFO(Kernel_Pthread, "posix pthread_create redirect to scePthreadCreate");
|
||||
|
||||
int result = scePthreadCreate(thread, attr, start_routine, arg, "");
|
||||
if (result != 0) {
|
||||
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
|
||||
? result + -SCE_KERNEL_ERROR_UNKNOWN
|
||||
: POSIX_EOTHER;
|
||||
return rt;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("lZzFeSxPl08", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setcancelstate);
|
||||
LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init);
|
||||
|
@ -1349,6 +1342,7 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
|||
// libs
|
||||
RwlockSymbolsRegister(sym);
|
||||
SemaphoreSymbolsRegister(sym);
|
||||
KeySymbolsRegister(sym);
|
||||
}
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
|
|
@ -39,22 +39,24 @@ using ScePthreadCond = PthreadCondInternal*;
|
|||
using ScePthreadCondattr = PthreadCondAttrInternal*;
|
||||
using OrbisPthreadRwlock = PthreadRwInternal*;
|
||||
using OrbisPthreadRwlockattr = PthreadRwLockAttrInternal*;
|
||||
using OrbisPthreadKey = int;
|
||||
using PthreadKeyDestructor = PS4_SYSV_ABI void (*)(void*);
|
||||
using OrbisPthreadKey = u32;
|
||||
|
||||
using pthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*);
|
||||
using PthreadKeyDestructor = PS4_SYSV_ABI void (*)(void*);
|
||||
using PthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*);
|
||||
|
||||
struct PthreadInternal {
|
||||
u8 reserved[4096];
|
||||
std::string name;
|
||||
pthread_t pth;
|
||||
ScePthreadAttr attr;
|
||||
pthreadEntryFunc entry;
|
||||
PthreadEntryFunc entry;
|
||||
void* arg;
|
||||
std::atomic_bool is_started;
|
||||
std::atomic_bool is_detached;
|
||||
std::atomic_bool is_almost_done;
|
||||
std::atomic_bool is_free;
|
||||
using Destructor = std::pair<OrbisPthreadKey, PthreadKeyDestructor>;
|
||||
std::vector<Destructor> key_destructors;
|
||||
};
|
||||
|
||||
struct PthreadAttrInternal {
|
||||
|
@ -195,7 +197,7 @@ int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr,
|
|||
const /*SceKernelCpumask*/ u64 mask);
|
||||
int PS4_SYSV_ABI scePthreadSetaffinity(ScePthread thread, const /*SceKernelCpumask*/ u64 mask);
|
||||
int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr,
|
||||
pthreadEntryFunc start_routine, void* arg, const char* name);
|
||||
PthreadEntryFunc start_routine, void* arg, const char* name);
|
||||
|
||||
/***
|
||||
* Mutex calls
|
||||
|
|
|
@ -1,103 +1,47 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <thread>
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/kernel/threads/threads.h"
|
||||
#include "core/libraries/kernel/thread_management.h"
|
||||
#include "core/libraries/libs.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 ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
if (!g_pthread_cxt->getPthreadKeys()->CreateKey(key, destructor)) {
|
||||
return ORBIS_KERNEL_ERROR_EAGAIN;
|
||||
int result = pthread_key_create(key, nullptr);
|
||||
if (destructor) {
|
||||
auto thread = scePthreadSelf();
|
||||
thread->key_destructors.emplace_back(*key, destructor);
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
if (result != 0) {
|
||||
LOG_ERROR(Kernel_Pthread, "scePthreadKeyCreate: error = {}", result);
|
||||
result += ORBIS_KERNEL_ERROR_UNKNOWN;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
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;
|
||||
return pthread_getspecific(key);
|
||||
}
|
||||
|
||||
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 ORBIS_KERNEL_ERROR_EINVAL;
|
||||
int result = pthread_setspecific(key, value);
|
||||
if (result != 0) {
|
||||
LOG_ERROR(Kernel_Pthread, "scePthreadSetspecific: error = {}", result);
|
||||
result += ORBIS_KERNEL_ERROR_UNKNOWN;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
void KeySymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("geDaqgH9lTg", "libkernel", 1, "libkernel", 1, 1, scePthreadKeyCreate);
|
||||
LIB_FUNCTION("eoht7mQOCmo", "libkernel", 1, "libkernel", 1, 1, scePthreadGetspecific);
|
||||
LIB_FUNCTION("+BzXYkqYeLE", "libkernel", 1, "libkernel", 1, 1, scePthreadSetspecific);
|
||||
}
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
|
|
@ -15,5 +15,6 @@ int PS4_SYSV_ABI scePthreadRwlockattrInit(OrbisPthreadRwlockattr* attr);
|
|||
|
||||
void SemaphoreSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
||||
void RwlockSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
||||
void KeySymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include "common/assert.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/thread.h"
|
||||
|
|
Loading…
Add table
Reference in a new issue