diff --git a/Utilities/SSemaphore.cpp b/Utilities/SSemaphore.cpp index 37c3cc6faa..fd1aad9fbb 100644 --- a/Utilities/SSemaphore.cpp +++ b/Utilities/SSemaphore.cpp @@ -19,10 +19,7 @@ void SSemaphore::wait() while (true) { - if (Emu.IsStopped()) - { - return; - } + CHECK_EMU_STATUS; m_cond.wait_for(cv_lock, std::chrono::milliseconds(1)); diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index c2e8273140..aa968854e3 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1214,14 +1214,7 @@ thread_t::~thread_t() noexcept(false) { if (m_thread) { - if (g_tls_this_thread != m_thread.get()) - { - m_thread->m_thread.join(); - } - else - { - throw EXCEPTION("Deadlock"); - } + throw EXCEPTION("Neither joined nor detached"); } } diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 09a077b3ec..209d992732 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -84,6 +84,28 @@ public: bool is_current() const; }; +class autojoin_thread_t final : private thread_t +{ +public: + using thread_t::mutex; + using thread_t::cv; + +public: + autojoin_thread_t() = delete; + + autojoin_thread_t(std::function name, std::function func) + { + start(std::move(name), std::move(func)); + } + + virtual ~autojoin_thread_t() override + { + join(); + } + + using thread_t::is_current; +}; + struct waiter_map_t { static const size_t size = 16; diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index b6f33c78d2..846aac7b0b 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -609,10 +609,19 @@ u32 SPUThread::get_ch_value(u32 ch) case SPU_RdEventStat: { + std::unique_lock lock(mutex, std::defer_lock); + u32 result; - while (!(result = ch_event_stat.load() & ch_event_mask) && !Emu.IsStopped()) + + while ((result = ch_event_stat.load() & ch_event_mask) == 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + CHECK_EMU_STATUS; + + if (IsStopped()) throw CPUThreadStop{}; + + if (!lock) lock.lock(); + + cv.wait_for(lock, std::chrono::milliseconds(1)); } return result; diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index c4185b3e80..c3e8e422d8 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -4,6 +4,7 @@ #include "Emu/System.h" #include "Emu/CPU/CPUThread.h" #include "Emu/Cell/PPUThread.h" +#include "Emu/Cell/SPUThread.h" #include "Emu/ARMv7/ARMv7Thread.h" #include "Emu/SysCalls/lv2/sys_time.h" @@ -615,9 +616,7 @@ namespace vm if (context.GPR[1] < context.stack_addr) { - LOG_ERROR(PPU, "vm::stack_push(0x%x,%d): stack overflow (SP=0x%llx, stack=*0x%x)", size, align_v, context.GPR[1], context.stack_addr); - context.GPR[1] = old_pos; - return 0; + throw EXCEPTION("Stack overflow (size=0x%x, align=0x%x, SP=0x%llx, stack=*0x%x)", size, align_v, old_pos, context.stack_addr); } else { @@ -628,8 +627,20 @@ namespace vm case CPU_THREAD_SPU: case CPU_THREAD_RAW_SPU: { - assert(!"stack_push(): SPU not supported"); - return 0; + SPUThread& context = static_cast(CPU); + + old_pos = context.GPR[1]._u32[3]; + context.GPR[1]._u32[3] -= align(size, 16); + context.GPR[1]._u32[3] &= ~(align_v - 1); + + if (context.GPR[1]._u32[3] >= 0x40000) // extremely rough + { + throw EXCEPTION("Stack overflow (size=0x%x, align=0x%x, SP=LS:0x%05x)", size, align_v, old_pos); + } + else + { + return context.GPR[1]._u32[3] + context.offset; + } } case CPU_THREAD_ARMv7: @@ -642,9 +653,7 @@ namespace vm if (context.SP < context.stack_addr) { - LOG_ERROR(ARMv7, "vm::stack_push(0x%x,%d): stack overflow (SP=0x%x, stack=*0x%x)", size, align_v, context.SP, context.stack_addr); - context.SP = old_pos; - return 0; + throw EXCEPTION("Stack overflow (size=0x%x, align=0x%x, SP=0x%x, stack=*0x%x)", size, align_v, context.SP, context.stack_addr); } else { @@ -654,8 +663,7 @@ namespace vm default: { - assert(!"stack_push(): invalid thread type"); - return 0; + throw EXCEPTION("Invalid thread type (%d)", CPU.GetId()); } } } @@ -668,9 +676,9 @@ namespace vm { PPUThread& context = static_cast(CPU); - if (context.GPR[1] != addr && !Emu.IsStopped()) + if (context.GPR[1] != addr) { - LOG_ERROR(PPU, "vm::stack_pop(*0x%x,*0x%x): stack inconsistency (SP=0x%llx)", addr, old_pos, context.GPR[1]); + throw EXCEPTION("Stack inconsistency (addr=0x%x, SP=0x%llx, old_pos=0x%x)", addr, context.GPR[1], old_pos); } context.GPR[1] = old_pos; @@ -680,7 +688,14 @@ namespace vm case CPU_THREAD_SPU: case CPU_THREAD_RAW_SPU: { - assert(!"stack_pop(): SPU not supported"); + SPUThread& context = static_cast(CPU); + + if (context.GPR[1]._u32[3] + context.offset != addr) + { + throw EXCEPTION("Stack inconsistency (addr=0x%x, SP=LS:0x%05x, old_pos=LS:0x%05x)", addr, context.GPR[1]._u32[3], old_pos); + } + + context.GPR[1]._u32[3] = old_pos; return; } @@ -688,9 +703,9 @@ namespace vm { ARMv7Context& context = static_cast(CPU); - if (context.SP != addr && !Emu.IsStopped()) + if (context.SP != addr) { - LOG_ERROR(ARMv7, "vm::stack_pop(*0x%x,*0x%x): stack inconsistency (SP=0x%x)", addr, old_pos, context.SP); + throw EXCEPTION("Stack inconsistency (addr=0x%x, SP=0x%x, old_pos=0x%x)", addr, context.SP, old_pos); } context.SP = old_pos; @@ -699,8 +714,7 @@ namespace vm default: { - assert(!"stack_pop(): invalid thread type"); - return; + throw EXCEPTION("Invalid thread type (%d)", CPU.GetType()); } } } diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index f06ad6836e..10e41e70c7 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2456,14 +2456,16 @@ void RSXThread::Task() m_last_flip_time = get_system_time() - 1000000; - thread_t vblank(WRAP_EXPR("VBlank thread"), [this]() + autojoin_thread_t vblank(WRAP_EXPR("VBlank Thread"), [this]() { const u64 start_time = get_system_time(); m_vblank_count = 0; - while (joinable() && !Emu.IsStopped()) + while (joinable()) { + CHECK_EMU_STATUS; + if (get_system_time() - start_time > m_vblank_count * 1000000 / 60) { m_vblank_count++; @@ -2567,8 +2569,6 @@ void RSXThread::Task() }); } - LOG_NOTICE(RSX, "RSX thread ended"); - OnExitThread(); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index fbf7108a71..aedbe70e6b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -569,11 +569,8 @@ s32 cellAdecClose(u32 handle) while (!adec->is_finished) { - if (Emu.IsStopped()) - { - cellAdec.Warning("cellAdecClose(%d) aborted", handle); - break; - } + CHECK_EMU_STATUS; + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack } diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index ee0be9b527..7329b6413a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -81,7 +81,7 @@ s32 cellAudioInit() squeue_t out_queue; - thread_t iat(WRAP_EXPR("Internal Audio Thread"), [&out_queue]() + autojoin_thread_t iat(WRAP_EXPR("Internal Audio Thread"), [&out_queue]() { const bool use_u16 = Ini.AudioConvertToU16.GetValue(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.h b/rpcs3/Emu/SysCalls/Modules/cellAudio.h index 616a2e4258..ccd79d24ba 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.h @@ -121,7 +121,7 @@ struct AudioPortConfig atomic level_set; }; -struct AudioConfig //custom structure +struct AudioConfig final // custom structure { atomic state; thread_t thread; @@ -135,6 +135,14 @@ struct AudioConfig //custom structure AudioConfig() = default; + ~AudioConfig() + { + if (thread.joinable()) + { + thread.join(); + } + } + u32 open_port() { for (u32 i = 0; i < AUDIO_PORT_COUNT; i++) diff --git a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp index 4a8cd86fd5..9e263fe881 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp @@ -690,15 +690,10 @@ s32 cellFsStReadWait(u32 fd, u64 size) std::unique_lock lock(file->mutex); + // wait for size availability or stream end while (file->st_total_read - file->st_copied < size && file->st_total_read < file->st_read_size) { - // wait for size availability or stream end - - if (Emu.IsStopped()) - { - cellFs.Warning("cellFsStReadWait(0x%x) aborted", fd); - return CELL_OK; - } + CHECK_EMU_STATUS; file->cv.wait_for(lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp index 11841f6025..c16e77d5f5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp @@ -105,7 +105,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr msgString, vm::ptr msgString, vm::ptr spurs) while (true) { - if (Emu.IsStopped()) - { - sys_ppu_thread_exit(CPU, 0); - } + CHECK_EMU_STATUS; if (spurs->handlerExiting.load()) { @@ -518,6 +515,8 @@ void spursHandlerEntry(PPUThread& CPU) while (true) { + CHECK_EMU_STATUS; + if (spurs->flags1 & SF1_EXIT_IF_NO_WORK) { spursHandlerWaitReady(CPU, spurs); @@ -538,14 +537,13 @@ void spursHandlerEntry(PPUThread& CPU) throw EXCEPTION("sys_spu_thread_group_join() failed (0x%x)", rc); } - if (Emu.IsStopped()) - { - continue; - } - if ((spurs->flags1 & SF1_EXIT_IF_NO_WORK) == 0) { - assert(spurs->handlerExiting.load() == 1 || Emu.IsStopped()); + if (spurs->handlerExiting.load() != 1) + { + throw EXCEPTION("Unexpected handlerExiting value (false)"); + } + sys_ppu_thread_exit(CPU, 0); } } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp index c3e4308eea..2bb4690821 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp @@ -530,9 +530,7 @@ bool spursKernelWorkloadExit(SPUThread & spu) { bool spursKernelEntry(SPUThread & spu) { while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); - if (Emu.IsStopped()) { - return false; - } + CHECK_EMU_STATUS; } auto ctxt = vm::get_ptr(spu.offset + 0x100); @@ -676,7 +674,7 @@ void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt) { // If all SPUs are idling and the exit_if_no_work flag is set then the SPU thread group must exit. Otherwise wait for external events. if (spuIdling && shouldExit == false && foundReadyWorkload == false) { // The system service blocks by making a reservation and waiting on the lock line reservation lost event. - if (Emu.IsStopped()) throw SpursModuleExit(); + CHECK_EMU_STATUS; if (!lock) lock.lock(); spu.cv.wait_for(lock, std::chrono::milliseconds(1)); continue; @@ -744,6 +742,7 @@ void spursSysServiceMain(SPUThread & spu, u32 pollStatus) { cellSpursModulePutTrace(&pkt, ctxt->dmaTagId); while (true) { + CHECK_EMU_STATUS; // Process requests for the system service spursSysServiceProcessRequests(spu, ctxt); @@ -784,7 +783,7 @@ poll: cellSpursModulePutTrace(&pkt, ctxt->dmaTagId); spursSysServiceIdleHandler(spu, ctxt); - if (Emu.IsStopped()) return; + CHECK_EMU_STATUS; goto poll; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 9b5a7f604d..0c554d0a1c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -829,10 +829,7 @@ s32 _cellSyncLFQueueGetPushPointer(PPUThread& CPU, vm::ptr queu { while (true) { - if (Emu.IsStopped()) - { - return -1; - } + CHECK_EMU_STATUS; const auto old = queue->push1.load_sync(); auto push = old; @@ -1082,6 +1079,8 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm: while (true) { + CHECK_EMU_STATUS; + s32 res; if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) @@ -1101,12 +1100,6 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm: } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - - if (Emu.IsStopped()) - { - cellSync.Warning("_cellSyncLFQueuePushBody(queue=*0x%x) aborted", queue); - return CELL_OK; - } } const s32 depth = queue->m_depth; @@ -1142,10 +1135,7 @@ s32 _cellSyncLFQueueGetPopPointer(PPUThread& CPU, vm::ptr queue { while (true) { - if (Emu.IsStopped()) - { - return -1; - } + CHECK_EMU_STATUS; const auto old = queue->pop1.load_sync(); auto pop = old; @@ -1395,6 +1385,8 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm:: while (true) { + CHECK_EMU_STATUS; + s32 res; if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) @@ -1414,12 +1406,6 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm:: } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - - if (Emu.IsStopped()) - { - cellSync.Warning("_cellSyncLFQueuePopBody(queue=*0x%x) aborted", queue); - return CELL_OK; - } } const s32 depth = queue->m_depth; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index fd3b2d59bd..19681303cf 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -330,13 +330,9 @@ s32 cellSysutilCheckCallback(PPUThread& CPU) while (Emu.GetCallbackManager().Check(CPU, res)) { - count++; + CHECK_EMU_STATUS; - if (Emu.IsStopped()) - { - cellSysutil.Warning("cellSysutilCheckCallback() aborted"); - return CELL_OK; - } + count++; if (res) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp index b60654b31e..f995f6d6e1 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp @@ -594,11 +594,8 @@ s32 cellVdecClose(u32 handle) while (!vdec->is_finished) { - if (Emu.IsStopped()) - { - cellVdec.Warning("cellVdecClose(%d) aborted", handle); - break; - } + CHECK_EMU_STATUS; + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp index c0eaac84a6..53a987e60e 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp @@ -186,6 +186,8 @@ s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout) while (!cond->mutex->owner.expired() || !cond->signaled || cond->waiters.count(CPU.GetId())) { + CHECK_EMU_STATUS; + const bool is_timedout = timeout && get_system_time() - start_time > timeout; // check timeout @@ -203,12 +205,6 @@ s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout) return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_cond.Warning("sys_cond_wait(id=0x%x) aborted", cond_id); - return CELL_OK; - } - // wait on appropriate condition variable (cond->signaled || is_timedout ? cond->mutex->cv : cond->cv).wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp index 0179e1fa00..ba29f2e567 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp @@ -141,6 +141,8 @@ s32 sys_event_flag_wait(u32 id, u64 bitptn, u32 mode, vm::ptr result, u64 t break; } + CHECK_EMU_STATUS; + if (ef->cancelled) { if (!--ef->cancelled) @@ -157,12 +159,6 @@ s32 sys_event_flag_wait(u32 id, u64 bitptn, u32 mode, vm::ptr result, u64 t return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_event_flag.Warning("sys_event_flag_wait(id=0x%x) aborted", id); - return CELL_OK; - } - ef->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp index 0c9ae4ab42..9c65f3863a 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp @@ -103,8 +103,10 @@ s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u32 intrthread, std::unique_lock cond_lock(tag.handler_mutex); - while (!Emu.IsStopped()) + while (!CPU.IsStopped()) { + CHECK_EMU_STATUS; + // call interrupt handler until int status is clear if (tag.stat.load()) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp index 8892d5ef9e..ed90c0b4a3 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp @@ -180,6 +180,8 @@ s32 _sys_lwcond_queue_wait(PPUThread& CPU, u32 lwcond_id, u32 lwmutex_id, u64 ti while ((!(cond->signaled1 && mutex->signaled) && !cond->signaled2) || cond->waiters.count(CPU.GetId())) { + CHECK_EMU_STATUS; + const bool is_timedout = timeout && get_system_time() - start_time > timeout; // check timeout @@ -210,12 +212,6 @@ s32 _sys_lwcond_queue_wait(PPUThread& CPU, u32 lwcond_id, u32 lwmutex_id, u64 ti } } - if (Emu.IsStopped()) - { - sys_lwcond.Warning("_sys_lwcond_queue_wait(lwcond_id=0x%x) aborted", lwcond_id); - return CELL_OK; - } - (cond->signaled1 ? mutex->cv : cond->cv).wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp index 3aff7e8203..3de015b610 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp @@ -77,18 +77,14 @@ s32 _sys_lwmutex_lock(u32 lwmutex_id, u64 timeout) while (!mutex->signaled) { + CHECK_EMU_STATUS; + if (timeout && get_system_time() - start_time > timeout) { mutex->waiters--; return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_lwmutex.Warning("_sys_lwmutex_lock(lwmutex_id=0x%x) aborted", lwmutex_id); - return CELL_OK; - } - mutex->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp index 32c280a7c1..2780cb5951 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp @@ -119,18 +119,14 @@ s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout) while (!mutex->owner.expired()) { + CHECK_EMU_STATUS; + if (timeout && get_system_time() - start_time > timeout) { mutex->waiters--; return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_mutex.Warning("sys_mutex_lock(mutex_id=0x%x) aborted", mutex_id); - return CELL_OK; - } - mutex->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp index 72e3f983fd..186c943626 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp @@ -36,19 +36,20 @@ s32 sys_process_exit(s32 status) LV2_LOCK; - if (!Emu.IsStopped()) + CHECK_EMU_STATUS; + + sys_process.Success("Process finished"); + + CallAfter([]() { - sys_process.Success("Process finished"); + Emu.Stop(); + }); - CallAfter([]() - { - Emu.Stop(); - }); + while (true) + { + CHECK_EMU_STATUS; - while (!Emu.IsStopped()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp index cac0d33348..efe810e1e5 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp @@ -84,18 +84,14 @@ s32 sys_rwlock_rlock(u32 rw_lock_id, u64 timeout) while (rwlock->writer || rwlock->wwaiters) { + CHECK_EMU_STATUS; + if (timeout && get_system_time() - start_time > timeout) { rwlock->rwaiters--; return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_rwlock.Warning("sys_rwlock_rlock(rw_lock_id=0x%x) aborted", rw_lock_id); - return CELL_OK; - } - rwlock->rcv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } @@ -179,18 +175,14 @@ s32 sys_rwlock_wlock(PPUThread& CPU, u32 rw_lock_id, u64 timeout) while (rwlock->readers || rwlock->writer) { + CHECK_EMU_STATUS; + if (timeout && get_system_time() - start_time > timeout) { rwlock->wwaiters--; return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_rwlock.Warning("sys_rwlock_wlock(rw_lock_id=0x%x) aborted", rw_lock_id); - return CELL_OK; - } - rwlock->wcv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp index b0f6aa72ee..181df21075 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp @@ -91,18 +91,14 @@ s32 sys_semaphore_wait(u32 sem, u64 timeout) while (semaphore->value <= 0) { + CHECK_EMU_STATUS; + if (timeout && get_system_time() - start_time > timeout) { semaphore->waiters--; return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_semaphore.Warning("sys_semaphore_wait(%d) aborted", sem); - return CELL_OK; - } - semaphore->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index 984b2cd5fd..0ae310953a 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -546,11 +546,7 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr cause, vm::ptr status) break; } - if (Emu.IsStopped()) - { - sys_spu.Warning("sys_spu_thread_group_join(id=0x%x) aborted", id); - return CELL_OK; - } + CHECK_EMU_STATUS; group->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp index f75735d025..5a8e54fdfc 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp @@ -60,7 +60,6 @@ lv2_timer_t::lv2_timer_t() lv2_timer_t::~lv2_timer_t() { - thread.cv.notify_one(); thread.join(); } @@ -253,13 +252,9 @@ s32 sys_timer_sleep(u32 sleep_time) while (useconds > (passed = get_system_time() - start_time) + 1000) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + CHECK_EMU_STATUS; - if (Emu.IsStopped()) - { - sys_timer.Warning("sys_timer_sleep(sleep_time=%d) aborted", sleep_time); - return CELL_OK; - } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } if (useconds > passed) @@ -280,13 +275,9 @@ s32 sys_timer_usleep(u64 sleep_time) while (sleep_time > (passed = get_system_time() - start_time) + 1000) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + CHECK_EMU_STATUS; - if (Emu.IsStopped()) - { - sys_timer.Warning("sys_timer_usleep(sleep_time=0x%llx) aborted", sleep_time); - return CELL_OK; - } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } if (sleep_time > passed) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_timer.h b/rpcs3/Emu/SysCalls/lv2/sys_timer.h index 151ef5d0ec..0d5c87e227 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_timer.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_timer.h @@ -19,7 +19,7 @@ struct sys_timer_information_t be_t pad; }; -struct lv2_timer_t +struct lv2_timer_t final { std::weak_ptr port; // event queue u64 source; // event source