From df119b8a5b7db6cdc877963da7b42607248a7dd5 Mon Sep 17 00:00:00 2001 From: Daniel R <47796739+polybiusproxy@users.noreply.github.com> Date: Sun, 8 Dec 2024 17:30:33 +0100 Subject: [PATCH] The way to Unity, pt.3 (#1681) --- src/common/ntapi.cpp | 2 + src/common/ntapi.h | 20 ++++ src/core/libraries/ajm/ajm_context.cpp | 2 + src/core/libraries/kernel/kernel.cpp | 3 +- src/core/libraries/kernel/memory.cpp | 3 +- src/core/libraries/kernel/process.cpp | 15 ++- src/core/libraries/kernel/sync/semaphore.h | 42 ++++--- .../libraries/kernel/threads/event_flag.cpp | 30 ++++- .../libraries/kernel/threads/exception.cpp | 50 ++++++-- src/core/libraries/kernel/threads/pthread.cpp | 2 + .../libraries/kernel/threads/semaphore.cpp | 108 ++++++++++++++++-- src/core/libraries/save_data/save_backup.cpp | 2 +- src/core/libraries/save_data/save_memory.cpp | 2 +- src/core/linker.h | 9 ++ src/core/memory.cpp | 8 +- src/core/memory.h | 4 +- src/imgui/renderer/texture_manager.cpp | 4 + 17 files changed, 256 insertions(+), 50 deletions(-) diff --git a/src/common/ntapi.cpp b/src/common/ntapi.cpp index e0ff1cef0d..c76c4657ef 100644 --- a/src/common/ntapi.cpp +++ b/src/common/ntapi.cpp @@ -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 diff --git a/src/common/ntapi.h b/src/common/ntapi.h index cb1ba7f1cd..daab8440d5 100644 --- a/src/common/ntapi.h +++ b/src/common/ntapi.h @@ -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(); diff --git a/src/core/libraries/ajm/ajm_context.cpp b/src/core/libraries/ajm/ajm_context.cpp index e30e1c4782..09255110c1 100644 --- a/src/core/libraries/ajm/ajm_context.cpp +++ b/src/core/libraries/ajm/ajm_context.cpp @@ -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) { diff --git a/src/core/libraries/kernel/kernel.cpp b/src/core/libraries/kernel/kernel.cpp index 0b4e89fc7a..bda4462578 100644 --- a/src/core/libraries/kernel/kernel.cpp +++ b/src/core/libraries/kernel/kernel.cpp @@ -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 diff --git a/src/core/libraries/kernel/memory.cpp b/src/core/libraries/kernel/memory.cpp index 606c5c1859..7d326cbbfd 100644 --- a/src/core/libraries/kernel/memory.cpp +++ b/src/core/libraries/kernel/memory.cpp @@ -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(addr), len); - return ORBIS_OK; + return memory->UnmapMemory(std::bit_cast(addr), len); } int PS4_SYSV_ABI posix_munmap(void* addr, size_t len) { diff --git a/src/core/libraries/kernel/process.cpp b/src/core/libraries/kernel/process.cpp index a657ddf981..6c29d93050 100644 --- a/src/core/libraries/kernel/process.cpp +++ b/src/core/libraries/kernel/process.cpp @@ -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::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(); 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::Instance(); auto* module = linker->FindByAddress(addr); + if (!module) { + return ORBIS_KERNEL_ERROR_EFAULT; + } const auto mod_info = module->GetModuleInfoEx(); // Fill in module info. diff --git a/src/core/libraries/kernel/sync/semaphore.h b/src/core/libraries/kernel/sync/semaphore.h index 884b089688..48a5dc0d8a 100644 --- a/src/core/libraries/kernel/sync/semaphore.h +++ b/src/core/libraries/kernel/sync/semaphore.h @@ -87,14 +87,23 @@ class Semaphore { template bool try_acquire_for(const std::chrono::duration& rel_time) { #ifdef _WIN64 - const auto rel_time_ms = std::chrono::ceil(rel_time); - const u64 timeout_ms = static_cast(rel_time_ms.count()); + const auto start_time = std::chrono::high_resolution_clock::now(); + auto rel_time_ms = std::chrono::ceil(rel_time); - if (timeout_ms == 0) { - return false; + while (rel_time_ms.count() > 0) { + u64 timeout_ms = static_cast(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(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(rel_time).count(); const auto timeout = dispatch_time(DISPATCH_TIME_NOW, rel_time_ns); @@ -107,19 +116,26 @@ class Semaphore { template bool try_acquire_until(const std::chrono::time_point& 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(abs_time - now); - const u64 timeout_ms = static_cast(rel_time.count()); - if (timeout_ms == 0) { - return false; + auto rel_time = std::chrono::ceil(abs_time - start_time); + while (rel_time.count() > 0) { + u64 timeout_ms = static_cast(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(elapsed_time); + } else { + return false; + } } - u64 res = WaitForSingleObjectEx(sem, static_cast(timeout_ms), true); - return res == WAIT_OBJECT_0; + return false; #elif defined(__APPLE__) auto abs_s = std::chrono::time_point_cast(abs_time); auto abs_ns = std::chrono::time_point_cast(abs_time) - diff --git a/src/core/libraries/kernel/threads/event_flag.cpp b/src/core/libraries/kernel/threads/event_flag.cpp index ce75bed9ef..24ddcb9277 100644 --- a/src/core/libraries/kernel/threads/event_flag.cpp +++ b/src/core/libraries/kernel/threads/event_flag.cpp @@ -132,6 +132,33 @@ class EventFlagInternal { 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; } diff --git a/src/core/libraries/kernel/threads/exception.cpp b/src/core/libraries/kernel/threads/exception.cpp index b6d89aae4c..017984e0d3 100644 --- a/src/core/libraries/kernel/threads/exception.cpp +++ b/src/core/libraries/kernel/threads/exception.cpp @@ -7,6 +7,7 @@ #include "core/libraries/libs.h" #ifdef _WIN64 +#include "common/ntapi.h" #else #include #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(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(thread->native_thr.GetHandle()); pthread_kill(pthr, SIGUSR2); +#else + USER_APC_OPTION option; + option.UserApcFlags = QueueUserApcFlagsSpecialUserApc; + + u64 res = NtQueueApcThreadEx(reinterpret_cast(thread->native_thr.GetHandle()), option, + ExceptionHandler, (void*)thread->name.c_str(), nullptr, nullptr); + ASSERT(res == 0); #endif return 0; } diff --git a/src/core/libraries/kernel/threads/pthread.cpp b/src/core/libraries/kernel/threads/pthread.cpp index b2fe099342..c83af86d0e 100644 --- a/src/core/libraries/kernel/threads/pthread.cpp +++ b/src/core/libraries/kernel/threads/pthread.cpp @@ -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); diff --git a/src/core/libraries/kernel/threads/semaphore.cpp b/src/core/libraries/kernel/threads/semaphore.cpp index 5aa04f251f..39c1a0233d 100644 --- a/src/core/libraries/kernel/threads/semaphore.cpp +++ b/src/core/libraries/kernel/threads/semaphore.cpp @@ -111,15 +111,19 @@ class OrbisSem { 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 diff --git a/src/core/libraries/save_data/save_backup.cpp b/src/core/libraries/save_data/save_backup.cpp index 3f7969d696..5261cdb11f 100644 --- a/src/core/libraries/save_data/save_backup.cpp +++ b/src/core/libraries/save_data/save_backup.cpp @@ -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; diff --git a/src/core/libraries/save_data/save_memory.cpp b/src/core/libraries/save_data/save_memory.cpp index e9ef53761d..84179bc27d 100644 --- a/src/core/libraries/save_data/save_memory.cpp +++ b/src/core/libraries/save_data/save_memory.cpp @@ -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) { { diff --git a/src/core/linker.h b/src/core/linker.h index 3a1aeb9608..d6b5d648ae 100644 --- a/src/core/linker.h +++ b/src/core/linker.h @@ -85,6 +85,15 @@ class Linker { 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; } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 3e1cd441f0..82e4b7ad3e 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -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) { diff --git a/src/core/memory.h b/src/core/memory.h index 2efa027630..364609451f 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -192,7 +192,7 @@ class MemoryManager { 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 @@ class MemoryManager { 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; diff --git a/src/imgui/renderer/texture_manager.cpp b/src/imgui/renderer/texture_manager.cpp index dd233ee60a..f13c995be1 100644 --- a/src/imgui/renderer/texture_manager.cpp +++ b/src/imgui/renderer/texture_manager.cpp @@ -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};