diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index abe53fb669..3a591c2998 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1012,10 +1012,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) switch (d_size) { - case 1: reg_value = vm::priv_ref>(addr).exchange((u8)reg_value); break; - case 2: reg_value = vm::priv_ref>(addr).exchange((u16)reg_value); break; - case 4: reg_value = vm::priv_ref>(addr).exchange((u32)reg_value); break; - case 8: reg_value = vm::priv_ref>(addr).exchange((u64)reg_value); break; + case 1: reg_value = vm::priv_ref>(addr).exchange((u8)reg_value); break; + case 2: reg_value = vm::priv_ref>(addr).exchange((u16)reg_value); break; + case 4: reg_value = vm::priv_ref>(addr).exchange((u32)reg_value); break; + case 8: reg_value = vm::priv_ref>(addr).exchange((u64)reg_value); break; default: return false; } @@ -1035,10 +1035,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) switch (d_size) { - case 1: old_value = vm::priv_ref>(addr).compare_and_swap((u8)cmp_value, (u8)reg_value); break; - case 2: old_value = vm::priv_ref>(addr).compare_and_swap((u16)cmp_value, (u16)reg_value); break; - case 4: old_value = vm::priv_ref>(addr).compare_and_swap((u32)cmp_value, (u32)reg_value); break; - case 8: old_value = vm::priv_ref>(addr).compare_and_swap((u64)cmp_value, (u64)reg_value); break; + case 1: old_value = vm::priv_ref>(addr).compare_and_swap((u8)cmp_value, (u8)reg_value); break; + case 2: old_value = vm::priv_ref>(addr).compare_and_swap((u16)cmp_value, (u16)reg_value); break; + case 4: old_value = vm::priv_ref>(addr).compare_and_swap((u32)cmp_value, (u32)reg_value); break; + case 8: old_value = vm::priv_ref>(addr).compare_and_swap((u64)cmp_value, (u64)reg_value); break; default: return false; } @@ -1058,10 +1058,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) switch (d_size) { - case 1: value = vm::priv_ref>(addr) &= static_cast(value); break; - case 2: value = vm::priv_ref>(addr) &= static_cast(value); break; - case 4: value = vm::priv_ref>(addr) &= static_cast(value); break; - case 8: value = vm::priv_ref>(addr) &= value; break; + case 1: value = vm::priv_ref>(addr) &= (u8)value; break; + case 2: value = vm::priv_ref>(addr) &= (u16)value; break; + case 4: value = vm::priv_ref>(addr) &= (u32)value; break; + case 8: value = vm::priv_ref>(addr) &= value; break; default: return false; } diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 23f0fdcdb3..23676853c9 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -13,10 +13,10 @@ class thread_ctrl_t final // name getter const std::function name; - // true if TLS of some thread points to owner + // true if assigned somewhere in TLS std::atomic assigned{ false }; - // assign TLS + // assign TLS (must be assigned only once) void set_current(); public: @@ -174,7 +174,7 @@ class squeue_t }; }; - atomic m_sync; + atomic_t m_sync; mutable std::mutex m_rcv_mutex; mutable std::mutex m_wcv_mutex; diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 6f73550194..4d8ece34af 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -37,6 +37,7 @@ CPUThread::CPUThread(CPUThreadType type, const std::string& name, std::function< } catch (CPUThreadReturn) { + ; } catch (CPUThreadStop) { @@ -47,12 +48,21 @@ CPUThread::CPUThread(CPUThreadType type, const std::string& name, std::function< m_state |= CPU_STATE_DEAD; break; } + catch (const fmt::exception&) + { + DumpInformation(); + throw; + } m_state &= ~CPU_STATE_RETURN; continue; } - if (!lock) lock.lock(); + if (!lock) + { + lock.lock(); + continue; + } cv.wait(lock); } diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index 962405187d..9917a723ae 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -38,7 +38,7 @@ class CPUDecoder; class CPUThread : protected thread_t, public std::enable_shared_from_this { protected: - atomic m_state; // thread state flags + atomic_t m_state; // thread state flags std::unique_ptr m_dec; diff --git a/rpcs3/Emu/CPU/CPUThreadManager.cpp b/rpcs3/Emu/CPU/CPUThreadManager.cpp index 1ef6cc3682..c6d902c530 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.cpp +++ b/rpcs3/Emu/CPU/CPUThreadManager.cpp @@ -28,43 +28,43 @@ void CPUThreadManager::Close() } } -std::vector> CPUThreadManager::GetAllThreads() const +std::vector> CPUThreadManager::GetAllThreads() { std::vector> result; - for (auto& v : Emu.GetIdManager().get_data()) + for (auto& t : Emu.GetIdManager().get_all()) { - result.emplace_back(std::static_pointer_cast(v.data)); + result.emplace_back(t); } - for (auto& v : Emu.GetIdManager().get_data()) + for (auto& t : Emu.GetIdManager().get_all()) { - result.emplace_back(std::static_pointer_cast(v.data)); + result.emplace_back(t); } - for (auto& v : Emu.GetIdManager().get_data()) + for (auto& t : Emu.GetIdManager().get_all()) { - result.emplace_back(std::static_pointer_cast(v.data)); + result.emplace_back(t); } - for (auto& v : Emu.GetIdManager().get_data()) + for (auto& t : Emu.GetIdManager().get_all()) { - result.emplace_back(std::static_pointer_cast(v.data)); + result.emplace_back(t); } return result; } -void CPUThreadManager::Exec() const +void CPUThreadManager::Exec() { - for (auto& v : Emu.GetIdManager().get_data()) + for (auto& t : Emu.GetIdManager().get_all()) { - static_cast(v.data.get())->Exec(); + t->Exec(); } - for (auto& v : Emu.GetIdManager().get_data()) + for (auto& t : Emu.GetIdManager().get_all()) { - static_cast(v.data.get())->Exec(); + t->Exec(); } } diff --git a/rpcs3/Emu/CPU/CPUThreadManager.h b/rpcs3/Emu/CPU/CPUThreadManager.h index c6f2e7ed7c..5fa772e971 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.h +++ b/rpcs3/Emu/CPU/CPUThreadManager.h @@ -15,9 +15,9 @@ public: void Close(); - std::vector> GetAllThreads() const; + static std::vector> GetAllThreads(); - void Exec() const; + static void Exec(); std::shared_ptr NewRawSPUThread(); diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 4c8afdf890..9b050946e0 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -507,10 +507,9 @@ void PPUThread::DumpInformation() const { if (~hle_code < 1024) { - LOG_SUCCESS(HLE, "Last function: syscall %lld (%s)", ~hle_code, SysCalls::GetFuncName(hle_code)); + LOG_SUCCESS(HLE, "Last syscall: %lld (%s)", ~hle_code, SysCalls::GetFuncName(hle_code)); } - - if (hle_code > 0) + else if (hle_code) { LOG_SUCCESS(HLE, "Last function: %s (0x%llx)", SysCalls::GetFuncName(hle_code), hle_code); } diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 106d09d36b..ecc3ccf31e 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -137,7 +137,7 @@ union spu_channel_t u32 value; }; - atomic sync_var; // atomic variable + atomic_t sync_var; // atomic variable public: bool try_push(u32 value) @@ -223,8 +223,8 @@ struct spu_channel_4_t u32 value2; }; - atomic sync_var; - atomic value3; + atomic_t sync_var; + atomic_t value3; public: void clear() @@ -280,10 +280,10 @@ public: struct spu_interrupt_tag_t { - atomic mask; - atomic stat; + atomic_t mask; + atomic_t stat; - atomic assigned; + atomic_t assigned; std::mutex handler_mutex; std::condition_variable cond; @@ -526,14 +526,14 @@ public: spu_channel_t ch_snr2; // SPU Signal Notification Register 2 u32 ch_event_mask; - atomic ch_event_stat; + atomic_t ch_event_stat; u64 ch_dec_start_timestamp; // timestamp of writing decrementer value u32 ch_dec_value; // written decrementer value - atomic run_ctrl; // SPU Run Control register (only provided to get latest data written) - atomic status; // SPU Status register - atomic npc; // SPU Next Program Counter register + atomic_t run_ctrl; // SPU Run Control register (only provided to get latest data written) + atomic_t status; // SPU Status register + atomic_t npc; // SPU Next Program Counter register spu_interrupt_tag_t int0; // SPU Class 0 Interrupt Management spu_interrupt_tag_t int2; // SPU Class 2 Interrupt Management diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index fba1d03252..aec7469f8f 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -20,13 +20,13 @@ class ID_data_t final { public: const std::shared_ptr data; - const std::type_info& info; + const std::size_t info; const u32 type; const u32 id; template force_inline ID_data_t(std::shared_ptr data, u32 type, u32 id) : data(std::move(data)) - , info(typeid(T)) + , info(typeid(T).hash_code()) , type(type) , id(id) { @@ -62,13 +62,23 @@ class ID_manager public: // check if ID exists and has specified type - template bool check_id(const u32 id) + template bool check_id(u32 id) { std::lock_guard lock(m_mutex); auto f = m_id_map.find(id); - return f != m_id_map.end() && f->second.info == typeid(T); + return f != m_id_map.end() && f->second.info == typeid(T).hash_code(); + } + + // check if ID exists and has specified type + bool check_id(u32 id, u32 type) + { + std::lock_guard lock(m_mutex); + + auto f = m_id_map.find(id); + + return f != m_id_map.end() && f->second.type == type; } // must be called from the constructor called through make() to get further ID of current object @@ -122,14 +132,14 @@ public: return m_cur_id++; } - // load ID created with type Original, optionally static_cast to T + // load ID created with type Orig, optionally static_cast to T template auto get(u32 id) -> decltype(std::shared_ptr(static_cast(std::declval()))) { std::lock_guard lock(m_mutex); auto f = m_id_map.find(id); - if (f == m_id_map.end() || f->second.info != typeid(Orig)) + if (f == m_id_map.end() || f->second.info != typeid(Orig).hash_code()) { return nullptr; } @@ -137,13 +147,33 @@ public: return std::static_pointer_cast(f->second.data); } + // load all IDs created with type Orig, optionally static_cast to T + template auto get_all() -> std::vector(static_cast(std::declval())))> + { + std::lock_guard lock(m_mutex); + + std::vector> result; + + const std::size_t hash = typeid(Orig).hash_code(); + + for (auto& v : m_id_map) + { + if (v.second.info == hash) + { + result.emplace_back(std::static_pointer_cast(v.second.data)); + } + } + + return result; + } + template bool remove(u32 id) { std::lock_guard lock(m_mutex); auto item = m_id_map.find(id); - if (item == m_id_map.end() || item->second.info != typeid(T)) + if (item == m_id_map.end() || item->second.info != typeid(T).hash_code()) { return false; } @@ -159,9 +189,11 @@ public: u32 result = 0; + const std::size_t hash = typeid(T).hash_code(); + for (auto& v : m_id_map) { - if (v.second.info == typeid(T)) + if (v.second.info == hash) { result++; } @@ -187,15 +219,18 @@ public: return result; } + // get sorted ID list template std::set get_IDs() { std::lock_guard lock(m_mutex); std::set result; + const std::size_t hash = typeid(T).hash_code(); + for (auto& v : m_id_map) { - if (v.second.info == typeid(T)) + if (v.second.info == hash) { result.insert(v.first); } @@ -204,6 +239,7 @@ public: return result; } + // get sorted ID list std::set get_IDs(u32 type) { std::lock_guard lock(m_mutex); @@ -227,9 +263,11 @@ public: std::vector result; + const std::size_t hash = typeid(T).hash_code(); + for (auto& v : m_id_map) { - if (v.second.info == typeid(T)) + if (v.second.info == hash) { result.emplace_back(v.second); } diff --git a/rpcs3/Emu/Memory/atomic.h b/rpcs3/Emu/Memory/atomic.h index e5cc022962..385a3477db 100644 --- a/rpcs3/Emu/Memory/atomic.h +++ b/rpcs3/Emu/Memory/atomic.h @@ -318,7 +318,7 @@ template> inline auto opera }); } -template using atomic = _atomic_base; // Atomic Type with native endianness (for emulator memory) +template using atomic_t = _atomic_base; // Atomic Type with native endianness (for emulator memory) template using atomic_be_t = _atomic_base>; // Atomic BE Type (for PS3 virtual memory) diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 9e7876907b..d1e11c1562 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -74,11 +74,11 @@ namespace vm void* g_base_addr = (atexit(finalize), initialize()); void* g_priv_addr; - std::array, 0x100000000ull / 4096> g_page_info = {}; // information about every page + std::array, 0x100000000ull / 4096> g_page_info = {}; // information about every page class reservation_mutex_t { - atomic m_owner{}; + atomic_t m_owner{}; std::condition_variable m_cv; std::mutex m_mutex; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.h b/rpcs3/Emu/SysCalls/Modules/cellAudio.h index ccd79d24ba..6b8c3d12ce 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.h @@ -100,7 +100,7 @@ enum AudioPortState : u32 struct AudioPortConfig { std::mutex mutex; - atomic state; + atomic_t state; u32 channel; u32 block; @@ -118,12 +118,12 @@ struct AudioPortConfig }; float level; - atomic level_set; + atomic_t level_set; }; struct AudioConfig final // custom structure { - atomic state; + atomic_t state; thread_t thread; AudioPortConfig ports[AUDIO_PORT_COUNT]; diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 9bf9554bcf..b296075c74 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -34,14 +34,19 @@ #include "SysCalls.h" -void null_func(PPUThread& CPU); +void null_func(PPUThread& ppu) +{ + const auto code = ppu.GPR[11]; + LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", code, SysCalls::GetFuncName(~code)); + ppu.GPR[3] = 0; +} // UNS = Unused // ROOT = Root // DBG = Debug // PM = Product Mode // AuthID = Authentication ID -const ppu_func_caller sc_table[1024] = +const ppu_func_caller g_sc_table[1024] = { null_func, bind_func(sys_process_getpid), //1 (0x001) @@ -886,13 +891,6 @@ const ppu_func_caller sc_table[1024] = null_func, null_func, null_func, bind_func(cellGcmCallback), //1023 UNS }; -void null_func(PPUThread& CPU) -{ - const auto code = CPU.GPR[11]; - LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", code, SysCalls::GetFuncName(~code)); - CPU.GPR[3] = 0; -} - void SysCalls::DoSyscall(PPUThread& CPU, u64 code) { if (code >= 1024) @@ -908,7 +906,7 @@ void SysCalls::DoSyscall(PPUThread& CPU, u64 code) LOG_NOTICE(PPU, "Syscall %lld called: %s", code, SysCalls::GetFuncName(~code)); } - sc_table[code](CPU); + g_sc_table[code](CPU); if (Ini.HLELogging.GetValue()) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp index 19c8eb6ad8..142bfcc88c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp @@ -87,14 +87,6 @@ s32 sys_cond_signal(u32 cond_id) // signal one waiting thread; protocol is ignored in current implementation if (thread->Signal()) { - cond->sent++; - - if (!cond->mutex->owner) - { - // set the appropriate mutex owner if free; protocol is ignored in current implementation - cond->mutex->owner = thread; - } - return CELL_OK; } } @@ -120,13 +112,7 @@ s32 sys_cond_signal_all(u32 cond_id) // signal all waiting threads; protocol is ignored in current implementation if (thread->Signal()) { - cond->sent++; - - if (!cond->mutex->owner) - { - // set the appropriate mutex owner if free; protocol is ignored in current implementation - cond->mutex->owner = thread; - } + ; } } @@ -153,14 +139,6 @@ s32 sys_cond_signal_to(u32 cond_id, u32 thread_id) // signal specified thread if (thread->GetId() == thread_id && thread->Signal()) { - cond->sent++; - - if (!cond->mutex->owner) - { - // set the appropriate mutex owner if free; protocol is ignored in current implementation - cond->mutex->owner = thread; - } - return CELL_OK; } } @@ -228,8 +206,6 @@ s32 sys_cond_wait(PPUThread& ppu, u32 cond_id, u64 timeout) CHECK_EMU_STATUS; } - - cond->recv++; } // reown the mutex (could be set when notified) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.h b/rpcs3/Emu/SysCalls/lv2/sys_cond.h index 7d3ff6cb1b..6fbe55e7f2 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.h @@ -26,9 +26,6 @@ struct lv2_cond_t sleep_queue_t sq; - std::atomic sent{ 0 }; - std::atomic recv{ 0 }; - lv2_cond_t(const std::shared_ptr& mutex, u64 name) : mutex(mutex) , name(name) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.h b/rpcs3/Emu/SysCalls/lv2/sys_fs.h index 9af6417019..8d282f13e6 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.h @@ -177,7 +177,7 @@ struct lv2_file_t std::mutex mutex; std::condition_variable cv; - atomic st_status; + atomic_t st_status; u64 st_ringbuf_size; u64 st_block_size; @@ -191,7 +191,7 @@ struct lv2_file_t std::atomic st_total_read; std::atomic st_copied; - atomic st_callback; + atomic_t st_callback; lv2_file_t(std::shared_ptr file, s32 mode, s32 flags) : file(std::move(file)) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp index 9c65f3863a..6792fcbc30 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp @@ -98,10 +98,10 @@ s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u32 intrthread, it->custom_task = [thread, &tag, arg](PPUThread& CPU) { - const auto pc = CPU.PC; - const auto rtoc = CPU.GPR[2]; + const u32 pc = CPU.PC; + const u32 rtoc = CPU.GPR[2]; - std::unique_lock cond_lock(tag.handler_mutex); + std::unique_lock lock(tag.handler_mutex); while (!CPU.IsStopped()) { @@ -114,7 +114,7 @@ s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u32 intrthread, CPU.FastCall2(pc, rtoc); } - tag.cond.wait_for(cond_lock, std::chrono::milliseconds(1)); + tag.cond.wait_for(lock, std::chrono::milliseconds(1)); } }; } @@ -149,7 +149,7 @@ void sys_interrupt_thread_eoi(PPUThread& CPU) // TODO: maybe it should actually unwind the stack of PPU thread? - CPU.GPR[1] = align(CPU.stack_addr + CPU.stack_size, 0x200) - 0x200; // supercrutch to avoid stack check + CPU.GPR[1] = align(CPU.stack_addr + CPU.stack_size, 0x200) - 0x200; // supercrutch to bypass stack check CPU.FastStop(); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp index e83e508df1..d2908bfa76 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp @@ -11,6 +11,24 @@ SysCallBase sys_mutex("sys_mutex"); extern u64 get_system_time(); +void lv2_mutex_t::unlock(lv2_lock_type& lv2_lock) +{ + CHECK_LV2_LOCK(lv2_lock); + + owner.reset(); + + if (sq.size()) + { + // pick new owner; protocol is ignored in current implementation + owner = sq.front(); + + if (!owner->Signal()) + { + throw EXCEPTION("Mutex owner not signaled"); + } + } +} + s32 sys_mutex_create(vm::ptr mutex_id, vm::ptr attr) { sys_mutex.Warning("sys_mutex_create(mutex_id=*0x%x, attr=*0x%x)", mutex_id, attr); @@ -217,19 +235,7 @@ s32 sys_mutex_unlock(PPUThread& ppu, u32 mutex_id) } else { - // free the mutex - mutex->owner.reset(); - - if (mutex->sq.size()) - { - // pick another owner; protocol is ignored in current implementation - mutex->owner = mutex->sq.front(); - - if (!mutex->owner->Signal()) - { - throw EXCEPTION("Mutex owner not signaled"); - } - } + mutex->unlock(lv2_lock); } return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.h b/rpcs3/Emu/SysCalls/lv2/sys_mutex.h index d465edb172..d1d7449102 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.h @@ -39,6 +39,8 @@ struct lv2_mutex_t , name(name) { } + + void unlock(lv2_lock_type& lv2_lock); }; REG_ID_TYPE(lv2_mutex_t, 0x85); // SYS_MUTEX_OBJECT diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp index 2dde9da9ec..5506df3ad3 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp @@ -18,23 +18,17 @@ void _sys_ppu_thread_exit(PPUThread& ppu, u64 errorcode) LV2_LOCK; // get all sys_mutex objects - for (auto& _id : Emu.GetIdManager().get_data()) + for (auto& mutex : Emu.GetIdManager().get_all()) { - const auto mutex = std::static_pointer_cast(_id.data); - // unlock mutex if locked by this thread if (mutex->owner.get() == &ppu) { - mutex->owner.reset(); - - if (mutex->sq.size()) - { - mutex->owner = mutex->sq.front(); - mutex->owner->Signal(); - } + mutex->unlock(lv2_lock); } } + const auto thread = ppu.shared_from_this(); + if (!ppu.is_joinable) { const u32 id = ppu.GetId(); @@ -260,8 +254,8 @@ s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr p return CELL_EINVAL; } - const bool is_joinable = flags & SYS_PPU_THREAD_CREATE_JOINABLE; - const bool is_interrupt = flags & SYS_PPU_THREAD_CREATE_INTERRUPT; + const bool is_joinable = (flags & SYS_PPU_THREAD_CREATE_JOINABLE) != 0; + const bool is_interrupt = (flags & SYS_PPU_THREAD_CREATE_INTERRUPT) != 0; if (is_joinable && is_interrupt) { diff --git a/rpcs3/Gui/KernelExplorer.cpp b/rpcs3/Gui/KernelExplorer.cpp index f976d47f0b..6351713025 100644 --- a/rpcs3/Gui/KernelExplorer.cpp +++ b/rpcs3/Gui/KernelExplorer.cpp @@ -4,8 +4,9 @@ #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/CPU/CPUThreadManager.h" -#include "Emu/CPU/CPUThread.h" +#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" @@ -81,6 +82,7 @@ void KernelExplorer::Update() { sprintf(name, "Semaphores (%d)", count); const auto& node = m_tree->AppendItem(root, name); + for (const auto id : Emu.GetIdManager().get_IDs(SYS_SEMAPHORE_OBJECT)) { const auto sem = Emu.GetIdManager().get(id); @@ -94,6 +96,7 @@ void KernelExplorer::Update() { sprintf(name, "Mutexes (%d)", count); const auto& node = m_tree->AppendItem(root, name); + for (const auto id : Emu.GetIdManager().get_IDs(SYS_MUTEX_OBJECT)) { const auto mutex = Emu.GetIdManager().get(id); @@ -107,6 +110,7 @@ void KernelExplorer::Update() { sprintf(name, "Lightweight Mutexes (%d)", count); const auto& node = m_tree->AppendItem(root, name); + for (const auto id : Emu.GetIdManager().get_IDs(SYS_LWMUTEX_OBJECT)) { const auto lwm = Emu.GetIdManager().get(id); @@ -120,6 +124,7 @@ void KernelExplorer::Update() { sprintf(name, "Condition Variables (%d)", count); const auto& node = m_tree->AppendItem(root, name); + for (const auto id : Emu.GetIdManager().get_IDs(SYS_COND_OBJECT)) { const auto cond = Emu.GetIdManager().get(id); @@ -133,6 +138,7 @@ void KernelExplorer::Update() { sprintf(name, "Lightweight Condition Variables (%d)", count); const auto& node = m_tree->AppendItem(root, name); + for (const auto id : Emu.GetIdManager().get_IDs(SYS_LWCOND_OBJECT)) { const auto lwc = Emu.GetIdManager().get(id); @@ -146,6 +152,7 @@ void KernelExplorer::Update() { sprintf(name, "Event Queues (%d)", count); const auto& node = m_tree->AppendItem(root, name); + for (const auto id : Emu.GetIdManager().get_IDs(SYS_EVENT_QUEUE_OBJECT)) { const auto queue = Emu.GetIdManager().get(id); @@ -159,6 +166,7 @@ void KernelExplorer::Update() { sprintf(name, "Event Ports (%d)", count); const auto& node = m_tree->AppendItem(root, name); + for (const auto id : Emu.GetIdManager().get_IDs(SYS_EVENT_PORT_OBJECT)) { const auto port = Emu.GetIdManager().get(id); @@ -174,6 +182,7 @@ void KernelExplorer::Update() const auto& node = m_tree->AppendItem(root, name); //sprintf(name, "Segment List (%l)", 2 * objects.size()); // TODO: Assuming 2 segments per PRX file is not good //m_tree->AppendItem(node, name); + for (const auto& id : Emu.GetIdManager().get_IDs(SYS_PRX_OBJECT)) { sprintf(name, "PRX: ID = 0x%x", id); @@ -186,6 +195,7 @@ void KernelExplorer::Update() { sprintf(name, "Memory Containers (%d)", count); const auto& node = m_tree->AppendItem(root, name); + for (const auto& id : Emu.GetIdManager().get_IDs(SYS_MEM_OBJECT)) { sprintf(name, "Memory Container: ID = 0x%x", id); @@ -198,6 +208,7 @@ void KernelExplorer::Update() { sprintf(name, "Event Flags (%d)", count); const auto& node = m_tree->AppendItem(root, name); + for (const auto& id : Emu.GetIdManager().get_IDs(SYS_EVENT_FLAG_OBJECT)) { sprintf(name, "Event Flag: ID = 0x%x", id); @@ -205,71 +216,47 @@ void KernelExplorer::Update() } } - // PPU / SPU / RawSPU threads + // PPU Threads + if (u32 count = Emu.GetIdManager().get_count()) { - // TODO: add mutexes owners + sprintf(name, "PPU Threads (%d)", count); + const auto& node = m_tree->AppendItem(root, name); - //const auto& objects = Emu.GetCPU().GetThreads(); - u32 ppu_threads_count = 0; - u32 spu_threads_count = 0; - u32 raw_spu_threads_count = 0; - //for (const auto& thread : objects) - //{ - // if (thread->GetType() == CPU_THREAD_PPU) - // ppu_threads_count++; + for (const auto& thread : Emu.GetIdManager().get_all()) + { + sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString()); + m_tree->AppendItem(node, name); + } + } - // if (thread->GetType() == CPU_THREAD_SPU) - // spu_threads_count++; + if (u32 count = Emu.GetIdManager().get_count()) + { + sprintf(name, "SPU Threads (%d)", count); + const auto& node = m_tree->AppendItem(root, name); - // if (thread->GetType() == CPU_THREAD_RAW_SPU) - // raw_spu_threads_count++; - //} + for (const auto& thread : Emu.GetIdManager().get_all()) + { + if (thread->GetType() == CPU_THREAD_SPU) + { + sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString()); + m_tree->AppendItem(node, name); + } + } + } - //if (ppu_threads_count) - //{ - // sprintf(name, "PPU Threads (%d)", ppu_threads_count); - // const auto& node = m_tree->AppendItem(root, name); - - // for (const auto& thread : objects) - // { - // if (thread->GetType() == CPU_THREAD_PPU) - // { - // sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString().c_str()); - // m_tree->AppendItem(node, name); - // } - // } - //} - - //if (spu_threads_count) - //{ - // sprintf(name, "SPU Threads (%d)", spu_threads_count); - // const auto& node = m_tree->AppendItem(root, name); - - // for (const auto& thread : objects) - // { - // if (thread->GetType() == CPU_THREAD_SPU) - // { - // sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString().c_str()); - // m_tree->AppendItem(node, name); - // } - // } - //} - - //if (raw_spu_threads_count) - //{ - // sprintf(name, "RawSPU Threads (%d)", raw_spu_threads_count); - // const auto& node = m_tree->AppendItem(root, name); - - // for (const auto& thread : objects) - // { - // if (thread->GetType() == CPU_THREAD_RAW_SPU) - // { - // sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString().c_str()); - // m_tree->AppendItem(node, name); - // } - // } - //} + if (u32 count = Emu.GetIdManager().get_count()) + { + sprintf(name, "RawSPU Threads (%d)", count); + const auto& node = m_tree->AppendItem(root, name); + for (const auto& thread : Emu.GetIdManager().get_all()) + { + if (thread->GetType() == CPU_THREAD_RAW_SPU) + { + sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString()); + m_tree->AppendItem(node, name); + } + } } m_tree->Expand(root); diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 4fc8cfee4d..d6882a71c3 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -424,7 +424,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) wxCheckBox* chbox_gs_3dmonitor = new wxCheckBox(p_graphics, wxID_ANY, "3D Monitor"); wxCheckBox* chbox_audio_dump = new wxCheckBox(p_audio, wxID_ANY, "Dump to file"); wxCheckBox* chbox_audio_conv = new wxCheckBox(p_audio, wxID_ANY, "Convert to 16 bit"); - wxCheckBox* chbox_hle_logging = new wxCheckBox(p_hle, wxID_ANY, "Log all SysCalls"); + wxCheckBox* chbox_hle_logging = new wxCheckBox(p_hle, wxID_ANY, "Log everything"); wxCheckBox* chbox_rsx_logging = new wxCheckBox(p_hle, wxID_ANY, "RSX Logging"); wxCheckBox* chbox_hle_hook_stfunc = new wxCheckBox(p_hle, wxID_ANY, "Hook static functions"); wxCheckBox* chbox_hle_savetty = new wxCheckBox(p_hle, wxID_ANY, "Save TTY output to file");