diff --git a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp index 1be4e220bb..8a332d3674 100644 --- a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp @@ -131,9 +131,6 @@ s32 cellFsRead(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr> nread) if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; - if (nbytes != (u32)nbytes) - return CELL_ENOMEM; - // TODO: checks const u64 res = nbytes ? file->Read(buf.get_ptr(), nbytes) : 0; @@ -150,8 +147,6 @@ s32 cellFsWrite(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrite std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; - if (nbytes != (u32)nbytes) return CELL_ENOMEM; - // TODO: checks const u64 res = nbytes ? file->Write(buf.get_ptr(), nbytes) : 0; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp index c7dacd681e..31eb558f9f 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp @@ -174,6 +174,7 @@ s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout) // unlock mutex cond->mutex->owner.reset(); + cond->mutex->cv.notify_one(); // save recursive value const u32 recursive_value = cond->mutex->recursive_count.exchange(0); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp index cbd55b4fc3..4297628b77 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp @@ -65,7 +65,13 @@ s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mod return CELL_ESRCH; } - // lwmutex_id, ppu_thread_id are ignored in current implementation + std::shared_ptr mutex; + if (lwmutex_id && !Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + { + return CELL_ESRCH; + } + + // ppu_thread_id is ignored in current implementation if (mode != 1 && mode != 2 && mode != 3) { @@ -129,7 +135,11 @@ s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode) return CELL_ESRCH; } - // lwmutex_id is ignored in current implementation + std::shared_ptr mutex; + if (lwmutex_id && !Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + { + return CELL_ESRCH; + } if (mode != 1 && mode != 2) { @@ -171,22 +181,39 @@ s32 _sys_lwcond_queue_wait(u32 lwcond_id, u32 lwmutex_id, u64 timeout) return CELL_ESRCH; } - // lwmutex_id, protocol are ignored in current implementation + std::shared_ptr mutex; + if (!Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + { + return CELL_ESRCH; + } + + // finalize unlocking the mutex + mutex->signaled++; + mutex->cv.notify_one(); + + // protocol is ignored in current implementation cond->waiters++; assert(cond->waiters > 0); - while (!cond->signaled1 && !cond->signaled2) + while (!(cond->signaled1 && mutex->signaled) && !cond->signaled2) { const bool is_timedout = timeout && get_system_time() - start_time > timeout; // check timeout (TODO) if (is_timedout) { - sys_lwcond.Fatal("_sys_lwcond_queue_wait(%d): TIMED OUT", lwcond_id); - // cancel waiting cond->waiters--; assert(cond->waiters >= 0); - return CELL_ETIMEDOUT; + if (mutex->signaled) + { + mutex->signaled--; + + return CELL_EDEADLK; + } + else + { + return CELL_ETIMEDOUT; + } } if (Emu.IsStopped()) @@ -200,6 +227,7 @@ s32 _sys_lwcond_queue_wait(u32 lwcond_id, u32 lwmutex_id, u64 timeout) if (cond->signaled1) { + mutex->signaled--; cond->signaled1--; return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h index d64b5348f3..0b1471bc3c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h @@ -82,7 +82,7 @@ struct lwmutex_t : protocol(protocol) , name(name) { - } + } }; // Aux