diff --git a/rpcs3/Emu/ARMv7/ARMv7Context.h b/rpcs3/Emu/ARMv7/ARMv7Context.h index 491e0a0845..c0aebaff78 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Context.h +++ b/rpcs3/Emu/ARMv7/ARMv7Context.h @@ -79,8 +79,8 @@ struct ARMv7Context { struct { - u8 cond : 3; u8 state : 5; + u8 cond : 3; }; u8 IT; diff --git a/rpcs3/Emu/ARMv7/Modules/psv_sema_object.cpp b/rpcs3/Emu/ARMv7/Modules/psv_sema_object.cpp index 4e6046bd25..0e67d72444 100644 --- a/rpcs3/Emu/ARMv7/Modules/psv_sema_object.cpp +++ b/rpcs3/Emu/ARMv7/Modules/psv_sema_object.cpp @@ -4,5 +4,3 @@ #include "Emu/ARMv7/PSVObjectList.h" #include "sceLibKernel.h" #include "psv_sema_object.h" - -psv_object_list_t g_psv_sema_list; diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp index fd852feae7..e033e4ef22 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp @@ -468,7 +468,14 @@ s32 sceKernelCreateSema(vm::psv::ptr pName, u32 attr, s32 initCount, s32 sceKernelDeleteSema(s32 semaId) { - throw __FUNCTION__; + sceLibKernel.Error("sceKernelDeleteSema(semaId=0x%x)", semaId); + + if (!g_psv_sema_list.remove(semaId)) + { + RETURN_ERROR(SCE_KERNEL_ERROR_INVALID_UID); + } + + throw SCE_OK; } s32 sceKernelOpenSema(vm::psv::ptr pName) diff --git a/rpcs3/Emu/ARMv7/PSVObjectList.cpp b/rpcs3/Emu/ARMv7/PSVObjectList.cpp index d9cb43aeef..c90ebf20da 100644 --- a/rpcs3/Emu/ARMv7/PSVObjectList.cpp +++ b/rpcs3/Emu/ARMv7/PSVObjectList.cpp @@ -1,3 +1,13 @@ #include "stdafx.h" -#include "PSVObjectList.h" +#include "Emu/Memory/Memory.h" +#include "Emu/ARMv7/PSVFuncList.h" +#include "Emu/ARMv7/PSVObjectList.h" +#include "Modules/sceLibKernel.h" +#include "Modules/psv_sema_object.h" +psv_object_list_t g_psv_sema_list; + +void clear_all_psv_objects() +{ + g_psv_sema_list.clear(); +} diff --git a/rpcs3/Emu/ARMv7/PSVObjectList.h b/rpcs3/Emu/ARMv7/PSVObjectList.h index 5fb6b5da93..d25c6e39ce 100644 --- a/rpcs3/Emu/ARMv7/PSVObjectList.h +++ b/rpcs3/Emu/ARMv7/PSVObjectList.h @@ -25,6 +25,7 @@ template class psv_object_list_t // Class for managing object data { std::array, 0x8000> m_data; + std::mutex m_mutex; // TODO: remove it when shared_ptr atomic ops are fully available public: static const u32 uid_class = type; @@ -57,12 +58,16 @@ public: // generate UID for newly created object (will return zero if the limit exceeded) s32 add(std::shared_ptr& data) { + std::lock_guard lock(m_mutex); + for (auto& value : m_data) { // find an empty position and move the pointer - std::shared_ptr old_ptr = nullptr; - if (std::atomic_compare_exchange_strong(&value, &old_ptr, data)) + //std::shared_ptr old_ptr = nullptr; + //if (std::atomic_compare_exchange_strong(&value, &old_ptr, data)) + if (!value) { + value = data; psv_uid_t id = psv_uid_t::make(1); // odd number id.type = uid_class; // set type id.number = &value - m_data.data(); // set position @@ -81,12 +86,19 @@ public: return nullptr; } - return std::atomic_exchange(&m_data[psv_uid_t::make(uid).number], nullptr); + std::lock_guard lock(m_mutex); + + std::shared_ptr old_ptr = nullptr; + m_data[psv_uid_t::make(uid).number].swap(old_ptr); + return old_ptr; + //return std::atomic_exchange>(&m_data[psv_uid_t::make(uid).number], nullptr); } // remove all objects void clear() { + std::lock_guard lock(m_mutex); + for (auto& value : m_data) { value = nullptr; @@ -94,3 +106,4 @@ public: } }; +void clear_all_psv_objects(); diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 9e17b56ddf..8324e0e54f 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -6,6 +6,7 @@ #include "Emu/GameInfo.h" #include "Emu/ARMv7/PSVFuncList.h" +#include "Emu/ARMv7/PSVObjectList.h" #include "Emu/SysCalls/Static.h" #include "Emu/SysCalls/ModuleManager.h" #include "Emu/Cell/PPUThread.h" @@ -363,6 +364,7 @@ void Emulator::Stop() LOG_NOTICE(HLE, "All threads stopped..."); finalize_psv_modules(); + clear_all_psv_objects(); m_rsx_callback = 0; // TODO: check finalization order