mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-02-04 20:48:15 +00:00
The way to Unity, pt.3 (#1681)
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
This commit is contained in:
parent
1793fd4df0
commit
fea2593ab4
|
@ -9,6 +9,7 @@ NtClose_t NtClose = nullptr;
|
|||
NtSetInformationFile_t NtSetInformationFile = nullptr;
|
||||
NtCreateThread_t NtCreateThread = nullptr;
|
||||
NtTerminateThread_t NtTerminateThread = nullptr;
|
||||
NtQueueApcThreadEx_t NtQueueApcThreadEx = nullptr;
|
||||
|
||||
namespace Common::NtApi {
|
||||
|
||||
|
@ -21,6 +22,7 @@ void Initialize() {
|
|||
(NtSetInformationFile_t)GetProcAddress(nt_handle, "NtSetInformationFile");
|
||||
NtCreateThread = (NtCreateThread_t)GetProcAddress(nt_handle, "NtCreateThread");
|
||||
NtTerminateThread = (NtTerminateThread_t)GetProcAddress(nt_handle, "NtTerminateThread");
|
||||
NtQueueApcThreadEx = (NtQueueApcThreadEx_t)GetProcAddress(nt_handle, "NtQueueApcThreadEx");
|
||||
}
|
||||
|
||||
} // namespace Common::NtApi
|
||||
|
|
|
@ -509,6 +509,20 @@ typedef struct _TEB { /* win32/win64 */
|
|||
static_assert(offsetof(TEB, DeallocationStack) ==
|
||||
0x1478); /* The only member we care about at the moment */
|
||||
|
||||
typedef enum _QUEUE_USER_APC_FLAGS {
|
||||
QueueUserApcFlagsNone,
|
||||
QueueUserApcFlagsSpecialUserApc,
|
||||
QueueUserApcFlagsMaxValue
|
||||
} QUEUE_USER_APC_FLAGS;
|
||||
|
||||
typedef union _USER_APC_OPTION {
|
||||
ULONG_PTR UserApcFlags;
|
||||
HANDLE MemoryReserveHandle;
|
||||
} USER_APC_OPTION, *PUSER_APC_OPTION;
|
||||
|
||||
using PPS_APC_ROUTINE = void (*)(PVOID ApcArgument1, PVOID ApcArgument2, PVOID ApcArgument3,
|
||||
PCONTEXT Context);
|
||||
|
||||
typedef u64(__stdcall* NtClose_t)(HANDLE Handle);
|
||||
|
||||
typedef u64(__stdcall* NtSetInformationFile_t)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock,
|
||||
|
@ -522,10 +536,16 @@ typedef u64(__stdcall* NtCreateThread_t)(PHANDLE ThreadHandle, ACCESS_MASK Desir
|
|||
|
||||
typedef u64(__stdcall* NtTerminateThread_t)(HANDLE ThreadHandle, u64 ExitStatus);
|
||||
|
||||
typedef u64(__stdcall* NtQueueApcThreadEx_t)(HANDLE ThreadHandle,
|
||||
USER_APC_OPTION UserApcReserveHandle,
|
||||
PPS_APC_ROUTINE ApcRoutine, PVOID ApcArgument1,
|
||||
PVOID ApcArgument2, PVOID ApcArgument3);
|
||||
|
||||
extern NtClose_t NtClose;
|
||||
extern NtSetInformationFile_t NtSetInformationFile;
|
||||
extern NtCreateThread_t NtCreateThread;
|
||||
extern NtTerminateThread_t NtTerminateThread;
|
||||
extern NtQueueApcThreadEx_t NtQueueApcThreadEx;
|
||||
|
||||
namespace Common::NtApi {
|
||||
void Initialize();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/thread.h"
|
||||
#include "core/libraries/ajm/ajm.h"
|
||||
#include "core/libraries/ajm/ajm_at9.h"
|
||||
#include "core/libraries/ajm/ajm_context.h"
|
||||
|
@ -53,6 +54,7 @@ s32 AjmContext::ModuleRegister(AjmCodecType type) {
|
|||
}
|
||||
|
||||
void AjmContext::WorkerThread(std::stop_token stop) {
|
||||
Common::SetCurrentThreadName("shadPS4:AjmWorker");
|
||||
while (!stop.stop_requested()) {
|
||||
auto batch = batch_queue.PopWait(stop);
|
||||
if (batch != nullptr) {
|
||||
|
|
|
@ -46,7 +46,7 @@ void KernelSignalRequest() {
|
|||
}
|
||||
|
||||
static void KernelServiceThread(std::stop_token stoken) {
|
||||
Common::SetCurrentThreadName("shadPS4:Kernel_ServiceThread");
|
||||
Common::SetCurrentThreadName("shadPS4:KernelServiceThread");
|
||||
|
||||
while (!stoken.stop_requested()) {
|
||||
HLE_TRACE;
|
||||
|
@ -255,6 +255,7 @@ void RegisterKernel(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("NWtTN10cJzE", "libSceLibcInternalExt", 1, "libSceLibcInternal", 1, 1,
|
||||
sceLibcHeapGetTraceInfo);
|
||||
LIB_FUNCTION("FxVZqBAA7ks", "libkernel", 1, "libkernel", 1, 1, ps4__write);
|
||||
LIB_FUNCTION("FN4gaPmuFV8", "libScePosix", 1, "libkernel", 1, 1, ps4__write);
|
||||
}
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
|
|
@ -492,8 +492,7 @@ int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
auto* memory = Core::Memory::Instance();
|
||||
memory->UnmapMemory(std::bit_cast<VAddr>(addr), len);
|
||||
return ORBIS_OK;
|
||||
return memory->UnmapMemory(std::bit_cast<VAddr>(addr), len);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_munmap(void* addr, size_t len) {
|
||||
|
|
|
@ -45,10 +45,11 @@ s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char* moduleFileName, size_t arg
|
|||
|
||||
// Load PRX module and relocate any modules that import it.
|
||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||
u32 handle = linker->LoadModule(path, true);
|
||||
if (handle == -1) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
u32 handle = linker->FindByName(path);
|
||||
if (handle != -1) {
|
||||
return handle;
|
||||
}
|
||||
handle = linker->LoadModule(path, true);
|
||||
auto* module = linker->GetModule(handle);
|
||||
linker->RelocateAnyImports(module);
|
||||
|
||||
|
@ -60,7 +61,10 @@ s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char* moduleFileName, size_t arg
|
|||
// Retrieve and verify proc param according to libkernel.
|
||||
u64* param = module->GetProcParam<u64*>();
|
||||
ASSERT_MSG(!param || param[0] >= 0x18, "Invalid module param size: {}", param[0]);
|
||||
module->Start(args, argp, param);
|
||||
s32 ret = module->Start(args, argp, param);
|
||||
if (pRes) {
|
||||
*pRes = ret;
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
@ -104,6 +108,9 @@ s32 PS4_SYSV_ABI sceKernelGetModuleInfoForUnwind(VAddr addr, int flags,
|
|||
LOG_INFO(Lib_Kernel, "called addr = {:#x}, flags = {:#x}", addr, flags);
|
||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||
auto* module = linker->FindByAddress(addr);
|
||||
if (!module) {
|
||||
return ORBIS_KERNEL_ERROR_EFAULT;
|
||||
}
|
||||
const auto mod_info = module->GetModuleInfoEx();
|
||||
|
||||
// Fill in module info.
|
||||
|
|
|
@ -87,14 +87,23 @@ public:
|
|||
template <class Rep, class Period>
|
||||
bool try_acquire_for(const std::chrono::duration<Rep, Period>& rel_time) {
|
||||
#ifdef _WIN64
|
||||
const auto rel_time_ms = std::chrono::ceil<std::chrono::milliseconds>(rel_time);
|
||||
const u64 timeout_ms = static_cast<u64>(rel_time_ms.count());
|
||||
const auto start_time = std::chrono::high_resolution_clock::now();
|
||||
auto rel_time_ms = std::chrono::ceil<std::chrono::milliseconds>(rel_time);
|
||||
|
||||
if (timeout_ms == 0) {
|
||||
return false;
|
||||
while (rel_time_ms.count() > 0) {
|
||||
u64 timeout_ms = static_cast<u64>(rel_time_ms.count());
|
||||
u64 res = WaitForSingleObjectEx(sem, timeout_ms, true);
|
||||
if (res == WAIT_OBJECT_0) {
|
||||
return true;
|
||||
} else if (res == WAIT_IO_COMPLETION) {
|
||||
auto elapsed_time = std::chrono::high_resolution_clock::now() - start_time;
|
||||
rel_time_ms -= std::chrono::duration_cast<std::chrono::milliseconds>(elapsed_time);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return WaitForSingleObjectEx(sem, timeout_ms, true) == WAIT_OBJECT_0;
|
||||
return false;
|
||||
#elif defined(__APPLE__)
|
||||
const auto rel_time_ns = std::chrono::ceil<std::chrono::nanoseconds>(rel_time).count();
|
||||
const auto timeout = dispatch_time(DISPATCH_TIME_NOW, rel_time_ns);
|
||||
|
@ -107,19 +116,26 @@ public:
|
|||
template <class Clock, class Duration>
|
||||
bool try_acquire_until(const std::chrono::time_point<Clock, Duration>& abs_time) {
|
||||
#ifdef _WIN64
|
||||
const auto now = Clock::now();
|
||||
if (now >= abs_time) {
|
||||
const auto start_time = Clock::now();
|
||||
if (start_time >= abs_time) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto rel_time = std::chrono::ceil<std::chrono::milliseconds>(abs_time - now);
|
||||
const u64 timeout_ms = static_cast<u64>(rel_time.count());
|
||||
if (timeout_ms == 0) {
|
||||
return false;
|
||||
auto rel_time = std::chrono::ceil<std::chrono::milliseconds>(abs_time - start_time);
|
||||
while (rel_time.count() > 0) {
|
||||
u64 timeout_ms = static_cast<u64>(rel_time.count());
|
||||
u64 res = WaitForSingleObjectEx(sem, timeout_ms, true);
|
||||
if (res == WAIT_OBJECT_0) {
|
||||
return true;
|
||||
} else if (res == WAIT_IO_COMPLETION) {
|
||||
auto elapsed_time = Clock::now() - start_time;
|
||||
rel_time -= std::chrono::duration_cast<std::chrono::milliseconds>(elapsed_time);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
u64 res = WaitForSingleObjectEx(sem, static_cast<u64>(timeout_ms), true);
|
||||
return res == WAIT_OBJECT_0;
|
||||
return false;
|
||||
#elif defined(__APPLE__)
|
||||
auto abs_s = std::chrono::time_point_cast<std::chrono::seconds>(abs_time);
|
||||
auto abs_ns = std::chrono::time_point_cast<std::chrono::nanoseconds>(abs_time) -
|
||||
|
|
|
@ -132,6 +132,33 @@ public:
|
|||
m_bits &= bits;
|
||||
}
|
||||
|
||||
void Cancel(u64 setPattern, int* numWaitThreads) {
|
||||
std::unique_lock lock{m_mutex};
|
||||
|
||||
while (m_status != Status::Set) {
|
||||
m_mutex.unlock();
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
if (numWaitThreads) {
|
||||
*numWaitThreads = m_waiting_threads;
|
||||
}
|
||||
|
||||
m_status = Status::Canceled;
|
||||
m_bits = setPattern;
|
||||
|
||||
m_cond_var.notify_all();
|
||||
|
||||
while (m_waiting_threads > 0) {
|
||||
m_mutex.unlock();
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
m_status = Status::Set;
|
||||
}
|
||||
|
||||
private:
|
||||
enum class Status { Set, Canceled, Deleted };
|
||||
|
||||
|
@ -232,7 +259,8 @@ int PS4_SYSV_ABI sceKernelClearEventFlag(OrbisKernelEventFlag ef, u64 bitPattern
|
|||
|
||||
int PS4_SYSV_ABI sceKernelCancelEventFlag(OrbisKernelEventFlag ef, u64 setPattern,
|
||||
int* pNumWaitThreads) {
|
||||
LOG_ERROR(Kernel_Event, "(STUBBED) called");
|
||||
LOG_DEBUG(Kernel_Event, "called");
|
||||
ef->Cancel(setPattern, pNumWaitThreads);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "core/libraries/libs.h"
|
||||
|
||||
#ifdef _WIN64
|
||||
#include "common/ntapi.h"
|
||||
#else
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
@ -64,6 +65,34 @@ void SigactionHandler(int signum, siginfo_t* inf, ucontext_t* raw_context) {
|
|||
handler(POSIX_SIGUSR1, &ctx);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void ExceptionHandler(void* arg1, void* arg2, void* arg3, PCONTEXT context) {
|
||||
const char* thrName = (char*)arg1;
|
||||
LOG_INFO(Lib_Kernel, "Exception raised successfully on thread '{}'", thrName);
|
||||
const auto handler = Handlers[POSIX_SIGUSR1];
|
||||
if (handler) {
|
||||
auto ctx = Ucontext{};
|
||||
ctx.uc_mcontext.mc_r8 = context->R8;
|
||||
ctx.uc_mcontext.mc_r9 = context->R9;
|
||||
ctx.uc_mcontext.mc_r10 = context->R10;
|
||||
ctx.uc_mcontext.mc_r11 = context->R11;
|
||||
ctx.uc_mcontext.mc_r12 = context->R12;
|
||||
ctx.uc_mcontext.mc_r13 = context->R13;
|
||||
ctx.uc_mcontext.mc_r14 = context->R14;
|
||||
ctx.uc_mcontext.mc_r15 = context->R15;
|
||||
ctx.uc_mcontext.mc_rdi = context->Rdi;
|
||||
ctx.uc_mcontext.mc_rsi = context->Rsi;
|
||||
ctx.uc_mcontext.mc_rbp = context->Rbp;
|
||||
ctx.uc_mcontext.mc_rbx = context->Rbx;
|
||||
ctx.uc_mcontext.mc_rdx = context->Rdx;
|
||||
ctx.uc_mcontext.mc_rax = context->Rax;
|
||||
ctx.uc_mcontext.mc_rcx = context->Rcx;
|
||||
ctx.uc_mcontext.mc_rsp = context->Rsp;
|
||||
ctx.uc_mcontext.mc_fs = context->SegFs;
|
||||
ctx.uc_mcontext.mc_gs = context->SegGs;
|
||||
handler(POSIX_SIGUSR1, &ctx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int PS4_SYSV_ABI sceKernelInstallExceptionHandler(s32 signum, SceKernelExceptionHandler handler) {
|
||||
|
@ -73,9 +102,7 @@ int PS4_SYSV_ABI sceKernelInstallExceptionHandler(s32 signum, SceKernelException
|
|||
}
|
||||
ASSERT_MSG(!Handlers[POSIX_SIGUSR1], "Invalid parameters");
|
||||
Handlers[POSIX_SIGUSR1] = handler;
|
||||
#ifdef _WIN64
|
||||
UNREACHABLE_MSG("Missing exception implementation");
|
||||
#else
|
||||
#ifndef _WIN64
|
||||
struct sigaction act = {};
|
||||
act.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||
act.sa_sigaction = reinterpret_cast<decltype(act.sa_sigaction)>(SigactionHandler);
|
||||
|
@ -91,9 +118,7 @@ int PS4_SYSV_ABI sceKernelRemoveExceptionHandler(s32 signum) {
|
|||
}
|
||||
ASSERT_MSG(Handlers[POSIX_SIGUSR1], "Invalid parameters");
|
||||
Handlers[POSIX_SIGUSR1] = nullptr;
|
||||
#ifdef _WIN64
|
||||
UNREACHABLE_MSG("Missing exception implementation");
|
||||
#else
|
||||
#ifndef _WIN64
|
||||
struct sigaction act = {};
|
||||
act.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||
act.sa_sigaction = nullptr;
|
||||
|
@ -103,13 +128,18 @@ int PS4_SYSV_ABI sceKernelRemoveExceptionHandler(s32 signum) {
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) {
|
||||
LOG_ERROR(Lib_Kernel, "Raising exception");
|
||||
LOG_WARNING(Lib_Kernel, "Raising exception on thread '{}'", thread->name);
|
||||
ASSERT_MSG(signum == POSIX_SIGUSR1, "Attempting to raise non user defined signal!");
|
||||
#ifdef _WIN64
|
||||
UNREACHABLE_MSG("Missing exception implementation");
|
||||
#else
|
||||
#ifndef _WIN64
|
||||
pthread_t pthr = *reinterpret_cast<pthread_t*>(thread->native_thr.GetHandle());
|
||||
pthread_kill(pthr, SIGUSR2);
|
||||
#else
|
||||
USER_APC_OPTION option;
|
||||
option.UserApcFlags = QueueUserApcFlagsSpecialUserApc;
|
||||
|
||||
u64 res = NtQueueApcThreadEx(reinterpret_cast<HANDLE>(thread->native_thr.GetHandle()), option,
|
||||
ExceptionHandler, (void*)thread->name.c_str(), nullptr, nullptr);
|
||||
ASSERT(res == 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -540,6 +540,8 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("onNY9Byn-W8", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_join));
|
||||
LIB_FUNCTION("P41kTWUS3EI", "libkernel", 1, "libkernel", 1, 1,
|
||||
ORBIS(posix_pthread_getschedparam));
|
||||
LIB_FUNCTION("oIRFTjoILbg", "libkernel", 1, "libkernel", 1, 1,
|
||||
ORBIS(posix_pthread_setschedparam));
|
||||
LIB_FUNCTION("How7B8Oet6k", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_getname_np));
|
||||
LIB_FUNCTION("3kg7rT0NQIs", "libkernel", 1, "libkernel", 1, 1, posix_pthread_exit);
|
||||
LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self);
|
||||
|
|
|
@ -111,15 +111,19 @@ public:
|
|||
BinarySemaphore sem;
|
||||
u32 priority;
|
||||
s32 need_count;
|
||||
std::string thr_name;
|
||||
bool was_signaled{};
|
||||
bool was_deleted{};
|
||||
bool was_cancled{};
|
||||
|
||||
explicit WaitingThread(s32 need_count, bool is_fifo) : sem{0}, need_count{need_count} {
|
||||
explicit WaitingThread(s32 need_count, bool is_fifo)
|
||||
: sem{0}, priority{0}, need_count{need_count} {
|
||||
// Retrieve calling thread priority for sorting into waiting threads list.
|
||||
if (!is_fifo) {
|
||||
priority = g_curthread->attr.prio;
|
||||
}
|
||||
|
||||
thr_name = g_curthread->name;
|
||||
}
|
||||
|
||||
int GetResult(bool timed_out) {
|
||||
|
@ -232,6 +236,7 @@ int PS4_SYSV_ABI sceKernelDeleteSema(OrbisKernelSema sem) {
|
|||
return ORBIS_KERNEL_ERROR_ESRCH;
|
||||
}
|
||||
sem->Delete();
|
||||
delete sem;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -246,6 +251,16 @@ int PS4_SYSV_ABI posix_sem_init(PthreadSem** sem, int pshared, u32 value) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_sem_destroy(PthreadSem** sem) {
|
||||
if (sem == nullptr || *sem == nullptr) {
|
||||
*__Error() = POSIX_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
delete *sem;
|
||||
*sem = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_sem_wait(PthreadSem** sem) {
|
||||
if (sem == nullptr || *sem == nullptr) {
|
||||
*__Error() = POSIX_EINVAL;
|
||||
|
@ -296,16 +311,6 @@ int PS4_SYSV_ABI posix_sem_post(PthreadSem** sem) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_sem_destroy(PthreadSem** sem) {
|
||||
if (sem == nullptr || *sem == nullptr) {
|
||||
*__Error() = POSIX_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
delete *sem;
|
||||
*sem = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_sem_getvalue(PthreadSem** sem, int* sval) {
|
||||
if (sem == nullptr || *sem == nullptr) {
|
||||
*__Error() = POSIX_EINVAL;
|
||||
|
@ -317,6 +322,77 @@ int PS4_SYSV_ABI posix_sem_getvalue(PthreadSem** sem, int* sval) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemInit(PthreadSem** sem, int flag, u32 value, const char* name) {
|
||||
if (flag != 0) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
s32 ret = posix_sem_init(sem, 0, value);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemDestroy(PthreadSem** sem) {
|
||||
s32 ret = posix_sem_destroy(sem);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemWait(PthreadSem** sem) {
|
||||
s32 ret = posix_sem_wait(sem);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemTrywait(PthreadSem** sem) {
|
||||
s32 ret = posix_sem_trywait(sem);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemTimedwait(PthreadSem** sem, u32 usec) {
|
||||
OrbisKernelTimespec time{};
|
||||
time.tv_sec = usec / 1000000;
|
||||
time.tv_nsec = (usec % 1000000) * 1000;
|
||||
|
||||
s32 ret = posix_sem_timedwait(sem, &time);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemPost(PthreadSem** sem) {
|
||||
s32 ret = posix_sem_post(sem);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemGetvalue(PthreadSem** sem, int* sval) {
|
||||
s32 ret = posix_sem_getvalue(sem, sval);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void RegisterSemaphore(Core::Loader::SymbolsResolver* sym) {
|
||||
// Orbis
|
||||
LIB_FUNCTION("188x57JYp0g", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateSema);
|
||||
|
@ -328,12 +404,20 @@ void RegisterSemaphore(Core::Loader::SymbolsResolver* sym) {
|
|||
|
||||
// Posix
|
||||
LIB_FUNCTION("pDuPEf3m4fI", "libScePosix", 1, "libkernel", 1, 1, posix_sem_init);
|
||||
LIB_FUNCTION("cDW233RAwWo", "libScePosix", 1, "libkernel", 1, 1, posix_sem_destroy);
|
||||
LIB_FUNCTION("YCV5dGGBcCo", "libScePosix", 1, "libkernel", 1, 1, posix_sem_wait);
|
||||
LIB_FUNCTION("WBWzsRifCEA", "libScePosix", 1, "libkernel", 1, 1, posix_sem_trywait);
|
||||
LIB_FUNCTION("w5IHyvahg-o", "libScePosix", 1, "libkernel", 1, 1, posix_sem_timedwait);
|
||||
LIB_FUNCTION("IKP8typ0QUk", "libScePosix", 1, "libkernel", 1, 1, posix_sem_post);
|
||||
LIB_FUNCTION("cDW233RAwWo", "libScePosix", 1, "libkernel", 1, 1, posix_sem_destroy);
|
||||
LIB_FUNCTION("Bq+LRV-N6Hk", "libScePosix", 1, "libkernel", 1, 1, posix_sem_getvalue);
|
||||
|
||||
LIB_FUNCTION("GEnUkDZoUwY", "libkernel", 1, "libkernel", 1, 1, scePthreadSemInit);
|
||||
LIB_FUNCTION("Vwc+L05e6oE", "libkernel", 1, "libkernel", 1, 1, scePthreadSemDestroy);
|
||||
LIB_FUNCTION("C36iRE0F5sE", "libkernel", 1, "libkernel", 1, 1, scePthreadSemWait);
|
||||
LIB_FUNCTION("H2a+IN9TP0E", "libkernel", 1, "libkernel", 1, 1, scePthreadSemTrywait);
|
||||
LIB_FUNCTION("fjN6NQHhK8k", "libkernel", 1, "libkernel", 1, 1, scePthreadSemTimedwait);
|
||||
LIB_FUNCTION("aishVAiFaYM", "libkernel", 1, "libkernel", 1, 1, scePthreadSemPost);
|
||||
LIB_FUNCTION("DjpBvGlaWbQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSemGetvalue);
|
||||
}
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
|
|
@ -79,7 +79,7 @@ static void backup(const std::filesystem::path& dir_name) {
|
|||
}
|
||||
|
||||
static void BackupThreadBody() {
|
||||
Common::SetCurrentThreadName("shadPS4:SaveData_BackupThread");
|
||||
Common::SetCurrentThreadName("shadPS4:SaveData:BackupThread");
|
||||
while (g_backup_status != WorkerStatus::Stopping) {
|
||||
g_backup_status = WorkerStatus::Waiting;
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ static void SaveFileSafe(void* buf, size_t count, const std::filesystem::path& p
|
|||
}
|
||||
|
||||
[[noreturn]] void SaveThreadLoop() {
|
||||
Common::SetCurrentThreadName("shadPS4:SaveData_SaveDataMemoryThread");
|
||||
Common::SetCurrentThreadName("shadPS4:SaveData:SaveDataMemoryThread");
|
||||
std::mutex mtx;
|
||||
while (true) {
|
||||
{
|
||||
|
|
|
@ -85,6 +85,15 @@ public:
|
|||
return m_modules.at(index).get();
|
||||
}
|
||||
|
||||
u32 FindByName(const std::filesystem::path& name) const {
|
||||
for (u32 i = 0; i < m_modules.size(); i++) {
|
||||
if (name == m_modules[i]->file) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
u32 MaxTlsIndex() const {
|
||||
return max_tls_index;
|
||||
}
|
||||
|
|
|
@ -375,12 +375,12 @@ void MemoryManager::PoolDecommit(VAddr virtual_addr, size_t size) {
|
|||
TRACK_FREE(virtual_addr, "VMEM");
|
||||
}
|
||||
|
||||
void MemoryManager::UnmapMemory(VAddr virtual_addr, size_t size) {
|
||||
s32 MemoryManager::UnmapMemory(VAddr virtual_addr, size_t size) {
|
||||
std::scoped_lock lk{mutex};
|
||||
UnmapMemoryImpl(virtual_addr, size);
|
||||
return UnmapMemoryImpl(virtual_addr, size);
|
||||
}
|
||||
|
||||
void MemoryManager::UnmapMemoryImpl(VAddr virtual_addr, size_t size) {
|
||||
s32 MemoryManager::UnmapMemoryImpl(VAddr virtual_addr, size_t size) {
|
||||
const auto it = FindVMA(virtual_addr);
|
||||
const auto& vma_base = it->second;
|
||||
ASSERT_MSG(vma_base.Contains(virtual_addr, size),
|
||||
|
@ -415,6 +415,8 @@ void MemoryManager::UnmapMemoryImpl(VAddr virtual_addr, size_t size) {
|
|||
impl.Unmap(vma_base_addr, vma_base_size, start_in_vma, start_in_vma + size, phys_base, is_exec,
|
||||
has_backing, readonly_file);
|
||||
TRACK_FREE(virtual_addr, "VMEM");
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int MemoryManager::QueryProtection(VAddr addr, void** start, void** end, u32* prot) {
|
||||
|
|
|
@ -192,7 +192,7 @@ public:
|
|||
|
||||
void PoolDecommit(VAddr virtual_addr, size_t size);
|
||||
|
||||
void UnmapMemory(VAddr virtual_addr, size_t size);
|
||||
s32 UnmapMemory(VAddr virtual_addr, size_t size);
|
||||
|
||||
int QueryProtection(VAddr addr, void** start, void** end, u32* prot);
|
||||
|
||||
|
@ -250,7 +250,7 @@ private:
|
|||
|
||||
DMemHandle Split(DMemHandle dmem_handle, size_t offset_in_area);
|
||||
|
||||
void UnmapMemoryImpl(VAddr virtual_addr, size_t size);
|
||||
s32 UnmapMemoryImpl(VAddr virtual_addr, size_t size);
|
||||
|
||||
private:
|
||||
AddressSpace impl;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "common/io_file.h"
|
||||
#include "common/polyfill_thread.h"
|
||||
#include "common/stb.h"
|
||||
#include "common/thread.h"
|
||||
#include "imgui_impl_vulkan.h"
|
||||
#include "texture_manager.h"
|
||||
|
||||
|
@ -81,6 +82,7 @@ RefCountedTexture::~RefCountedTexture() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
RefCountedTexture::Image RefCountedTexture::GetTexture() const {
|
||||
if (inner == nullptr) {
|
||||
return {};
|
||||
|
@ -91,6 +93,7 @@ RefCountedTexture::Image RefCountedTexture::GetTexture() const {
|
|||
.height = inner->height,
|
||||
};
|
||||
}
|
||||
|
||||
RefCountedTexture::operator bool() const {
|
||||
return inner != nullptr && inner->texture_id != nullptr;
|
||||
}
|
||||
|
@ -130,6 +133,7 @@ Inner::~Inner() {
|
|||
}
|
||||
|
||||
void WorkerLoop() {
|
||||
Common::SetCurrentThreadName("shadPS4:ImGuiTextureManager");
|
||||
std::mutex mtx;
|
||||
while (g_is_worker_running) {
|
||||
std::unique_lock lk{mtx};
|
||||
|
|
Loading…
Reference in a new issue