mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-13 22:23:15 +00:00
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:
parent
6904764aab
commit
c4506da0ae
104 changed files with 5554 additions and 3979 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue