kernel: Rewrite pthread emulation (#1440)

* libkernel: Cleanup some function places

* kernel: Refactor thread functions

* kernel: It builds

* kernel: Fix a bunch of bugs, kernel thread heap

* kernel: File cleanup pt1

* File cleanup pt2

* File cleanup pt3

* File cleanup pt4

* kernel: Add missing funcs

* kernel: Add basic exceptions for linux

* gnmdriver: Add workload functions

* kernel: Fix new pthreads code on macOS. (#1441)

* kernel: Downgrade edeadlk to log

* gnmdriver: Add sceGnmSubmitCommandBuffersForWorkload

* exception: Add context register population for macOS. (#1444)

* kernel: Pthread rewrite touchups for Windows

* kernel: Multiplatform thread implementation

* mutex: Remove spamming log

* pthread_spec: Make assert into a log

* pthread_spec: Zero initialize array

* Attempt to fix non-Windows builds

* hotfix: change incorrect NID for scePthreadAttrSetaffinity

* scePthreadAttrSetaffinity implementation

* Attempt to fix Linux

* windows: Address a bunch of address space problems

* address_space: Fix unmap of region surrounded by placeholders

* libs: Reduce logging

* pthread: Implement condvar with waitable atomics and sleepqueue

* sleepq: Separate and make faster

* time: Remove delay execution

* Causes high cpu usage in Tohou Luna Nights

* kernel: Cleanup files again

* pthread: Add missing include

* semaphore: Use binary_semaphore instead of condvar

* Seems more reliable

* libraries/sysmodule: log module on `sceSysmoduleIsLoaded`

* libraries/kernel: implement `scePthreadSetPrio`

---------

Co-authored-by: squidbus <175574877+squidbus@users.noreply.github.com>
Co-authored-by: Daniel R. <47796739+polybiusproxy@users.noreply.github.com>
This commit is contained in:
TheTurtle 2024-11-21 22:59:38 +02:00 committed by GitHub
parent 6904764aab
commit c4506da0ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
104 changed files with 5554 additions and 3979 deletions

View file

@ -1,80 +1,63 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/singleton.h"
#include "core/linker.h"
#include "net_ctl_codes.h"
#include "net_ctl_obj.h"
#include <algorithm>
#include "core/libraries/network/net_ctl_codes.h"
#include "core/libraries/network/net_ctl_obj.h"
#include "core/tls.h"
Libraries::NetCtl::NetCtlInternal::NetCtlInternal() {
callbacks.fill({nullptr, nullptr});
nptoolCallbacks.fill({nullptr, nullptr});
}
namespace Libraries::NetCtl {
Libraries::NetCtl::NetCtlInternal::~NetCtlInternal() {}
NetCtlInternal::NetCtlInternal() = default;
s32 Libraries::NetCtl::NetCtlInternal::registerCallback(OrbisNetCtlCallback func, void* arg) {
std::unique_lock lock{m_mutex};
NetCtlInternal::~NetCtlInternal() = default;
s32 NetCtlInternal::RegisterCallback(OrbisNetCtlCallback func, void* arg) {
std::scoped_lock lock{m_mutex};
// Find the next available slot
int next_id = 0;
for (const auto& callback : callbacks) {
if (callback.func == nullptr) {
break;
}
next_id++;
}
if (next_id == 8) {
const auto it = std::ranges::find(callbacks, nullptr, &NetCtlCallback::func);
if (it == callbacks.end()) {
return ORBIS_NET_CTL_ERROR_CALLBACK_MAX;
}
const int next_id = std::distance(callbacks.begin(), it);
callbacks[next_id].func = func;
callbacks[next_id].arg = arg;
return next_id;
}
s32 Libraries::NetCtl::NetCtlInternal::registerNpToolkitCallback(
OrbisNetCtlCallbackForNpToolkit func, void* arg) {
std::unique_lock lock{m_mutex};
s32 NetCtlInternal::RegisterNpToolkitCallback(OrbisNetCtlCallbackForNpToolkit func, void* arg) {
std::scoped_lock lock{m_mutex};
// Find the next available slot
int next_id = 0;
for (const auto& callback : nptoolCallbacks) {
if (callback.func == nullptr) {
break;
}
next_id++;
}
if (next_id == 8) {
const auto it = std::ranges::find(nptool_callbacks, nullptr, &NetCtlCallbackForNpToolkit::func);
if (it == nptool_callbacks.end()) {
return ORBIS_NET_CTL_ERROR_CALLBACK_MAX;
}
nptoolCallbacks[next_id].func = func;
nptoolCallbacks[next_id].arg = arg;
const int next_id = std::distance(nptool_callbacks.begin(), it);
nptool_callbacks[next_id].func = func;
nptool_callbacks[next_id].arg = arg;
return next_id;
}
void Libraries::NetCtl::NetCtlInternal::checkCallback() {
std::unique_lock lock{m_mutex};
const auto* linker = Common::Singleton<Core::Linker>::Instance();
for (auto& callback : callbacks) {
if (callback.func != nullptr) {
linker->ExecuteGuest(callback.func, ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED,
callback.arg);
void NetCtlInternal::CheckCallback() {
std::scoped_lock lock{m_mutex};
for (const auto [func, arg] : callbacks) {
if (func != nullptr) {
Core::ExecuteGuest(func, ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED, arg);
}
}
}
void Libraries::NetCtl::NetCtlInternal::checkNpToolkitCallback() {
std::unique_lock lock{m_mutex};
const auto* linker = Common::Singleton<Core::Linker>::Instance();
for (auto& callback : nptoolCallbacks) {
if (callback.func != nullptr) {
linker->ExecuteGuest(callback.func, ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED,
callback.arg);
void NetCtlInternal::CheckNpToolkitCallback() {
std::scoped_lock lock{m_mutex};
for (const auto [func, arg] : nptool_callbacks) {
if (func != nullptr) {
Core::ExecuteGuest(func, ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED, arg);
}
}
}
} // namespace Libraries::NetCtl

View file

@ -3,9 +3,7 @@
#pragma once
#include <condition_variable>
#include <mutex>
#include "common/types.h"
namespace Libraries::NetCtl {
@ -25,16 +23,17 @@ struct NetCtlCallbackForNpToolkit {
class NetCtlInternal {
public:
NetCtlInternal();
explicit NetCtlInternal();
~NetCtlInternal();
s32 registerCallback(OrbisNetCtlCallback func, void* arg);
s32 registerNpToolkitCallback(OrbisNetCtlCallbackForNpToolkit func, void* arg);
void checkCallback();
void checkNpToolkitCallback();
s32 RegisterCallback(OrbisNetCtlCallback func, void* arg);
s32 RegisterNpToolkitCallback(OrbisNetCtlCallbackForNpToolkit func, void* arg);
void CheckCallback();
void CheckNpToolkitCallback();
public:
std::array<NetCtlCallback, 8> nptoolCallbacks;
std::array<NetCtlCallbackForNpToolkit, 8> callbacks;
std::array<NetCtlCallbackForNpToolkit, 8> nptool_callbacks{};
std::array<NetCtlCallback, 8> callbacks{};
std::mutex m_mutex;
};
} // namespace Libraries::NetCtl

View file

@ -13,7 +13,6 @@
#endif
#include "common/logging/log.h"
#include "common/singleton.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"
#include "core/libraries/network/net_ctl_codes.h"
@ -21,6 +20,8 @@
namespace Libraries::NetCtl {
static NetCtlInternal netctl;
int PS4_SYSV_ABI sceNetBweCheckCallbackIpcInt() {
LOG_ERROR(Lib_NetCtl, "(STUBBED) called");
return ORBIS_OK;
@ -92,8 +93,7 @@ int PS4_SYSV_ABI sceNetCtlUnregisterCallbackV6() {
}
int PS4_SYSV_ABI sceNetCtlCheckCallback() {
auto* netctl = Common::Singleton<Libraries::NetCtl::NetCtlInternal>::Instance();
netctl->checkCallback();
netctl.CheckCallback();
return ORBIS_OK;
}
@ -298,8 +298,7 @@ int PS4_SYSV_ABI sceNetCtlRegisterCallback(OrbisNetCtlCallback func, void* arg,
if (!func || !cid) {
return ORBIS_NET_CTL_ERROR_INVALID_ADDR;
}
auto* netctl = Common::Singleton<Libraries::NetCtl::NetCtlInternal>::Instance();
s32 result = netctl->registerCallback(func, arg);
s32 result = netctl.RegisterCallback(func, arg);
if (result < 0) {
return result;
} else {
@ -374,8 +373,7 @@ int PS4_SYSV_ABI Func_D8DCB6973537A3DC() {
}
int PS4_SYSV_ABI sceNetCtlCheckCallbackForNpToolkit() {
auto* netctl = Common::Singleton<Libraries::NetCtl::NetCtlInternal>::Instance();
netctl->checkNpToolkitCallback();
netctl.CheckNpToolkitCallback();
return ORBIS_OK;
}
@ -389,8 +387,7 @@ int PS4_SYSV_ABI sceNetCtlRegisterCallbackForNpToolkit(OrbisNetCtlCallbackForNpT
if (!func || !cid) {
return ORBIS_NET_CTL_ERROR_INVALID_ADDR;
}
auto* netctl = Common::Singleton<Libraries::NetCtl::NetCtlInternal>::Instance();
s32 result = netctl->registerNpToolkitCallback(func, arg);
s32 result = netctl.RegisterNpToolkitCallback(func, arg);
if (result < 0) {
return result;
} else {

View file

@ -4,7 +4,7 @@
#pragma once
#include "common/types.h"
#include "net_ctl_obj.h"
#include "core/libraries/network/net_ctl_obj.h"
namespace Core::Loader {
class SymbolsResolver;