diff --git a/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp b/Utilities/SleepQueue.cpp similarity index 89% rename from rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp rename to Utilities/SleepQueue.cpp index c622bdc54d..f7a991fb06 100644 --- a/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp +++ b/Utilities/SleepQueue.cpp @@ -1,10 +1,7 @@ #include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" -#include "Emu/System.h" - #include "Emu/CPU/CPUThread.h" -#include "sleep_queue.h" + +#include "SleepQueue.h" void sleep_queue_entry_t::add_entry() { diff --git a/rpcs3/Emu/SysCalls/lv2/sleep_queue.h b/Utilities/SleepQueue.h similarity index 52% rename from rpcs3/Emu/SysCalls/lv2/sleep_queue.h rename to Utilities/SleepQueue.h index 59d6a68d2f..e468b3823e 100644 --- a/rpcs3/Emu/SysCalls/lv2/sleep_queue.h +++ b/Utilities/SleepQueue.h @@ -1,49 +1,10 @@ #pragma once -namespace vm { using namespace ps3; } - -// attr_protocol (waiting scheduling policy) -enum -{ - // First In, First Out - SYS_SYNC_FIFO = 1, - // Priority Order - SYS_SYNC_PRIORITY = 2, - // Basic Priority Inheritance Protocol (probably not implemented) - SYS_SYNC_PRIORITY_INHERIT = 3, - // Not selected while unlocking - SYS_SYNC_RETRY = 4, - // - SYS_SYNC_ATTR_PROTOCOL_MASK = 0xF, -}; - -// attr_recursive (recursive locks policy) -enum -{ - // Recursive locks are allowed - SYS_SYNC_RECURSIVE = 0x10, - // Recursive locks are NOT allowed - SYS_SYNC_NOT_RECURSIVE = 0x20, - // - SYS_SYNC_ATTR_RECURSIVE_MASK = 0xF0, //??? -}; - -// attr_pshared -enum -{ - SYS_SYNC_NOT_PROCESS_SHARED = 0x200, -}; - -// attr_adaptive -enum -{ - SYS_SYNC_ADAPTIVE = 0x1000, - SYS_SYNC_NOT_ADAPTIVE = 0x2000, -}; +class CPUThread; using sleep_queue_t = std::deque>; -static struct defer_sleep_t{} const defer_sleep{}; +static struct defer_sleep_t {} const defer_sleep{}; // automatic object handling a thread entry in the sleep queue class sleep_queue_entry_t final diff --git a/rpcs3/Emu/ARMv7/ARMv7Callback.h b/rpcs3/Emu/ARMv7/ARMv7Callback.h index d9e42f3d36..a1ddd72593 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Callback.h +++ b/rpcs3/Emu/ARMv7/ARMv7Callback.h @@ -5,13 +5,13 @@ namespace vm { template - force_inline RT _ptr_base::operator()(ARMv7Context& context, T... args) const + force_inline RT _ptr_base::operator()(ARMv7Thread& context, T... args) const { return psv_func_detail::func_caller::call(context, VM_CAST(this->addr()), args...); } } -template inline RT cb_call(ARMv7Context& context, u32 addr, T... args) +template inline RT cb_call(ARMv7Thread& context, u32 addr, T... args) { return psv_func_detail::func_caller::call(context, addr, args...); } diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp index 48612562ec..eca7bb67cd 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp @@ -541,7 +541,7 @@ void ARMv7_instrs::HACK(ARMv7Context& context, const ARMv7Code code, const ARMv7 if (ConditionPassed(context, cond)) { - execute_psv_func_by_index(context, index); + execute_psv_func_by_index(static_cast(context), index); } } diff --git a/rpcs3/Emu/ARMv7/Modules/psv_cond.cpp b/rpcs3/Emu/ARMv7/Modules/psv_cond.cpp deleted file mode 100644 index c89511b19d..0000000000 --- a/rpcs3/Emu/ARMv7/Modules/psv_cond.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/ARMv7/PSVFuncList.h" -#include "Emu/ARMv7/PSVObjectList.h" -#include "sceLibKernel.h" -#include "psv_cond.h" - -psv_cond_t::psv_cond_t(const char* name, u32 attr, s32 mutexId) - : attr(attr) - , mutexId(mutexId) -{ - strcpy_trunc(this->name, name); -} diff --git a/rpcs3/Emu/ARMv7/Modules/psv_cond.h b/rpcs3/Emu/ARMv7/Modules/psv_cond.h deleted file mode 100644 index 812b307695..0000000000 --- a/rpcs3/Emu/ARMv7/Modules/psv_cond.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct psv_cond_t -{ - char name[32]; - u32 attr; - s32 mutexId; - -public: - psv_cond_t(const char* name, u32 attr, s32 mutexId); -}; - -typedef psv_object_list_t psv_cond_list_t; - -extern psv_cond_list_t g_psv_cond_list; diff --git a/rpcs3/Emu/ARMv7/Modules/psv_event_flag.cpp b/rpcs3/Emu/ARMv7/Modules/psv_event_flag.cpp deleted file mode 100644 index 14c9af11bc..0000000000 --- a/rpcs3/Emu/ARMv7/Modules/psv_event_flag.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/ARMv7/PSVFuncList.h" -#include "Emu/ARMv7/PSVObjectList.h" -#include "sceLibKernel.h" -#include "psv_event_flag.h" - -psv_event_flag_t::psv_event_flag_t(const char* name, u32 attr, u32 pattern) - : attr(attr) - , pattern(pattern) -{ - strcpy_trunc(this->name, name); -} diff --git a/rpcs3/Emu/ARMv7/Modules/psv_event_flag.h b/rpcs3/Emu/ARMv7/Modules/psv_event_flag.h deleted file mode 100644 index 79a3f2ec86..0000000000 --- a/rpcs3/Emu/ARMv7/Modules/psv_event_flag.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct psv_event_flag_t -{ - char name[32]; - u32 attr; - u32 pattern; - -public: - psv_event_flag_t(const char* name, u32 attr, u32 pattern); -}; - -typedef psv_object_list_t psv_ef_list_t; - -extern psv_ef_list_t g_psv_ef_list; diff --git a/rpcs3/Emu/ARMv7/Modules/psv_mutex.cpp b/rpcs3/Emu/ARMv7/Modules/psv_mutex.cpp deleted file mode 100644 index 7733ad54ea..0000000000 --- a/rpcs3/Emu/ARMv7/Modules/psv_mutex.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/ARMv7/PSVFuncList.h" -#include "Emu/ARMv7/PSVObjectList.h" -#include "sceLibKernel.h" -#include "psv_mutex.h" - -psv_mutex_t::psv_mutex_t(const char* name, u32 attr, s32 count) - : attr(attr) - , count(count) -{ - strcpy_trunc(this->name, name); -} diff --git a/rpcs3/Emu/ARMv7/Modules/psv_mutex.h b/rpcs3/Emu/ARMv7/Modules/psv_mutex.h deleted file mode 100644 index 824c0ff96e..0000000000 --- a/rpcs3/Emu/ARMv7/Modules/psv_mutex.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct psv_mutex_t -{ - char name[32]; - u32 attr; - s32 count; - -public: - psv_mutex_t(const char* name, u32 attr, s32 count); -}; - -typedef psv_object_list_t psv_mutex_list_t; - -extern psv_mutex_list_t g_psv_mutex_list; diff --git a/rpcs3/Emu/ARMv7/Modules/psv_sema.cpp b/rpcs3/Emu/ARMv7/Modules/psv_sema.cpp deleted file mode 100644 index 20527eb5b3..0000000000 --- a/rpcs3/Emu/ARMv7/Modules/psv_sema.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/ARMv7/PSVFuncList.h" -#include "Emu/ARMv7/PSVObjectList.h" -#include "sceLibKernel.h" -#include "psv_sema.h" - -psv_sema_t::psv_sema_t(const char* name, u32 attr, s32 init_value, s32 max_value) - : attr(attr) - , value(init_value) - , max(max_value) -{ - strcpy_trunc(this->name, name); -} diff --git a/rpcs3/Emu/ARMv7/Modules/psv_sema.h b/rpcs3/Emu/ARMv7/Modules/psv_sema.h deleted file mode 100644 index c4c6715ea2..0000000000 --- a/rpcs3/Emu/ARMv7/Modules/psv_sema.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -struct psv_sema_t -{ - char name[32]; - u32 attr; - s32 value; - s32 max; - -public: - psv_sema_t(const char* name, u32 attr, s32 init_value, s32 max_value); -}; - -typedef psv_object_list_t psv_sema_list_t; - -extern psv_sema_list_t g_psv_sema_list; diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp index e9123a650f..de3618d275 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp @@ -8,10 +8,8 @@ #include "Emu/ARMv7/ARMv7Thread.h" #include "sceLibKernel.h" -#include "psv_sema.h" -#include "psv_event_flag.h" -#include "psv_mutex.h" -#include "psv_cond.h" + +extern u64 get_system_time(); s32 sceKernelAllocMemBlock(vm::cptr name, s32 type, u32 vsize, vm::ptr pOpt) { @@ -85,12 +83,12 @@ s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::cptr pArgBlock) return SCE_OK; } -s32 sceKernelExitThread(ARMv7Context& context, s32 exitStatus) +s32 sceKernelExitThread(ARMv7Thread& context, s32 exitStatus) { sceLibKernel.Warning("sceKernelExitThread(exitStatus=0x%x)", exitStatus); // exit status is stored in r0 - static_cast(context).exit(); + context.exit(); return SCE_OK; } @@ -117,15 +115,15 @@ s32 sceKernelDeleteThread(s32 threadId) return SCE_OK; } -s32 sceKernelExitDeleteThread(ARMv7Context& context, s32 exitStatus) +s32 sceKernelExitDeleteThread(ARMv7Thread& context, s32 exitStatus) { sceLibKernel.Warning("sceKernelExitDeleteThread(exitStatus=0x%x)", exitStatus); // exit status is stored in r0 - static_cast(context).stop(); + context.stop(); // current thread should be deleted - const u32 id = static_cast(context).get_id(); + const u32 id = context.get_id(); CallAfter([id]() { @@ -163,11 +161,11 @@ s32 sceKernelGetThreadCurrentPriority() throw EXCEPTION(""); } -u32 sceKernelGetThreadId(ARMv7Context& context) +u32 sceKernelGetThreadId(ARMv7Thread& context) { sceLibKernel.Log("sceKernelGetThreadId()"); - return static_cast(context).get_id(); + return context.get_id(); } s32 sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr) @@ -386,62 +384,275 @@ s32 sceKernelCreateEventFlag(vm::cptr pName, u32 attr, u32 initPattern, vm { sceLibKernel.Error("sceKernelCreateEventFlag(pName=*0x%x, attr=0x%x, initPattern=0x%x, pOptParam=*0x%x)", pName, attr, initPattern, pOptParam); - if (s32 id = g_psv_ef_list.create(pName.get_ptr(), attr, initPattern)) - { - return id; - } - - return SCE_KERNEL_ERROR_ERROR; + return idm::make(pName.get_ptr(), attr, initPattern); } s32 sceKernelDeleteEventFlag(s32 evfId) { - throw EXCEPTION(""); + sceLibKernel.Error("sceKernelDeleteEventFlag(evfId=0x%x)", evfId); + + const auto evf = idm::withdraw(evfId); + + if (!evf) + { + return SCE_KERNEL_ERROR_INVALID_UID; + } + + // Unregister IPC name + if (evf->ref.atomic_op(ipc_ref_try_unregister)) + { + evf->destroy(); + } + + return SCE_OK; } s32 sceKernelOpenEventFlag(vm::cptr pName) { - throw EXCEPTION(""); + sceLibKernel.Error("sceKernelOpenEventFlag(pName=*0x%x)", pName); + + // For now, go through all objects to find the name + for (const auto& data : idm::get_map()) + { + const auto& evf = data.second; + + if (evf->name == pName.get_ptr() && evf->ref.atomic_op(ipc_ref_try_inc)) + { + return idm::import(evf); + } + } + + return SCE_KERNEL_ERROR_UID_CANNOT_FIND_BY_NAME; } s32 sceKernelCloseEventFlag(s32 evfId) { - throw EXCEPTION(""); + sceLibKernel.Error("sceKernelCloseEventFlag(evfId=0x%x)", evfId); + + const auto evf = idm::withdraw(evfId); + + if (!evf) + { + return SCE_KERNEL_ERROR_INVALID_UID; + } + + // Decrement IPC ref + if (evf->ref.atomic_op(ipc_ref_try_dec)) + { + evf->destroy(); + } + + return SCE_OK; } -s32 sceKernelWaitEventFlag(s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr pResultPat, vm::ptr pTimeout) +s32 sceKernelWaitEventFlag(ARMv7Thread& context, s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr pResultPat, vm::ptr pTimeout) { - throw EXCEPTION(""); + sceLibKernel.Error("sceKernelWaitEventFlag(evfId=0x%x, bitPattern=0x%x, waitMode=0x%x, pResultPat=*0x%x, pTimeout=*0x%x)", evfId, bitPattern, waitMode, pResultPat, pTimeout); + + const u64 start_time = pTimeout ? get_system_time() : 0; + const u32 timeout = pTimeout ? pTimeout->value() : 0; + + const auto evf = idm::get(evfId); + + if (!evf) + { + return SCE_KERNEL_ERROR_INVALID_UID; + } + + std::unique_lock lock(evf->mutex); + + const u32 result = evf->pattern.atomic_op(event_flag_try_poll, bitPattern, waitMode); + + if (event_flag_test(result, bitPattern, waitMode)) + { + if (pResultPat) *pResultPat = result; + + return SCE_OK; + } + + // fixup register values for external use + context.GPR[1] = bitPattern; + context.GPR[2] = waitMode; + + // add waiter; attributes are ignored in current implementation + sleep_queue_entry_t waiter(context, evf->sq); + + while (!context.unsignal()) + { + CHECK_EMU_STATUS; + + if (pTimeout) + { + const u64 passed = get_system_time() - start_time; + + if (passed >= timeout) + { + context.GPR[0] = SCE_KERNEL_ERROR_WAIT_TIMEOUT; + context.GPR[1] = evf->pattern.load(); + break; + } + + context.cv.wait_for(lock, std::chrono::microseconds(timeout - passed)); + } + else + { + context.cv.wait(lock); + } + } + + if (pResultPat) *pResultPat = context.GPR[1]; + if (pTimeout) *pTimeout = static_cast(std::max(0, timeout - (get_system_time() - start_time))); + + return context.GPR[0]; } -s32 sceKernelWaitEventFlagCB(s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr pResultPat, vm::ptr pTimeout) +s32 sceKernelWaitEventFlagCB(ARMv7Thread& context, s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr pResultPat, vm::ptr pTimeout) { - throw EXCEPTION(""); + sceLibKernel.Todo("sceKernelWaitEventFlagCB(evfId=0x%x, bitPattern=0x%x, waitMode=0x%x, pResultPat=*0x%x, pTimeout=*0x%x)", evfId, bitPattern, waitMode, pResultPat, pTimeout); + + return sceKernelWaitEventFlag(context, evfId, bitPattern, waitMode, pResultPat, pTimeout); } s32 sceKernelPollEventFlag(s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr pResultPat) { - throw EXCEPTION(""); + sceLibKernel.Error("sceKernelPollEventFlag(evfId=0x%x, bitPattern=0x%x, waitMode=0x%x, pResultPat=*0x%x)", evfId, bitPattern, waitMode, pResultPat); + + const auto evf = idm::get(evfId); + + if (!evf) + { + return SCE_KERNEL_ERROR_INVALID_UID; + } + + std::lock_guard lock(evf->mutex); + + const u32 result = evf->pattern.atomic_op(event_flag_try_poll, bitPattern, waitMode); + + if (!event_flag_test(result, bitPattern, waitMode)) + { + return SCE_KERNEL_ERROR_EVENT_COND; + } + + *pResultPat = result; + + return SCE_OK; } s32 sceKernelSetEventFlag(s32 evfId, u32 bitPattern) { - throw EXCEPTION(""); + sceLibKernel.Error("sceKernelSetEventFlag(evfId=0x%x, bitPattern=0x%x)", evfId, bitPattern); + + const auto evf = idm::get(evfId); + + if (!evf) + { + return SCE_KERNEL_ERROR_INVALID_UID; + } + + std::lock_guard lock(evf->mutex); + + evf->pattern |= bitPattern; + + auto pred = [&](sleep_queue_t::value_type& thread) -> bool + { + auto& context = static_cast(*thread); + + // load pattern and mode from registers + const u32 pattern = context.GPR[1]; + const u32 mode = context.GPR[2]; + + // check specific pattern + const u32 result = evf->pattern.atomic_op(event_flag_try_poll, pattern, mode); + + if (event_flag_test(result, pattern, mode)) + { + // save pattern + context.GPR[0] = SCE_OK; + context.GPR[1] = result; + + context.signal(); + return true; + } + + return false; + }; + + // check all waiters; protocol is ignored in current implementation + evf->sq.erase(std::remove_if(evf->sq.begin(), evf->sq.end(), pred), evf->sq.end()); + + return SCE_OK; } s32 sceKernelClearEventFlag(s32 evfId, u32 bitPattern) { - throw EXCEPTION(""); + sceLibKernel.Error("sceKernelClearEventFlag(evfId=0x%x, bitPattern=0x%x)", evfId, bitPattern); + + const auto evf = idm::get(evfId); + + if (!evf) + { + return SCE_KERNEL_ERROR_INVALID_UID; + } + + std::lock_guard lock(evf->mutex); + + evf->pattern &= ~bitPattern; + + return SCE_OK; } s32 sceKernelCancelEventFlag(s32 evfId, u32 setPattern, vm::ptr pNumWaitThreads) { - throw EXCEPTION(""); + sceLibKernel.Error("sceKernelCancelEventFlag(evfId=0x%x, setPattern=0x%x, pNumWaitThreads=*0x%x)", evfId, setPattern, pNumWaitThreads); + + const auto evf = idm::get(evfId); + + if (!evf) + { + return SCE_KERNEL_ERROR_INVALID_UID; + } + + std::lock_guard lock(evf->mutex); + + for (auto& thread : evf->sq) + { + static_cast(*thread).GPR[0] = SCE_KERNEL_ERROR_WAIT_CANCEL; + static_cast(*thread).GPR[1] = setPattern; + thread->signal(); + } + + *pNumWaitThreads = static_cast(evf->sq.size()); + + evf->pattern.store(setPattern); + evf->sq.clear(); + + return SCE_OK; } s32 sceKernelGetEventFlagInfo(s32 evfId, vm::ptr pInfo) { - throw EXCEPTION(""); + sceLibKernel.Error("sceKernelGetEventFlagInfo(evfId=0x%x, pInfo=*0x%x)", evfId, pInfo); + + const auto evf = idm::get(evfId); + + if (!evf) + { + return SCE_KERNEL_ERROR_INVALID_UID; + } + + std::lock_guard lock(evf->mutex); + + pInfo->size = sizeof32(SceKernelEventFlagInfo); + pInfo->evfId = evfId; + + strcpy_trunc(pInfo->name, evf->name); + + pInfo->attr = evf->attr; + pInfo->initPattern = evf->init; + pInfo->currentPattern = evf->pattern.load(); + pInfo->numWaitThreads = static_cast(evf->sq.size()); + + return SCE_OK; } // Semaphore functions @@ -450,29 +661,21 @@ s32 sceKernelCreateSema(vm::cptr pName, u32 attr, s32 initCount, s32 maxCo { sceLibKernel.Error("sceKernelCreateSema(pName=*0x%x, attr=0x%x, initCount=%d, maxCount=%d, pOptParam=*0x%x)", pName, attr, initCount, maxCount, pOptParam); - if (s32 id = g_psv_sema_list.create(pName.get_ptr(), attr, initCount, maxCount)) - { - return id; - } - - return SCE_KERNEL_ERROR_ERROR; + return idm::make(pName.get_ptr(), attr, initCount, maxCount); } s32 sceKernelDeleteSema(s32 semaId) { sceLibKernel.Error("sceKernelDeleteSema(semaId=0x%x)", semaId); - const auto sema = g_psv_sema_list.get(semaId); + const auto sema = idm::withdraw(semaId); if (!sema) { return SCE_KERNEL_ERROR_INVALID_UID; } - if (!g_psv_sema_list.remove(semaId)) - { - return SCE_KERNEL_ERROR_INVALID_UID; - } + // ... return SCE_OK; } @@ -491,7 +694,7 @@ s32 sceKernelWaitSema(s32 semaId, s32 needCount, vm::ptr pTimeout) { sceLibKernel.Error("sceKernelWaitSema(semaId=0x%x, needCount=%d, pTimeout=*0x%x)", semaId, needCount, pTimeout); - const auto sema = g_psv_sema_list.get(semaId); + const auto sema = idm::get(semaId); if (!sema) { @@ -534,17 +737,23 @@ s32 sceKernelCreateMutex(vm::cptr pName, u32 attr, s32 initCount, vm::cptr { sceLibKernel.Error("sceKernelCreateMutex(pName=*0x%x, attr=0x%x, initCount=%d, pOptParam=*0x%x)", pName, attr, initCount, pOptParam); - if (s32 id = g_psv_mutex_list.create(pName.get_ptr(), attr, initCount)) - { - return id; - } - - return SCE_KERNEL_ERROR_ERROR; + return idm::make(pName.get_ptr(), attr, initCount); } s32 sceKernelDeleteMutex(s32 mutexId) { - throw EXCEPTION(""); + sceLibKernel.Error("sceKernelDeleteMutex(mutexId=0x%x)", mutexId); + + const auto mutex = idm::withdraw(mutexId); + + if (!mutex) + { + return SCE_KERNEL_ERROR_INVALID_UID; + } + + // ... + + return SCE_OK; } s32 sceKernelOpenMutex(vm::cptr pName) @@ -635,17 +844,30 @@ s32 sceKernelCreateCond(vm::cptr pName, u32 attr, s32 mutexId, vm::cptr(mutexId); + + if (!mutex) { - return id; + return SCE_KERNEL_ERROR_INVALID_UID; } - return SCE_KERNEL_ERROR_ERROR; + return idm::make(pName.get_ptr(), attr, mutex); } s32 sceKernelDeleteCond(s32 condId) { - throw EXCEPTION(""); + sceLibKernel.Error("sceKernelDeleteCond(condId=0x%x)", condId); + + const auto cond = idm::withdraw(condId); + + if (!cond) + { + return SCE_KERNEL_ERROR_INVALID_UID; + } + + // ... + + return SCE_OK; } s32 sceKernelOpenCond(vm::cptr pName) diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.h b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.h index 5b77b2c239..05e7968852 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.h +++ b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.h @@ -1,5 +1,7 @@ #pragma once +#include "Utilities/SleepQueue.h" + // Error Codes enum @@ -419,6 +421,14 @@ struct SceKernelResultEvent // Thread Manager definitions (event flags) +enum : u32 +{ + SCE_KERNEL_EVF_WAITMODE_AND = 0x00000000, + SCE_KERNEL_EVF_WAITMODE_OR = 0x00000001, + SCE_KERNEL_EVF_WAITMODE_CLEAR_ALL = 0x00000002, + SCE_KERNEL_EVF_WAITMODE_CLEAR_PAT = 0x00000004, +}; + struct SceKernelEventFlagOptParam { le_t size; @@ -435,6 +445,77 @@ struct SceKernelEventFlagInfo le_t numWaitThreads; }; +struct psv_event_flag_t +{ + const std::string name; // IPC Name + + atomic_t ref{ 0x80000000 }; // IPC Ref Counter + + const u32 attr; // Event Flag Attributes + const u32 init; // Event Flag Init Pattern + + atomic_t pattern; // Event Flag Pattern + + std::mutex mutex; + + sleep_queue_t sq; + + psv_event_flag_t(const char* name, u32 attr, u32 pattern) + : name(name) + , attr(attr) + , init(pattern) + { + this->pattern.store(pattern); + } + + // Wakeup all waiters to return SCE_KERNEL_ERROR_WAIT_DELETE + void destroy() + { + std::lock_guard lock(mutex); + + const u32 pattern = this->pattern.load(); + + for (auto& thread : sq) + { + static_cast(*thread).GPR[0] = SCE_KERNEL_ERROR_WAIT_DELETE; + static_cast(*thread).GPR[1] = pattern; + thread->signal(); + } + } +}; + +inline bool event_flag_test(u32 value, u32 pattern, u32 mode) +{ + if (mode & SCE_KERNEL_EVF_WAITMODE_OR) + { + return (value & pattern) != 0; + } + else + { + return (value & pattern) == pattern; + } +} + +inline void event_flag_try_poll(u32& value, u32 pattern, u32 mode) +{ + if (mode & ~7 || (mode & 6) == 6) + { + throw EXCEPTION("Unknown mode (0x%x)", mode); + } + + if (event_flag_test(value, pattern, mode)) + { + if (mode & SCE_KERNEL_EVF_WAITMODE_CLEAR_ALL) + { + value = 0; + } + else if (mode & SCE_KERNEL_EVF_WAITMODE_CLEAR_PAT) + { + value &= ~pattern; + } + } +} + // Thread Manager definitions (semaphores) struct SceKernelSemaOptParam @@ -454,6 +535,26 @@ struct SceKernelSemaInfo le_t numWaitThreads; }; +struct psv_semaphore_t +{ + const std::string name; // IPC Name + + atomic_t ref{ 0x80000000 }; // IPC Ref Counter + + const u32 attr; + const s32 max; + + atomic_t count; + + psv_semaphore_t(const char* name, u32 attr, s32 count, s32 max) + : name(name) + , attr(attr) + , max(max) + { + this->count.store(count); + } +}; + // Thread Manager definitions (mutexes) struct SceKernelMutexOptParam @@ -474,6 +575,24 @@ struct SceKernelMutexInfo le_t numWaitThreads; }; +struct psv_mutex_t +{ + const std::string name; // IPC Name + + atomic_t ref{ 0x80000000 }; // IPC Ref Counter + + const u32 attr; + + atomic_t count; + + psv_mutex_t(const char* name, u32 attr, s32 count) + : name(name) + , attr(attr) + { + this->count.store(count); + } +}; + // Thread Manager definitions (lightweight mutexes) struct SceKernelLwMutexWork @@ -516,6 +635,24 @@ struct SceKernelCondInfo le_t numWaitThreads; }; +struct psv_cond_t +{ + const std::string name; // IPC Name + + atomic_t ref{ 0x80000000 }; // IPC Ref Counter + + const u32 attr; + + const std::shared_ptr mutex; + + psv_cond_t(const char* name, u32 attr, const std::shared_ptr& mutex) + : name(name) + , attr(attr) + , mutex(mutex) + { + } +}; + // Thread Manager definitions (lightweight condition variables) struct SceKernelLwCondWork @@ -604,5 +741,47 @@ struct SceIoDirent }; // Module - extern psv_log_base sceLibKernel; + +// Aux + +inline bool ipc_ref_try_dec(u32& ref) +{ + if (ref & 0x7fffffff) + { + // return true if the last reference is removed and object must be deleted + return !--ref; + } + else + { + throw EXCEPTION("Unexpected IPC Ref value (0x%x)", ref); + } +} + +inline bool ipc_ref_try_inc(u32& ref) +{ + if (ref & 0x80000000) + { + if (!++ref) + { + throw EXCEPTION("IPC Ref overflow"); + } + + return true; + } + + return false; +} + +inline bool ipc_ref_try_unregister(u32& ref) +{ + if (ref & 0x80000000) + { + ref &= ~0x80000000; + + // return true if object must be deleted + return !ref; + } + + throw EXCEPTION("Unexpected IPC Ref value (0x%x)", ref); +} diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp index 5bc3ddfabf..274824bba4 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp @@ -9,7 +9,7 @@ vm::ptr g_dso; -std::vector> g_atexit; +std::vector> g_atexit; std::mutex g_atexit_mutex; @@ -155,7 +155,7 @@ namespace sce_libc_func std::lock_guard lock(g_atexit_mutex); - g_atexit.insert(g_atexit.begin(), [func, arg, dso](ARMv7Context& context) + g_atexit.insert(g_atexit.begin(), [func, arg, dso](ARMv7Thread& context) { func(context, arg); }); @@ -167,13 +167,13 @@ namespace sce_libc_func std::lock_guard lock(g_atexit_mutex); - g_atexit.insert(g_atexit.begin(), [func, arg, dso](ARMv7Context& context) + g_atexit.insert(g_atexit.begin(), [func, arg, dso](ARMv7Thread& context) { func(context, arg); }); } - void exit(ARMv7Context& context) + void exit(ARMv7Thread& context) { sceLibc.Warning("exit()"); @@ -201,7 +201,7 @@ namespace sce_libc_func } } - void printf(ARMv7Context& context, vm::cptr fmt, armv7_va_args_t va_args) + void printf(ARMv7Thread& context, vm::cptr fmt, armv7_va_args_t va_args) { sceLibc.Warning("printf(fmt=*0x%x)", fmt); sceLibc.Log("*** *fmt = '%s'", fmt.get_ptr()); @@ -212,7 +212,7 @@ namespace sce_libc_func LOG_NOTICE(TTY, result); } - void sprintf(ARMv7Context& context, vm::ptr str, vm::cptr fmt, armv7_va_args_t va_args) + void sprintf(ARMv7Thread& context, vm::ptr str, vm::cptr fmt, armv7_va_args_t va_args) { sceLibc.Warning("sprintf(str=*0x%x, fmt=*0x%x)", str, fmt); sceLibc.Log("*** *fmt = '%s'", fmt.get_ptr()); diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpBasic.cpp b/rpcs3/Emu/ARMv7/Modules/sceNpBasic.cpp index 578d691725..a081254608 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpBasic.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceNpBasic.cpp @@ -9,7 +9,7 @@ s32 sceNpBasicInit(vm::ptr opt) throw EXCEPTION(""); } -s32 sceNpBasicTerm(ARMv7Context&) +s32 sceNpBasicTerm(ARMv7Thread&) { throw EXCEPTION(""); } @@ -19,7 +19,7 @@ s32 sceNpBasicRegisterHandler(vm::cptr handlers, vm::cp throw EXCEPTION(""); } -s32 sceNpBasicUnregisterHandler(ARMv7Context&) +s32 sceNpBasicUnregisterHandler(ARMv7Thread&) { throw EXCEPTION(""); } diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpManager.cpp b/rpcs3/Emu/ARMv7/Modules/sceNpManager.cpp index aa1551bd30..b2dcb72816 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpManager.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceNpManager.cpp @@ -9,7 +9,7 @@ s32 sceNpInit(vm::cptr commConf, vm::ptr option throw EXCEPTION(""); } -s32 sceNpScoreTerm(ARMv7Context&) +s32 sceNpScoreTerm(ARMv7Thread&) { throw EXCEPTION(""); } diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpUtility.cpp b/rpcs3/Emu/ARMv7/Modules/sceNpUtility.cpp index 51192366ba..1c76fffba6 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpUtility.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceNpUtility.cpp @@ -9,7 +9,7 @@ s32 sceNpLookupInit(s32 usesAsync, s32 threadPriority, s32 cpuAffinityMask, vm:: throw EXCEPTION(""); } -s32 sceNpLookupTerm(ARMv7Context&) +s32 sceNpLookupTerm(ARMv7Thread&) { throw EXCEPTION(""); } diff --git a/rpcs3/Emu/ARMv7/Modules/scePerf.cpp b/rpcs3/Emu/ARMv7/Modules/scePerf.cpp index 9a5c2614f0..1ef2fcd3e8 100644 --- a/rpcs3/Emu/ARMv7/Modules/scePerf.cpp +++ b/rpcs3/Emu/ARMv7/Modules/scePerf.cpp @@ -6,7 +6,7 @@ extern u64 get_system_time(); -s32 scePerfArmPmonReset(ARMv7Context& context, s32 threadId) +s32 scePerfArmPmonReset(ARMv7Thread& context, s32 threadId) { scePerf.Warning("scePerfArmPmonReset(threadId=0x%x)", threadId); @@ -20,7 +20,7 @@ s32 scePerfArmPmonReset(ARMv7Context& context, s32 threadId) return SCE_OK; } -s32 scePerfArmPmonSelectEvent(ARMv7Context& context, s32 threadId, u32 counter, u8 eventCode) +s32 scePerfArmPmonSelectEvent(ARMv7Thread& context, s32 threadId, u32 counter, u8 eventCode) { scePerf.Warning("scePerfArmPmonSelectEvent(threadId=0x%x, counter=0x%x, eventCode=0x%x)", threadId, counter, eventCode); @@ -72,7 +72,7 @@ s32 scePerfArmPmonSelectEvent(ARMv7Context& context, s32 threadId, u32 counter, return SCE_OK; } -s32 scePerfArmPmonStart(ARMv7Context& context, s32 threadId) +s32 scePerfArmPmonStart(ARMv7Thread& context, s32 threadId) { scePerf.Warning("scePerfArmPmonStart(threadId=0x%x)", threadId); @@ -84,7 +84,7 @@ s32 scePerfArmPmonStart(ARMv7Context& context, s32 threadId) return SCE_OK; } -s32 scePerfArmPmonStop(ARMv7Context& context, s32 threadId) +s32 scePerfArmPmonStop(ARMv7Thread& context, s32 threadId) { scePerf.Warning("scePerfArmPmonStop(threadId=0x%x)"); @@ -96,7 +96,7 @@ s32 scePerfArmPmonStop(ARMv7Context& context, s32 threadId) return SCE_OK; } -s32 scePerfArmPmonGetCounterValue(ARMv7Context& context, s32 threadId, u32 counter, vm::ptr pValue) +s32 scePerfArmPmonGetCounterValue(ARMv7Thread& context, s32 threadId, u32 counter, vm::ptr pValue) { scePerf.Warning("scePerfArmPmonGetCounterValue(threadId=0x%x, counter=%d, pValue=*0x%x)", threadId, counter, pValue); @@ -122,7 +122,7 @@ s32 scePerfArmPmonGetCounterValue(ARMv7Context& context, s32 threadId, u32 count return SCE_OK; } -s32 scePerfArmPmonSoftwareIncrement(ARMv7Context& context, u32 mask) +s32 scePerfArmPmonSoftwareIncrement(ARMv7Thread& context, u32 mask) { scePerf.Warning("scePerfArmPmonSoftwareIncrement(mask=0x%x)", mask); diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.cpp b/rpcs3/Emu/ARMv7/PSVFuncList.cpp index 3bbf55cfab..3b09b0a8b5 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.cpp +++ b/rpcs3/Emu/ARMv7/PSVFuncList.cpp @@ -66,7 +66,7 @@ psv_func* get_psv_func_by_index(u32 index) return &g_psv_func_list[index]; } -void execute_psv_func_by_index(ARMv7Context& context, u32 index) +void execute_psv_func_by_index(ARMv7Thread& context, u32 index) { if (auto func = get_psv_func_by_index(index)) { @@ -229,9 +229,9 @@ void initialize_psv_modules() psv_func& hle_return = g_psv_func_list[SFI_HLE_RETURN]; hle_return.nid = 0; hle_return.name = "HLE_RETURN"; - hle_return.func = [](ARMv7Context& context) + hle_return.func = [](ARMv7Thread& context) { - static_cast(context).fast_stop(); + context.fast_stop(); }; // load functions diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.h b/rpcs3/Emu/ARMv7/PSVFuncList.h index 7613e7c391..e6a02cad24 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.h +++ b/rpcs3/Emu/ARMv7/PSVFuncList.h @@ -1,7 +1,7 @@ #pragma once #include "Emu/Memory/Memory.h" -#include "ARMv7Context.h" +#include "ARMv7Thread.h" #include "Emu/SysCalls/LogBase.h" namespace vm { using namespace psv; } @@ -40,7 +40,7 @@ public: }; -using armv7_func_caller = void(*)(ARMv7Context&); +using armv7_func_caller = void(*)(ARMv7Thread&); struct armv7_va_args_t { @@ -73,12 +73,12 @@ namespace psv_func_detail static_assert(!std::is_reference::value, "Invalid function argument type (reference)"); static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_GENERAL"); - force_inline static T get_arg(ARMv7Context& context) + force_inline static T get_arg(ARMv7Thread& context) { return cast_from_armv7_gpr(context.GPR[g_count - 1]); } - force_inline static void put_arg(ARMv7Context& context, const T& arg) + force_inline static void put_arg(ARMv7Thread& context, const T& arg) { context.GPR[g_count - 1] = cast_to_armv7_gpr(arg); } @@ -90,12 +90,12 @@ namespace psv_func_detail // first u64 argument is passed in r0-r1, second one is passed in r2-r3 (if g_count = 3) static_assert(g_count == 2 || g_count == 4, "Wrong u64 argument position"); - force_inline static u64 get_arg(ARMv7Context& context) + force_inline static u64 get_arg(ARMv7Thread& context) { return context.GPR_D[(g_count - 1) >> 1]; } - force_inline static void put_arg(ARMv7Context& context, u64 arg) + force_inline static void put_arg(ARMv7Thread& context, u64 arg) { context.GPR_D[(g_count - 1) >> 1] = arg; } @@ -106,12 +106,12 @@ namespace psv_func_detail { static_assert(g_count == 2 || g_count == 4, "Wrong s64 argument position"); - force_inline static s64 get_arg(ARMv7Context& context) + force_inline static s64 get_arg(ARMv7Thread& context) { return context.GPR_D[(g_count - 1) >> 1]; } - force_inline static void put_arg(ARMv7Context& context, s64 arg) + force_inline static void put_arg(ARMv7Thread& context, s64 arg) { context.GPR_D[(g_count - 1) >> 1] = arg; } @@ -123,11 +123,11 @@ namespace psv_func_detail static_assert(f_count <= 0, "TODO: Unsupported argument type (float)"); static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_FLOAT"); - force_inline static T get_arg(ARMv7Context& context) + force_inline static T get_arg(ARMv7Thread& context) { } - force_inline static void put_arg(ARMv7Context& context, const T& arg) + force_inline static void put_arg(ARMv7Thread& context, const T& arg) { } }; @@ -138,11 +138,11 @@ namespace psv_func_detail static_assert(v_count <= 0, "TODO: Unsupported argument type (vector)"); static_assert(std::is_same, v128>::value, "Invalid function argument type for ARG_VECTOR"); - force_inline static T get_arg(ARMv7Context& context) + force_inline static T get_arg(ARMv7Thread& context) { } - force_inline static void put_arg(ARMv7Context& context, const T& arg) + force_inline static void put_arg(ARMv7Thread& context, const T& arg) { } }; @@ -154,13 +154,13 @@ namespace psv_func_detail static_assert(v_count <= 0, "TODO: Unsupported stack argument type (vector)"); static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_STACK"); - force_inline static T get_arg(ARMv7Context& context) + force_inline static T get_arg(ARMv7Thread& context) { // TODO: check return cast_from_armv7_gpr(vm::read32(context.SP + sizeof(u32) * (g_count - 5))); } - force_inline static void put_arg(ARMv7Context& context, const T& arg) + force_inline static void put_arg(ARMv7Thread& context, const T& arg) { // TODO: check const int stack_pos = (g_count - 5) * 4 - FIXED_STACK_FRAME_SIZE; @@ -173,13 +173,13 @@ namespace psv_func_detail template struct bind_arg { - force_inline static u64 get_arg(ARMv7Context& context) + force_inline static u64 get_arg(ARMv7Thread& context) { // TODO: check return vm::read64(context.SP + sizeof(u32) * (g_count - 6)); } - force_inline static void put_arg(ARMv7Context& context, u64 arg) + force_inline static void put_arg(ARMv7Thread& context, u64 arg) { // TODO: check const int stack_pos = (g_count - 6) * 4 - FIXED_STACK_FRAME_SIZE; @@ -192,13 +192,13 @@ namespace psv_func_detail template struct bind_arg { - force_inline static s64 get_arg(ARMv7Context& context) + force_inline static s64 get_arg(ARMv7Thread& context) { // TODO: check return vm::read64(context.SP + sizeof(u32) * (g_count - 6)); } - force_inline static void put_arg(ARMv7Context& context, s64 arg) + force_inline static void put_arg(ARMv7Thread& context, s64 arg) { // TODO: check const int stack_pos = (g_count - 6) * 4 - FIXED_STACK_FRAME_SIZE; @@ -211,14 +211,14 @@ namespace psv_func_detail template struct bind_arg { - static_assert(std::is_same::value, "Invalid function argument type for ARG_CONTEXT"); + static_assert(std::is_same::value, "Invalid function argument type for ARG_CONTEXT"); - force_inline static ARMv7Context& get_arg(ARMv7Context& context) + force_inline static ARMv7Thread& get_arg(ARMv7Thread& context) { return context; } - force_inline static void put_arg(ARMv7Context& context, ARMv7Context& arg) + force_inline static void put_arg(ARMv7Thread& context, ARMv7Thread& arg) { } }; @@ -228,7 +228,7 @@ namespace psv_func_detail { static_assert(std::is_same, armv7_va_args_t>::value, "Invalid function argument type for ARG_VARIADIC"); - force_inline static armv7_va_args_t get_arg(ARMv7Context& context) + force_inline static armv7_va_args_t get_arg(ARMv7Thread& context) { return{ g_count, f_count, v_count }; } @@ -242,12 +242,12 @@ namespace psv_func_detail static_assert(type == ARG_GENERAL, "Wrong use of bind_result template"); static_assert(sizeof(T) <= 4, "Invalid function result type for ARG_GENERAL"); - force_inline static T get_result(ARMv7Context& context) + force_inline static T get_result(ARMv7Thread& context) { return cast_from_armv7_gpr(context.GPR[0]); } - force_inline static void put_result(ARMv7Context& context, const T& result) + force_inline static void put_result(ARMv7Thread& context, const T& result) { context.GPR[0] = cast_to_armv7_gpr(result); } @@ -256,12 +256,12 @@ namespace psv_func_detail template<> struct bind_result { - force_inline static u64 get_result(ARMv7Context& context) + force_inline static u64 get_result(ARMv7Thread& context) { return context.GPR_D[0]; } - force_inline static void put_result(ARMv7Context& context, u64 result) + force_inline static void put_result(ARMv7Thread& context, u64 result) { context.GPR_D[0] = result; } @@ -270,12 +270,12 @@ namespace psv_func_detail template<> struct bind_result { - force_inline static s64 get_result(ARMv7Context& context) + force_inline static s64 get_result(ARMv7Thread& context) { return context.GPR_D[0]; } - force_inline static void put_result(ARMv7Context& context, s64 result) + force_inline static void put_result(ARMv7Thread& context, s64 result) { context.GPR_D[0] = result; } @@ -286,7 +286,7 @@ namespace psv_func_detail //{ // static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT"); - // static force_inline void put_result(ARMv7Context& context, const T& result) + // static force_inline void put_result(ARMv7Thread& context, const T& result) // { // } //}; @@ -296,7 +296,7 @@ namespace psv_func_detail //{ // static_assert(std::is_same, v128>::value, "Invalid function result type for ARG_VECTOR"); - // static force_inline void put_result(ARMv7Context& context, const T& result) + // static force_inline void put_result(ARMv7Thread& context, const T& result) // { // } //}; @@ -317,7 +317,7 @@ namespace psv_func_detail // TODO: check calculations static const bool is_float = std::is_floating_point::value; static const bool is_vector = std::is_same, v128>::value; - static const bool is_context = std::is_same::value; + static const bool is_context = std::is_same::value; static const bool is_variadic = std::is_same, armv7_va_args_t>::value; static const bool is_general = !is_float && !is_vector && !is_context && !is_variadic; @@ -356,21 +356,21 @@ namespace psv_func_detail // argument type + g/f/v_count unpacker template struct bind_arg_packed { - force_inline static T get_arg(ARMv7Context& context) + force_inline static T get_arg(ARMv7Thread& context) { return bind_arg(type_pack & 0xff), (type_pack >> 8) & 0xff, (type_pack >> 16) & 0xff, (type_pack >> 24)>::get_arg(context); } }; template - force_inline RT call(ARMv7Context& context, RT(*func)(Args...), arg_info_pack_t info) + force_inline RT call(ARMv7Thread& context, RT(*func)(Args...), arg_info_pack_t info) { // do the actual function call when all arguments are prepared (simultaneous unpacking of Args... and Info...) return func(bind_arg_packed::get_arg(context)...); } template - force_inline RT call(ARMv7Context& context, RT(*func)(Args...), arg_info_pack_t info) + force_inline RT call(ARMv7Thread& context, RT(*func)(Args...), arg_info_pack_t info) { // unpack previous type counts (0/0/0 for the first time) const u32 g_count = (info.last_value >> 8) & 0xff; @@ -387,14 +387,14 @@ namespace psv_func_detail } template - force_inline static bool put_func_args(ARMv7Context& context) + force_inline static bool put_func_args(ARMv7Thread& context) { // terminator return false; } template - force_inline static bool put_func_args(ARMv7Context& context, T1 arg, T... args) + force_inline static bool put_func_args(ARMv7Thread& context, T1 arg, T... args) { using type = arg_type; const arg_class t = type::value; @@ -416,7 +416,7 @@ namespace psv_func_detail { using func_t = void(*)(T...); - static void do_call(ARMv7Context& context, func_t func) + static void do_call(ARMv7Thread& context, func_t func) { call(context, func, arg_info_pack_t<>{}); } @@ -427,7 +427,7 @@ namespace psv_func_detail { using func_t = RT(*)(T...); - static void do_call(ARMv7Context& context, func_t func) + static void do_call(ARMv7Thread& context, func_t func) { bind_result::value>::put_result(context, call(context, func, arg_info_pack_t<>{})); } @@ -436,7 +436,7 @@ namespace psv_func_detail template struct func_caller { - force_inline static RT call(ARMv7Context& context, u32 addr, T... args) + force_inline static RT call(ARMv7Thread& context, u32 addr, T... args) { func_caller::call(context, addr, args...); @@ -447,7 +447,7 @@ namespace psv_func_detail template struct func_caller { - force_inline static void call(ARMv7Context& context, u32 addr, T... args) + force_inline static void call(ARMv7Thread& context, u32 addr, T... args) { if (put_func_args<0, 0, 0, T...>(context, args...)) { @@ -496,19 +496,19 @@ enum psv_special_function_index : u16 // Do not call directly u32 add_psv_func(psv_func data); // Do not call directly -template force_inline void call_psv_func(ARMv7Context& context, RT(*func)(T...)) +template force_inline void call_psv_func(ARMv7Thread& context, RT(*func)(T...)) { psv_func_detail::func_binder::do_call(context, func); } -#define reg_psv_func(nid, module, name, func) add_psv_func(psv_func(nid, 0, module, name, [](ARMv7Context& context){ call_psv_func(context, func); })) +#define reg_psv_func(nid, module, name, func) add_psv_func(psv_func(nid, 0, module, name, [](ARMv7Thread& context){ call_psv_func(context, func); })) // Find registered HLE function by NID psv_func* get_psv_func_by_nid(u32 nid, u32* out_index = nullptr); // Find registered HLE function by its index psv_func* get_psv_func_by_index(u32 index); // Execute registered HLE function by its index -void execute_psv_func_by_index(ARMv7Context& context, u32 index); +void execute_psv_func_by_index(ARMv7Thread& context, u32 index); // Register all HLE functions void initialize_psv_modules(); // Unregister all HLE functions diff --git a/rpcs3/Emu/ARMv7/PSVObjectList.cpp b/rpcs3/Emu/ARMv7/PSVObjectList.cpp deleted file mode 100644 index d0212876ba..0000000000 --- a/rpcs3/Emu/ARMv7/PSVObjectList.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/ARMv7/PSVFuncList.h" -#include "Emu/ARMv7/PSVObjectList.h" -#include "Modules/sceLibKernel.h" -#include "Modules/psv_sema.h" -#include "Modules/psv_event_flag.h" -#include "Modules/psv_mutex.h" -#include "Modules/psv_cond.h" - -psv_sema_list_t g_psv_sema_list; -psv_ef_list_t g_psv_ef_list; -psv_mutex_list_t g_psv_mutex_list; -psv_cond_list_t g_psv_cond_list; - -void clear_all_psv_objects() -{ - g_psv_sema_list.clear(); - g_psv_ef_list.clear(); - g_psv_mutex_list.clear(); - g_psv_cond_list.clear(); -} diff --git a/rpcs3/Emu/ARMv7/PSVObjectList.h b/rpcs3/Emu/ARMv7/PSVObjectList.h index cb15c6f173..87fe194bae 100644 --- a/rpcs3/Emu/ARMv7/PSVObjectList.h +++ b/rpcs3/Emu/ARMv7/PSVObjectList.h @@ -122,5 +122,3 @@ public: m_hint = 0; } }; - -void clear_all_psv_objects(); diff --git a/rpcs3/Emu/Event.cpp b/rpcs3/Emu/Event.cpp index ff3dbd11c2..8c9ceae8cc 100644 --- a/rpcs3/Emu/Event.cpp +++ b/rpcs3/Emu/Event.cpp @@ -2,7 +2,6 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/lv2/sleep_queue.h" #include "Emu/SysCalls/lv2/sys_event.h" #include "Event.h" diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index bd8201521e..e29ef2994c 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -1,7 +1,7 @@ #pragma once class PPUThread; -struct ARMv7Context; +class ARMv7Thread; namespace vm { @@ -136,7 +136,7 @@ namespace vm RT operator()(PPUThread& CPU, T... args) const; // defined in ARMv7Callback.h, passing context is mandatory - RT operator()(ARMv7Context& context, T... args) const; + RT operator()(ARMv7Thread& context, T... args) const; // conversion to another function pointer template operator _ptr_base() const diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 8729986348..b3becabf3e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -6,7 +6,7 @@ #include "Emu/SysCalls/Callback.h" #include "rpcs3/Ini.h" -#include "Emu/SysCalls/lv2/sleep_queue.h" +#include "Emu/SysCalls/lv2/sys_sync.h" #include "Emu/SysCalls/lv2/sys_event.h" #include "Emu/Event.h" #include "Emu/Audio/AudioManager.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index 9de9d27184..056d16423c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -6,7 +6,7 @@ #include "Emu/Event.h" #include "Emu/Cell/SPUThread.h" -#include "Emu/SysCalls/lv2/sleep_queue.h" +#include "Emu/SysCalls/lv2/sys_sync.h" #include "Emu/SysCalls/lv2/sys_lwmutex.h" #include "Emu/SysCalls/lv2/sys_lwcond.h" #include "Emu/SysCalls/lv2/sys_spu.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp index 7ead629d4b..195d42154b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp @@ -3,7 +3,7 @@ #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/lv2/sleep_queue.h" +#include "Emu/SysCalls/lv2/sys_sync.h" #include "Emu/SysCalls/lv2/sys_lwmutex.h" #include "Emu/SysCalls/lv2/sys_lwcond.h" #include "Emu/SysCalls/lv2/sys_spu.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp index a2ae426665..f23b39b13b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp @@ -3,7 +3,7 @@ #include "Emu/System.h" #include "Emu/Cell/SPUThread.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/lv2/sleep_queue.h" +#include "Emu/SysCalls/lv2/sys_sync.h" #include "Emu/SysCalls/lv2/sys_lwmutex.h" #include "Emu/SysCalls/lv2/sys_lwcond.h" #include "Emu/SysCalls/lv2/sys_spu.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 048423451b..e7cbd57565 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -3,7 +3,7 @@ #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/lv2/sleep_queue.h" +#include "Emu/SysCalls/lv2/sys_sync.h" #include "Emu/SysCalls/lv2/sys_event.h" #include "Emu/SysCalls/lv2/sys_process.h" #include "Emu/Event.h" diff --git a/rpcs3/Emu/SysCalls/Modules/sys_lwcond_.cpp b/rpcs3/Emu/SysCalls/Modules/sys_lwcond_.cpp index 8af6a97245..3bf05a08a1 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_lwcond_.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_lwcond_.cpp @@ -4,6 +4,7 @@ #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/lv2/sys_sync.h" #include "Emu/SysCalls/lv2/sys_lwmutex.h" #include "Emu/SysCalls/lv2/sys_lwcond.h" #include "sysPrxForUser.h" diff --git a/rpcs3/Emu/SysCalls/Modules/sys_lwmutex_.cpp b/rpcs3/Emu/SysCalls/Modules/sys_lwmutex_.cpp index 7116d37271..6146af1a85 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_lwmutex_.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_lwmutex_.cpp @@ -4,6 +4,7 @@ #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/lv2/sys_sync.h" #include "Emu/SysCalls/lv2/sys_lwmutex.h" #include "sysPrxForUser.h" diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 42880c8c36..ff2ec5cd0f 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -6,7 +6,6 @@ #include "Emu/System.h" #include "Modules.h" -#include "lv2/sleep_queue.h" #include "lv2/sys_lwmutex.h" #include "lv2/sys_lwcond.h" #include "lv2/sys_mutex.h" diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp index ca26f063c6..5b5c8de7d2 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp @@ -5,6 +5,7 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/Cell/PPUThread.h" +#include "sys_sync.h" #include "sys_mutex.h" #include "sys_cond.h" diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.h b/rpcs3/Emu/SysCalls/lv2/sys_cond.h index c9ff2ba0ed..2b0583cd1e 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.h @@ -1,6 +1,6 @@ #pragma once -#include "sleep_queue.h" +#include "Utilities/SleepQueue.h" namespace vm { using namespace ps3; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp index a451cdb067..665648580a 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp @@ -7,6 +7,7 @@ #include "Emu/Cell/PPUThread.h" #include "Emu/Cell/SPUThread.h" #include "Emu/Event.h" +#include "sys_sync.h" #include "sys_process.h" #include "sys_event.h" diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.h b/rpcs3/Emu/SysCalls/lv2/sys_event.h index 30c7df98a6..511a3ca465 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.h @@ -1,6 +1,6 @@ #pragma once -#include "sleep_queue.h" +#include "Utilities/SleepQueue.h" namespace vm { using namespace ps3; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp index 7548621fc4..1425a2d141 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp @@ -5,6 +5,7 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/Cell/PPUThread.h" +#include "sys_sync.h" #include "sys_event_flag.h" SysCallBase sys_event_flag("sys_event_flag"); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h index c9958ae2fe..427027b84b 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h @@ -1,6 +1,6 @@ #pragma once -#include "sleep_queue.h" +#include "Utilities/SleepQueue.h" namespace vm { using namespace ps3; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h index db6ad198b2..38e961c759 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h @@ -1,6 +1,6 @@ #pragma once -#include "sleep_queue.h" +#include "Utilities/SleepQueue.h" namespace vm { using namespace ps3; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp index 52a6935456..61dc88a827 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp @@ -5,6 +5,7 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/Cell/PPUThread.h" +#include "sys_sync.h" #include "sys_lwmutex.h" SysCallBase sys_lwmutex("sys_lwmutex"); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h index 1aa484b6eb..431b8aa149 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h @@ -1,6 +1,6 @@ #pragma once -#include "sleep_queue.h" +#include "Utilities/SleepQueue.h" namespace vm { using namespace ps3; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp index f234b5a05a..a34c81fde6 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp @@ -5,6 +5,7 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/Cell/PPUThread.h" +#include "sys_sync.h" #include "sys_mutex.h" SysCallBase sys_mutex("sys_mutex"); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.h b/rpcs3/Emu/SysCalls/lv2/sys_mutex.h index b236bc8f2c..8e736b5ea9 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.h @@ -1,6 +1,6 @@ #pragma once -#include "sleep_queue.h" +#include "Utilities/SleepQueue.h" namespace vm { using namespace ps3; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp index 56d3278c12..c0fcfd21ae 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp @@ -5,6 +5,7 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/Cell/PPUThread.h" +#include "sys_sync.h" #include "sys_rwlock.h" SysCallBase sys_rwlock("sys_rwlock"); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h index bcd12dd16e..ea9f19f138 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h @@ -1,6 +1,6 @@ #pragma once -#include "sleep_queue.h" +#include "Utilities/SleepQueue.h" namespace vm { using namespace ps3; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp index bb27d6b271..99a4223dd3 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp @@ -5,6 +5,7 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/Cell/PPUThread.h" +#include "sys_sync.h" #include "sys_semaphore.h" SysCallBase sys_semaphore("sys_semaphore"); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h index 47719af44c..f179b072cd 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h @@ -1,6 +1,6 @@ #pragma once -#include "sleep_queue.h" +#include "Utilities/SleepQueue.h" namespace vm { using namespace ps3; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_sync.h b/rpcs3/Emu/SysCalls/lv2/sys_sync.h new file mode 100644 index 0000000000..76fc562eae --- /dev/null +++ b/rpcs3/Emu/SysCalls/lv2/sys_sync.h @@ -0,0 +1,42 @@ +#pragma once + +namespace vm { using namespace ps3; } + +// attr_protocol (waiting scheduling policy) +enum +{ + // First In, First Out + SYS_SYNC_FIFO = 1, + // Priority Order + SYS_SYNC_PRIORITY = 2, + // Basic Priority Inheritance Protocol (probably not implemented) + SYS_SYNC_PRIORITY_INHERIT = 3, + // Not selected while unlocking + SYS_SYNC_RETRY = 4, + // + SYS_SYNC_ATTR_PROTOCOL_MASK = 0xF, +}; + +// attr_recursive (recursive locks policy) +enum +{ + // Recursive locks are allowed + SYS_SYNC_RECURSIVE = 0x10, + // Recursive locks are NOT allowed + SYS_SYNC_NOT_RECURSIVE = 0x20, + // + SYS_SYNC_ATTR_RECURSIVE_MASK = 0xF0, //??? +}; + +// attr_pshared +enum +{ + SYS_SYNC_NOT_PROCESS_SHARED = 0x200, +}; + +// attr_adaptive +enum +{ + SYS_SYNC_ADAPTIVE = 0x1000, + SYS_SYNC_NOT_ADAPTIVE = 0x2000, +}; diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 2e53fe28b8..2896113304 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -40,7 +40,6 @@ extern std::atomic g_thread_count; extern u64 get_system_time(); extern void finalize_ppu_exec_map(); extern void finalize_psv_modules(); -extern void clear_all_psv_objects(); Emulator::Emulator() : m_status(Stopped) @@ -379,7 +378,6 @@ void Emulator::Stop() LOG_NOTICE(GENERAL, "Objects cleared..."); finalize_psv_modules(); - clear_all_psv_objects(); for (auto& v : decltype(g_armv7_dump)(std::move(g_armv7_dump))) { diff --git a/rpcs3/Gui/KernelExplorer.cpp b/rpcs3/Gui/KernelExplorer.cpp index 28f1769aa4..15a25e677f 100644 --- a/rpcs3/Gui/KernelExplorer.cpp +++ b/rpcs3/Gui/KernelExplorer.cpp @@ -7,7 +7,6 @@ #include "Emu/Cell/PPUThread.h" #include "Emu/Cell/SPUThread.h" #include "Emu/Cell/RawSPUThread.h" -#include "Emu/SysCalls/lv2/sleep_queue.h" #include "Emu/SysCalls/lv2/sys_lwmutex.h" #include "Emu/SysCalls/lv2/sys_lwcond.h" #include "Emu/SysCalls/lv2/sys_mutex.h" diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index f03eeeaf20..e6c15b14a7 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -47,6 +47,7 @@ + @@ -105,10 +106,6 @@ - - - - @@ -170,7 +167,6 @@ - @@ -223,7 +219,6 @@ - @@ -388,6 +383,7 @@ + @@ -408,10 +404,6 @@ - - - - @@ -571,7 +563,7 @@ - + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 6b6f6c583b..f6ced9eac7 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -84,9 +84,6 @@ {1d6abf72-0f18-43ec-9351-1fed1a3d1a1e} - - {368770cf-c8d9-4f4a-9ac3-5bdf48101ffe} - {2a8841dc-bce0-41bb-9fcb-5bf1f8dda213} @@ -587,15 +584,6 @@ Emu\CPU\ARMv7 - - Emu\CPU\ARMv7 - - - Emu\CPU\ARMv7\Objects - - - Emu\CPU\ARMv7\Objects - Emu\CPU\ARMv7\Modules @@ -764,21 +752,12 @@ Emu\CPU\ARMv7\Modules - - Emu\CPU\ARMv7\Objects - - - Emu\CPU\ARMv7\Objects - Emu\GPU\RSX Emu\SysCalls\Modules - - Emu\SysCalls\lv2 - Emu\SysCalls\lv2 @@ -1001,6 +980,9 @@ Emu + + Utilities + @@ -1594,12 +1576,6 @@ Emu\CPU\ARMv7 - - Emu\CPU\ARMv7\Objects - - - Emu\CPU\ARMv7\Objects - Emu\CPU\ARMv7\Modules @@ -1621,12 +1597,6 @@ Emu\CPU\ARMv7\Modules - - Emu\CPU\ARMv7\Objects - - - Emu\CPU\ARMv7\Objects - Emu\SysCalls\Modules @@ -1642,9 +1612,6 @@ Emu\CPU\Cell - - Emu\SysCalls\lv2 - Emu\Memory @@ -1891,5 +1858,11 @@ Emu\GPU\RSX\D3D12 + + Utilities + + + Emu\SysCalls\lv2 + \ No newline at end of file