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

This commit is contained in:
Daniel R. 2024-12-08 17:30:33 +01:00 committed by GitHub
parent 1793fd4df0
commit fea2593ab4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 256 additions and 50 deletions

View file

@ -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

View file

@ -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();

View file

@ -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) {

View file

@ -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

View file

@ -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) {

View file

@ -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.

View file

@ -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) -

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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) {
{

View file

@ -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;
}

View file

@ -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) {

View file

@ -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;

View file

@ -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};