From 3c6fa87625e66a7e462776ab26d182da4d8e31a3 Mon Sep 17 00:00:00 2001 From: Eladash Date: Wed, 18 Mar 2020 16:47:44 +0200 Subject: [PATCH 1/2] Fix lv2 sys_lwcond/sys_lwmutex kernel explorer names --- rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp | 2 +- rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_lwcond.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_lwcond.h | 4 ++-- rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_lwmutex.h | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp index 12347ba0d913..db1f892dea7b 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp @@ -18,7 +18,7 @@ error_code sys_lwcond_create(ppu_thread& ppu, vm::ptr lwcond, vm:: attrs->pshared = SYS_SYNC_NOT_PROCESS_SHARED; attrs->name_u64 = attr->name_u64; - if (auto res = g_cfg.core.hle_lwmutex ? sys_cond_create(ppu, out_id, lwmutex->sleep_queue, attrs) : _sys_lwcond_create(ppu, out_id, lwmutex->sleep_queue, lwcond, attr->name_u64)) + if (auto res = g_cfg.core.hle_lwmutex ? sys_cond_create(ppu, out_id, lwmutex->sleep_queue, attrs) : _sys_lwcond_create(ppu, out_id, lwmutex->sleep_queue, lwcond, std::bit_cast>(attr->name_u64))) { return res; } diff --git a/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp index 830485f99a44..ea7ba4ce1ced 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp @@ -41,7 +41,7 @@ error_code sys_lwmutex_create(ppu_thread& ppu, vm::ptr lwmutex, v attrs->flags = 0; attrs->name_u64 = attr->name_u64; - if (error_code res = g_cfg.core.hle_lwmutex ? sys_mutex_create(ppu, out_id, attrs) : _sys_lwmutex_create(ppu, out_id, protocol, lwmutex, 0x80000001, attr->name_u64)) + if (error_code res = g_cfg.core.hle_lwmutex ? sys_mutex_create(ppu, out_id, attrs) : _sys_lwmutex_create(ppu, out_id, protocol, lwmutex, 0x80000001, std::bit_cast>(attr->name_u64))) { return res; } diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp index 0922b707c1da..cfc12e2b4e8f 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp @@ -13,7 +13,7 @@ error_code _sys_lwcond_create(ppu_thread& ppu, vm::ptr lwcond_id, u32 lwmut { vm::temporary_unlock(ppu); - sys_lwcond.warning(u8"_sys_lwcond_create(lwcond_id=*0x%x, lwmutex_id=0x%x, control=*0x%x, name=0x%llx (“%s”))", lwcond_id, lwmutex_id, control, name, lv2_obj::name64(name)); + sys_lwcond.warning(u8"_sys_lwcond_create(lwcond_id=*0x%x, lwmutex_id=0x%x, control=*0x%x, name=0x%llx (“%s”))", lwcond_id, lwmutex_id, control, name, lv2_obj::name64(std::bit_cast>(name))); u32 protocol; diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.h b/rpcs3/Emu/Cell/lv2/sys_lwcond.h index 30ffbd648fb7..2255c7281b49 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.h +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.h @@ -25,7 +25,7 @@ struct lv2_lwcond final : lv2_obj { static const u32 id_base = 0x97000000; - const u64 name; + const be_t name; const u32 lwid; const u32 protocol; vm::ptr control; @@ -35,7 +35,7 @@ struct lv2_lwcond final : lv2_obj std::deque sq; lv2_lwcond(u64 name, u32 lwid, u32 protocol, vm::ptr control) - : name(name) + : name(std::bit_cast>(name)) , lwid(lwid) , protocol(protocol) , control(control) diff --git a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp index ea28ee0c3a88..1ee7f2691516 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp @@ -12,7 +12,7 @@ error_code _sys_lwmutex_create(ppu_thread& ppu, vm::ptr lwmutex_id, u32 pro { vm::temporary_unlock(ppu); - sys_lwmutex.warning(u8"_sys_lwmutex_create(lwmutex_id=*0x%x, protocol=0x%x, control=*0x%x, has_name=0x%x, name=0x%llx (“%s”))", lwmutex_id, protocol, control, has_name, name, lv2_obj::name64(name)); + sys_lwmutex.warning(u8"_sys_lwmutex_create(lwmutex_id=*0x%x, protocol=0x%x, control=*0x%x, has_name=0x%x, name=0x%llx (“%s”))", lwmutex_id, protocol, control, has_name, name, lv2_obj::name64(std::bit_cast>(name))); if (protocol != SYS_SYNC_FIFO && protocol != SYS_SYNC_RETRY && protocol != SYS_SYNC_PRIORITY) { diff --git a/rpcs3/Emu/Cell/lv2/sys_lwmutex.h b/rpcs3/Emu/Cell/lv2/sys_lwmutex.h index d10877cc21cd..818887293bf5 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwmutex.h +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.h @@ -57,7 +57,7 @@ struct lv2_lwmutex final : lv2_obj const u32 protocol; const vm::ptr control; - const u64 name; + const be_t name; shared_mutex mutex; atomic_t signaled{0}; @@ -66,7 +66,7 @@ struct lv2_lwmutex final : lv2_obj lv2_lwmutex(u32 protocol, vm::ptr control, u64 name) : protocol(protocol) , control(control) - , name(name) + , name(std::bit_cast>(name)) { } }; From a030c3e3e8c51de22a2d3fa4fa123f9b9d53b7c9 Mon Sep 17 00:00:00 2001 From: Eladash Date: Wed, 18 Mar 2020 21:44:58 +0200 Subject: [PATCH 2/2] Minor fix of sys_ppu_thread_yield return value Account for a special case where threads were rotated but no context switch was made. --- rpcs3/Emu/Cell/lv2/lv2.cpp | 32 +++++++++++++++++++++------ rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_sync.h | 2 +- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index 2454d9307426..519d94a6872a 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -1162,16 +1162,34 @@ bool lv2_obj::awake_unlocked(cpu_thread* cpu, s32 prio) if (const auto ppu = g_ppu[i]; ppu == cpu) { - if (g_ppu[i + 1]->prio != ppu->prio) + std::size_t j = i + 1; + + for (; j < g_ppu.size(); j++) { + if (g_ppu[j]->prio != ppu->prio) + { + break; + } + } + + if (j == i + 1) + { + // Empty 'same prio' threads list return false; } - else + + // Rotate current thread to the last position of the 'same prio' threads list + std::rotate(g_ppu.begin() + i, g_ppu.begin() + i + 1, g_ppu.begin() + j); + + if (j <= g_cfg.core.ppu_threads + 0u) { - g_ppu.erase(g_ppu.cbegin() + i); - ppu->start_time = get_guest_system_time(); - break; + // Threads were rotated, but no context switch was made + return false; } + + ppu->start_time = get_guest_system_time(); + cpu = nullptr; // Disable current thread enqueing, also enable threads list enqueing + break; } } } @@ -1227,9 +1245,9 @@ bool lv2_obj::awake_unlocked(cpu_thread* cpu, s32 prio) } // Remove pending if necessary - if (!g_pending.empty() && cpu && cpu == get_current_cpu_thread()) + if (!g_pending.empty() && ((cpu && cpu == get_current_cpu_thread()) || prio == yield_cmd)) { - unqueue(g_pending, cpu); + unqueue(g_pending, get_current_cpu_thread()); } // Suspend threads if necessary diff --git a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp index 5392decd44b6..d16863cb4168 100644 --- a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp @@ -82,7 +82,7 @@ s32 sys_ppu_thread_yield(ppu_thread& ppu) { sys_ppu_thread.trace("sys_ppu_thread_yield()"); - // Return 1 on no-op, 0 on successful context switch + // Return 0 on successful context switch, 1 otherwise return +!lv2_obj::yield(ppu); } diff --git a/rpcs3/Emu/Cell/lv2/sys_sync.h b/rpcs3/Emu/Cell/lv2/sys_sync.h index af245528337c..262a5d4fd654 100644 --- a/rpcs3/Emu/Cell/lv2/sys_sync.h +++ b/rpcs3/Emu/Cell/lv2/sys_sync.h @@ -159,7 +159,7 @@ struct lv2_obj return awake_unlocked(thread, prio); } - // Returns true and success, false if did nothing + // Returns true on successful context switch, false otherwise static bool yield(cpu_thread& thread) { vm::temporary_unlock(thread);