mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-26 20:15:03 +00:00
kernel: Rework keys
This commit is contained in:
parent
1307be09db
commit
b7b1487d99
@ -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);
|
const auto it = placeholders.find(virtual_addr);
|
||||||
ASSERT_MSG(it != placeholders.end(), "Cannot map already mapped region");
|
ASSERT_MSG(it != placeholders.end(), "Cannot map already mapped region");
|
||||||
ASSERT_MSG(virtual_addr >= it->lower() && virtual_addr + size <= it->upper(),
|
ASSERT_MSG(virtual_addr >= it->lower() && virtual_addr + size <= it->upper(),
|
||||||
@ -117,7 +117,7 @@ struct AddressSpace::Impl {
|
|||||||
// Perform the map.
|
// Perform the map.
|
||||||
void* ptr = nullptr;
|
void* ptr = nullptr;
|
||||||
if (phys_addr != -1) {
|
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,
|
ptr = MapViewOfFile3(backing, process, reinterpret_cast<PVOID>(virtual_addr), phys_addr,
|
||||||
size, MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
size, MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -881,6 +881,11 @@ int PS4_SYSV_ABI scePthreadAttrGet(ScePthread thread, ScePthreadAttr* attr) {
|
|||||||
|
|
||||||
static void cleanup_thread(void* arg) {
|
static void cleanup_thread(void* arg) {
|
||||||
auto* thread = static_cast<ScePthread>(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;
|
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,
|
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) {
|
if (thread == nullptr) {
|
||||||
return SCE_KERNEL_ERROR_EINVAL;
|
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,
|
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) {
|
const char* name) {
|
||||||
LOG_INFO(Kernel_Pthread, "posix pthread_create redirect to scePthreadCreate: name = {}", 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,
|
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");
|
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)) {
|
int PS4_SYSV_ABI scePthreadOnce(int* once_control, void (*init_routine)(void)) {
|
||||||
return pthread_once(reinterpret_cast<pthread_once_t*>(once_control), init_routine);
|
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) {
|
void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("lZzFeSxPl08", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setcancelstate);
|
LIB_FUNCTION("lZzFeSxPl08", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setcancelstate);
|
||||||
LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init);
|
LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init);
|
||||||
@ -1349,6 +1342,7 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
|||||||
// libs
|
// libs
|
||||||
RwlockSymbolsRegister(sym);
|
RwlockSymbolsRegister(sym);
|
||||||
SemaphoreSymbolsRegister(sym);
|
SemaphoreSymbolsRegister(sym);
|
||||||
|
KeySymbolsRegister(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
@ -39,22 +39,24 @@ using ScePthreadCond = PthreadCondInternal*;
|
|||||||
using ScePthreadCondattr = PthreadCondAttrInternal*;
|
using ScePthreadCondattr = PthreadCondAttrInternal*;
|
||||||
using OrbisPthreadRwlock = PthreadRwInternal*;
|
using OrbisPthreadRwlock = PthreadRwInternal*;
|
||||||
using OrbisPthreadRwlockattr = PthreadRwLockAttrInternal*;
|
using OrbisPthreadRwlockattr = PthreadRwLockAttrInternal*;
|
||||||
using OrbisPthreadKey = int;
|
using OrbisPthreadKey = u32;
|
||||||
using PthreadKeyDestructor = PS4_SYSV_ABI void (*)(void*);
|
|
||||||
|
|
||||||
using pthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*);
|
using PthreadKeyDestructor = PS4_SYSV_ABI void (*)(void*);
|
||||||
|
using PthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*);
|
||||||
|
|
||||||
struct PthreadInternal {
|
struct PthreadInternal {
|
||||||
u8 reserved[4096];
|
u8 reserved[4096];
|
||||||
std::string name;
|
std::string name;
|
||||||
pthread_t pth;
|
pthread_t pth;
|
||||||
ScePthreadAttr attr;
|
ScePthreadAttr attr;
|
||||||
pthreadEntryFunc entry;
|
PthreadEntryFunc entry;
|
||||||
void* arg;
|
void* arg;
|
||||||
std::atomic_bool is_started;
|
std::atomic_bool is_started;
|
||||||
std::atomic_bool is_detached;
|
std::atomic_bool is_detached;
|
||||||
std::atomic_bool is_almost_done;
|
std::atomic_bool is_almost_done;
|
||||||
std::atomic_bool is_free;
|
std::atomic_bool is_free;
|
||||||
|
using Destructor = std::pair<OrbisPthreadKey, PthreadKeyDestructor>;
|
||||||
|
std::vector<Destructor> key_destructors;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PthreadAttrInternal {
|
struct PthreadAttrInternal {
|
||||||
@ -195,7 +197,7 @@ int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr,
|
|||||||
const /*SceKernelCpumask*/ u64 mask);
|
const /*SceKernelCpumask*/ u64 mask);
|
||||||
int PS4_SYSV_ABI scePthreadSetaffinity(ScePthread thread, 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,
|
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
|
* Mutex calls
|
||||||
|
@ -1,103 +1,47 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
#include "common/logging/log.h"
|
|
||||||
#include "core/libraries/error_codes.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"
|
#include "core/libraries/libs.h"
|
||||||
|
|
||||||
namespace Libraries::Kernel {
|
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) {
|
int PS4_SYSV_ABI scePthreadKeyCreate(OrbisPthreadKey* key, PthreadKeyDestructor destructor) {
|
||||||
if (key == nullptr) {
|
if (key == nullptr) {
|
||||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_pthread_cxt->getPthreadKeys()->CreateKey(key, destructor)) {
|
int result = pthread_key_create(key, nullptr);
|
||||||
return ORBIS_KERNEL_ERROR_EAGAIN;
|
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) {
|
void* PS4_SYSV_ABI scePthreadGetspecific(OrbisPthreadKey key) {
|
||||||
auto id = std::this_thread::get_id();
|
return pthread_getspecific(key);
|
||||||
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) {
|
int PS4_SYSV_ABI scePthreadSetspecific(OrbisPthreadKey key, /* const*/ void* value) {
|
||||||
auto id = std::this_thread::get_id();
|
int result = pthread_setspecific(key, value);
|
||||||
int thread_id = *(unsigned*)&id;
|
if (result != 0) {
|
||||||
|
LOG_ERROR(Kernel_Pthread, "scePthreadSetspecific: error = {}", result);
|
||||||
if (!g_pthread_cxt->getPthreadKeys()->SetKey(key, thread_id, value)) {
|
result += ORBIS_KERNEL_ERROR_UNKNOWN;
|
||||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
|
||||||
}
|
}
|
||||||
|
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
|
} // namespace Libraries::Kernel
|
||||||
|
@ -15,5 +15,6 @@ int PS4_SYSV_ABI scePthreadRwlockattrInit(OrbisPthreadRwlockattr* attr);
|
|||||||
|
|
||||||
void SemaphoreSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
void SemaphoreSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
||||||
void RwlockSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
void RwlockSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
||||||
|
void KeySymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user