From 526aaf73022e5c8f24ebec73ba2396ceeddc7220 Mon Sep 17 00:00:00 2001 From: Eladash <18193363+elad335@users.noreply.github.com> Date: Thu, 28 Dec 2023 19:37:24 +0200 Subject: [PATCH] Fix idm::allocate_id at fixed position --- rpcs3/Emu/Cell/PPUModule.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_spu.cpp | 4 ++-- rpcs3/Emu/IdManager.cpp | 7 +++++-- rpcs3/Emu/IdManager.h | 23 ++++++++++++++++++----- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index 64caf51f4e..736de83f15 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -3019,7 +3019,7 @@ std::pair, CellError> ppu_load_overlay(const ppu_ex if (!ar && !virtual_load) { - idm::import_existing(ovlm); + ensure(idm::import_existing(ovlm)); try_spawn_ppu_if_exclusive_program(*ovlm); } diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index 14fb9cc677..6743ddf718 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -227,8 +227,8 @@ lv2_spu_group::lv2_spu_group(utils::serial& ar) noexcept if (ar.pop()) { ar(id_manager::g_id); - thread = std::make_shared>(ar, this); - idm::import_existing>(thread, idm::last_id()); + thread = std::make_shared>(stx::launch_retainer{}, ar, this); + ensure(idm::import_existing>(thread, idm::last_id())); running += !thread->stop_flag_removal_protection; } } diff --git a/rpcs3/Emu/IdManager.cpp b/rpcs3/Emu/IdManager.cpp index 8db94b2e51..71dea33da4 100644 --- a/rpcs3/Emu/IdManager.cpp +++ b/rpcs3/Emu/IdManager.cpp @@ -35,10 +35,13 @@ std::vector>& id_manager::get_typeinfo_map idm::map_data* idm::allocate_id(std::vector& vec, u32 type_id, u32 dst_id, u32 base, u32 step, u32 count, bool uses_lowest_id, std::pair invl_range) { - if (const u32 index = id_manager::get_index(dst_id, base, step, count, invl_range); index < count) + if (dst_id != (base ? 0 : u32{umax})) { // Fixed position construction - ensure(index < vec.size()); + const u32 index = id_manager::get_index(dst_id, base, step, count, invl_range); + ensure(index < count); + + vec.resize(std::max(vec.size(), index + 1)); if (vec[index].second) { diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index facbfbc71b..a5f4e2a7b2 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -102,13 +102,26 @@ namespace id_manager template struct id_traits_load_func { - static constexpr std::shared_ptr(*load)(utils::serial&) = [](utils::serial& ar) -> std::shared_ptr { return std::make_shared(stx::exact_t(ar)); }; + static constexpr std::shared_ptr(*load)(utils::serial&) = [](utils::serial& ar) -> std::shared_ptr + { + if constexpr (std::is_constructible_v, stx::exact_t>) + { + return std::make_shared(stx::launch_retainer{}, stx::exact_t(ar)); + } + else + { + return std::make_shared(stx::exact_t(ar)); + } + }; }; template struct id_traits_load_func> { - static constexpr std::shared_ptr(*load)(utils::serial&) = [](utils::serial& ar) -> std::shared_ptr { return T::load(stx::exact_t(ar)); }; + static constexpr std::shared_ptr(*load)(utils::serial&) = [](utils::serial& ar) -> std::shared_ptr + { + return T::load(stx::exact_t(ar)); + }; }; template @@ -354,10 +367,10 @@ namespace id_manager id_map& operator=(thread_state state) noexcept requires (std::is_assignable_v) { - if (private_copy.size() != vec.size()) - { - private_copy.clear(); + private_copy.clear(); + if (!vec.empty() || !private_copy.empty()) + { reader_lock lock(g_mutex); // Save all entries