From e94ea409feb74a91041b7d52724174cd82d4be66 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 14 Feb 2014 15:40:41 +0400 Subject: [PATCH 1/5] sys_lwcond, sys_mutex, sys_cond rewritten Some bugs fixed --- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 1 - rpcs3/Emu/SysCalls/Modules/cellResc.cpp | 2 +- rpcs3/Emu/SysCalls/SysCalls.cpp | 2 +- rpcs3/Emu/SysCalls/SysCalls.h | 2 +- rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp | 159 ++++++++++++----- rpcs3/Emu/SysCalls/lv2/SC_Condition.h | 13 +- rpcs3/Emu/SysCalls/lv2/SC_Event.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp | 212 ++++++++++++++++------- rpcs3/Emu/SysCalls/lv2/SC_Lwcond.h | 104 ----------- rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp | 36 +++- rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h | 29 +--- rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp | 198 +++++++++++++++------ rpcs3/Emu/SysCalls/lv2/SC_Mutex.h | 41 +++-- rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp | 3 +- 14 files changed, 489 insertions(+), 315 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 0e4e45186a..e8a886f930 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -449,7 +449,6 @@ int cellAudioSetNotifyEventQueue(u64 key) return CELL_AUDIO_ERROR_PARAM; } - eq->events.push(0, 0, 0, 0); eq->events.push(0, 0, 0, 0); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index 24c8971206..cfa5459a24 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -725,7 +725,7 @@ int cellRescSetBufferAddress(mem32_t colorBuffers, mem32_t vertexArray, mem32_t if(!s_rescInternalInstance->m_bInitialized) return CELL_RESC_ERROR_NOT_INITIALIZED; - if(!colorBuffers.GetAddr() || !vertexArray.GetAddr() || !fragmentShader.GetAddr()) + if(!colorBuffers.IsGood() || !vertexArray.IsGood() || !fragmentShader.IsGood()) return CELL_RESC_ERROR_BAD_ARGUMENT; if(colorBuffers.GetAddr() % COLOR_BUFFER_ALIGNMENT || vertexArray.GetAddr() % VERTEX_BUFFER_ALIGNMENT || diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 2e726d19f7..5b24a0e199 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -74,7 +74,7 @@ static func_caller* sc_table[1024] = bind_func(sys_cond_wait), //107 (0x06B) bind_func(sys_cond_signal), //108 (0x06C) bind_func(sys_cond_signal_all), //109 (0x06D) - null_func, null_func, null_func, null_func, //113 (0x071) + bind_func(sys_cond_signal_to), null_func, null_func, null_func, //113 (0x071) bind_func(sys_semaphore_get_value), //114 (0x072) null_func, null_func, null_func, bind_func(sys_event_flag_clear), null_func, //119 (0x077) bind_func(sys_rwlock_create), //120 (0x078) diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 08e75a648f..218fb482df 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -179,7 +179,7 @@ extern int sys_cond_signal_all(u32 cond_id); extern int sys_cond_signal_to(u32 cond_id, u32 thread_id); //sys_mutex -extern int sys_mutex_create(u32 mutex_id_addr, u32 attr_addr); +extern int sys_mutex_create(mem32_t mutex_id, mem_ptr_t attr); extern int sys_mutex_destroy(u32 mutex_id); extern int sys_mutex_lock(u32 mutex_id, u64 timeout); extern int sys_mutex_trylock(u32 mutex_id); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp index e8772e1970..a8af86c9e1 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp @@ -1,6 +1,5 @@ #include "stdafx.h" #include "Emu/SysCalls/SysCalls.h" -#include "SC_Mutex.h" #include "Emu/SysCalls/lv2/SC_Condition.h" SysCallBase sys_cond("sys_cond"); @@ -21,13 +20,16 @@ int sys_cond_create(mem32_t cond_id, u32 mutex_id, mem_ptr_t return CELL_EINVAL; } - mutex* mtx_data; - if (!Emu.GetIdManager().GetIDData(mutex_id, mtx_data)) + Mutex* mutex; + if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) { return CELL_ESRCH; } - cond_id = sys_cond.GetNewId(new condition(mtx_data->mtx, attr->name_u64)); + Cond* cond = new Cond(mutex, attr->name_u64); + u32 id = sys_cond.GetNewId(cond); + cond_id = id; + mutex->cond_count++; sys_cond.Warning("*** condition created [%s]: id = %d", wxString(attr->name, 8).wx_str(), cond_id.GetValue()); return CELL_OK; @@ -35,88 +37,165 @@ int sys_cond_create(mem32_t cond_id, u32 mutex_id, mem_ptr_t int sys_cond_destroy(u32 cond_id) { - sys_cond.Error("sys_cond_destroy(cond_id=%d)", cond_id); + sys_cond.Warning("sys_cond_destroy(cond_id=%d)", cond_id); - condition* cond; + Cond* cond; if (!Emu.GetIdManager().GetIDData(cond_id, cond)) { return CELL_ESRCH; } - if (true) // TODO + if (!cond->m_queue.finalize()) { return CELL_EBUSY; } + cond->mutex->cond_count--; Emu.GetIdManager().RemoveID(cond_id); return CELL_OK; } int sys_cond_wait(u32 cond_id, u64 timeout) { - sys_cond.Warning("sys_cond_wait(cond_id=%d, timeout=%lld)", cond_id, timeout); + sys_cond.Log("sys_cond_wait(cond_id=%d, timeout=%lld)", cond_id, timeout); - condition* cond_data = nullptr; - if(!sys_cond.CheckId(cond_id, cond_data)) return CELL_ESRCH; + Cond* cond; + if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + { + return CELL_ESRCH; + } + + Mutex* mutex = cond->mutex; + u32 tid = GetCurrentPPUThread().GetId(); + + if (mutex->m_mutex.GetOwner() != tid) + { + return CELL_EPERM; + } + + cond->m_queue.push(tid); + + mutex->m_mutex.unlock(tid); u32 counter = 0; - const u32 max_counter = timeout ? (timeout / 1000) : 20000; - do + const u32 max_counter = timeout ? (timeout / 1000) : ~0; + + while (true) { - if (Emu.IsStopped()) + /* switch (mutex->m_mutex.trylock(tid)) { - ConLog.Warning("sys_cond_wait(cond_id=%d, ...) aborted", cond_id); - return CELL_ETIMEDOUT; + case SMR_OK: mutex->m_mutex.unlock(tid); break; + case SMR_SIGNAL: return CELL_OK; + } */ + if (mutex->m_mutex.GetOwner() == tid) + { + _mm_mfence(); + return CELL_OK; } - switch (cond_data->cond.WaitTimeout(1)) - { - case wxCOND_NO_ERROR: return CELL_OK; - case wxCOND_TIMEOUT: break; - default: return CELL_EPERM; - } + Sleep(1); if (counter++ > max_counter) { - if (!timeout) - { - counter = 0; - } - else - { - return CELL_ETIMEDOUT; - } - } - } while (true); + cond->m_queue.invalidate(tid); + return CELL_ETIMEDOUT; + } + if (Emu.IsStopped()) + { + ConLog.Warning("sys_cond_wait(id=%d) aborted", cond_id); + return CELL_OK; + } + } } int sys_cond_signal(u32 cond_id) { - sys_cond.Warning("sys_cond_signal(cond_id=%d)", cond_id); + sys_cond.Log("sys_cond_signal(cond_id=%d)", cond_id); - condition* cond_data = nullptr; - if(!sys_cond.CheckId(cond_id, cond_data)) return CELL_ESRCH; + Cond* cond; + if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + { + return CELL_ESRCH; + } - cond_data->cond.Signal(); + Mutex* mutex = cond->mutex; + u32 tid = GetCurrentPPUThread().GetId(); + + if (u32 target = mutex->protocol == SYS_SYNC_PRIORITY ? mutex->m_queue.pop_prio() : mutex->m_queue.pop()) + { + if (mutex->m_mutex.trylock(target) != SMR_OK) + { + mutex->m_mutex.lock(tid); + mutex->m_mutex.unlock(tid, target); + } + } + + if (Emu.IsStopped()) + { + ConLog.Warning("sys_cond_signal(id=%d) aborted", cond_id); + } return CELL_OK; } int sys_cond_signal_all(u32 cond_id) { - sys_cond.Warning("sys_cond_signal_all(cond_id=%d)", cond_id); + sys_cond.Log("sys_cond_signal_all(cond_id=%d)", cond_id); - condition* cond_data = nullptr; - if(!sys_cond.CheckId(cond_id, cond_data)) return CELL_ESRCH; + Cond* cond; + if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + { + return CELL_ESRCH; + } - cond_data->cond.Broadcast(); + Mutex* mutex = cond->mutex; + u32 tid = GetCurrentPPUThread().GetId(); + + while (u32 target = mutex->protocol == SYS_SYNC_PRIORITY ? mutex->m_queue.pop_prio() : mutex->m_queue.pop()) + { + if (mutex->m_mutex.trylock(target) != SMR_OK) + { + mutex->m_mutex.lock(tid); + mutex->m_mutex.unlock(tid, target); + } + } + + if (Emu.IsStopped()) + { + ConLog.Warning("sys_cond_signal_all(id=%d) aborted", cond_id); + } return CELL_OK; } int sys_cond_signal_to(u32 cond_id, u32 thread_id) { - sys_cond.Error("sys_cond_signal_to(cond_id=%d, thread_id=%d)", cond_id, thread_id); + sys_cond.Log("sys_cond_signal_to(cond_id=%d, thread_id=%d)", cond_id, thread_id); + + Cond* cond; + if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + { + return CELL_ESRCH; + } + + if (!cond->m_queue.invalidate(thread_id)) + { + return CELL_EPERM; + } + + Mutex* mutex = cond->mutex; + u32 tid = GetCurrentPPUThread().GetId(); + + if (mutex->m_mutex.trylock(thread_id) != SMR_OK) + { + mutex->m_mutex.lock(tid); + mutex->m_mutex.unlock(tid, thread_id); + } + + if (Emu.IsStopped()) + { + ConLog.Warning("sys_cond_signal_to(id=%d, to=%d) aborted", cond_id, thread_id); + } return CELL_OK; } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Condition.h b/rpcs3/Emu/SysCalls/lv2/SC_Condition.h index 3781cf7fe4..dc849948b4 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Condition.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_Condition.h @@ -1,4 +1,5 @@ #pragma once +#include "SC_Mutex.h" struct sys_cond_attribute { @@ -12,14 +13,14 @@ struct sys_cond_attribute }; }; -struct condition +struct Cond { - wxCondition cond; - u64 name_u64; + Mutex* mutex; // associated with mutex + SleepQueue m_queue; - condition(wxMutex& mtx, u64 name) - : cond(mtx) - , name_u64(name) + Cond(Mutex* mutex, u64 name) + : mutex(mutex) + , m_queue(name) { } }; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp index e94557384e..ce84dc197d 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp @@ -59,7 +59,7 @@ int sys_event_queue_create(mem32_t equeue_id, mem_ptr_t at int sys_event_queue_destroy(u32 equeue_id, int mode) { - sys_event.Warning("sys_event_queue_destroy(equeue_id=%d, mode=0x%x)", equeue_id, mode); + sys_event.Error("sys_event_queue_destroy(equeue_id=%d, mode=0x%x)", equeue_id, mode); EventQueue* eq; if (!Emu.GetIdManager().GetIDData(equeue_id, eq)) diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp index 2b1afecd49..8ec6903349 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp @@ -10,13 +10,22 @@ int sys_lwcond_create(mem_ptr_t lwcond, mem_ptr_t l sys_lwcond.Warning("sys_lwcond_create(lwcond_addr=0x%x, lwmutex_addr=0x%x, attr_addr=0x%x)", lwcond.GetAddr(), lwmutex.GetAddr(), attr.GetAddr()); - if (!lwcond.IsGood() || !lwmutex.IsGood() || !attr.IsGood()) return CELL_EFAULT; + if (!lwcond.IsGood() || !lwmutex.IsGood() || !attr.IsGood()) + { + return CELL_EFAULT; + } lwcond->lwmutex = lwmutex.GetAddr(); - lwcond->lwcond_queue = sys_lwcond.GetNewId(new LWCond(attr->name_u64)); + lwcond->lwcond_queue = sys_lwcond.GetNewId(new SleepQueue(attr->name_u64)); + + if (lwmutex->attribute.ToBE() == se32(SYS_SYNC_RETRY)) + { + sys_lwcond.Warning("Unsupported SYS_SYNC_RETRY lwmutex protocol"); + } + + sys_lwcond.Warning("*** lwcond created [%s] (lwmutex.attr=0x%x): id = %d", + wxString(attr->name, 8).wx_str(), (u32)lwmutex->attribute, (u32)lwcond->lwcond_queue); - sys_lwcond.Warning("*** lwcond created [%s] (attr=0x%x, lwmutex.sq=0x%x): id = %d", - wxString(attr->name, 8).wx_str(), (u32)lwmutex->attribute, (u32)lwmutex->sleep_queue, (u32)lwcond->lwcond_queue); return CELL_OK; } @@ -24,12 +33,25 @@ int sys_lwcond_destroy(mem_ptr_t lwcond) { sys_lwcond.Warning("sys_lwcond_destroy(lwcond_addr=0x%x)", lwcond.GetAddr()); - if (!lwcond.IsGood()) return CELL_EFAULT; - LWCond* lwc; - u32 id = (u32)lwcond->lwcond_queue; - if (!sys_lwcond.CheckId(id, lwc)) return CELL_ESRCH; + if (!lwcond.IsGood()) + { + return CELL_EFAULT; + } - Emu.GetIdManager().RemoveID(id); + u32 lwc = lwcond->lwcond_queue; + + SleepQueue* sq; + if (!Emu.GetIdManager().GetIDData(lwc, sq)) + { + return CELL_ESRCH; + } + + if (!sq->finalize()) + { + return CELL_EBUSY; + } + + Emu.GetIdManager().RemoveID(lwc); return CELL_OK; } @@ -37,12 +59,33 @@ int sys_lwcond_signal(mem_ptr_t lwcond) { sys_lwcond.Log("sys_lwcond_signal(lwcond_addr=0x%x)", lwcond.GetAddr()); - if (!lwcond.IsGood()) return CELL_EFAULT; - LWCond* lwc; - u32 id = (u32)lwcond->lwcond_queue; - if (!sys_lwcond.CheckId(id, lwc)) return CELL_ESRCH; + if (!lwcond.IsGood()) + { + return CELL_EFAULT; + } - lwc->signal(mem_ptr_t(lwcond->lwmutex)->attribute); + SleepQueue* sq; + if (!Emu.GetIdManager().GetIDData((u32)lwcond->lwcond_queue, sq)) + { + return CELL_ESRCH; + } + + mem_ptr_t mutex(lwcond->lwmutex); + be_t tid = GetCurrentPPUThread().GetId(); + + if (be_t target = mutex->attribute.ToBE() == se32(SYS_SYNC_PRIORITY) ? sq->pop_prio() : sq->pop()) + { + if (mutex->owner.trylock(target) != SMR_OK) + { + mutex->owner.lock(tid); + mutex->owner.unlock(tid, target); + } + } + + if (Emu.IsStopped()) + { + ConLog.Warning("sys_lwcond_signal(sq=%d) aborted", (u32)lwcond->lwcond_queue); + } return CELL_OK; } @@ -51,12 +94,33 @@ int sys_lwcond_signal_all(mem_ptr_t lwcond) { sys_lwcond.Log("sys_lwcond_signal_all(lwcond_addr=0x%x)", lwcond.GetAddr()); - if (!lwcond.IsGood()) return CELL_EFAULT; - LWCond* lwc; - u32 id = (u32)lwcond->lwcond_queue; - if (!sys_lwcond.CheckId(id, lwc)) return CELL_ESRCH; + if (!lwcond.IsGood()) + { + return CELL_EFAULT; + } - lwc->signal_all(); + SleepQueue* sq; + if (!Emu.GetIdManager().GetIDData((u32)lwcond->lwcond_queue, sq)) + { + return CELL_ESRCH; + } + + mem_ptr_t mutex(lwcond->lwmutex); + be_t tid = GetCurrentPPUThread().GetId(); + + while (be_t target = mutex->attribute.ToBE() == se32(SYS_SYNC_PRIORITY) ? sq->pop_prio() : sq->pop()) + { + if (mutex->owner.trylock(target) != SMR_OK) + { + mutex->owner.lock(tid); + mutex->owner.unlock(tid, target); + } + } + + if (Emu.IsStopped()) + { + ConLog.Warning("sys_lwcond_signal_all(sq=%d) aborted", (u32)lwcond->lwcond_queue); + } return CELL_OK; } @@ -65,12 +129,37 @@ int sys_lwcond_signal_to(mem_ptr_t lwcond, u32 ppu_thread_id) { sys_lwcond.Log("sys_lwcond_signal_to(lwcond_addr=0x%x, ppu_thread_id=%d)", lwcond.GetAddr(), ppu_thread_id); - if (!lwcond.IsGood()) return CELL_EFAULT; - LWCond* lwc; - u32 id = (u32)lwcond->lwcond_queue; - if (!sys_lwcond.CheckId(id, lwc)) return CELL_ESRCH; + if (!lwcond.IsGood()) + { + return CELL_EFAULT; + } - if (!lwc->signal_to(ppu_thread_id)) return CELL_EPERM; + SleepQueue* sq; + if (!Emu.GetIdManager().GetIDData((u32)lwcond->lwcond_queue, sq)) + { + return CELL_ESRCH; + } + + if (!sq->invalidate(ppu_thread_id)) + { + return CELL_EPERM; + } + + mem_ptr_t mutex(lwcond->lwmutex); + be_t tid = GetCurrentPPUThread().GetId(); + + be_t target = ppu_thread_id; + + if (mutex->owner.trylock(target) != SMR_OK) + { + mutex->owner.lock(tid); + mutex->owner.unlock(tid, target); + } + + if (Emu.IsStopped()) + { + ConLog.Warning("sys_lwcond_signal_to(sq=%d, to=%d) aborted", (u32)lwcond->lwcond_queue, ppu_thread_id); + } return CELL_OK; } @@ -79,49 +168,56 @@ int sys_lwcond_wait(mem_ptr_t lwcond, u64 timeout) { sys_lwcond.Log("sys_lwcond_wait(lwcond_addr=0x%x, timeout=%lld)", lwcond.GetAddr(), timeout); - if (!lwcond.IsGood()) return CELL_EFAULT; - LWCond* lwc; - u32 id = (u32)lwcond->lwcond_queue; - if (!sys_lwcond.CheckId(id, lwc)) return CELL_ESRCH; - const u32 tid = GetCurrentPPUThread().GetId(); + if (!lwcond.IsGood()) + { + return CELL_EFAULT; + } - mem_ptr_t lwmutex(lwcond->lwmutex); + SleepQueue* sq; + if (!Emu.GetIdManager().GetIDData((u32)lwcond->lwcond_queue, sq)) + { + return CELL_ESRCH; + } - if ((u32)lwmutex->owner.GetOwner() != tid) return CELL_EPERM; // caller must own this lwmutex - lwc->begin_waiting(tid); + mem_ptr_t mutex(lwcond->lwmutex); + u32 tid_le = GetCurrentPPUThread().GetId(); + be_t tid = tid_le; + + if (mutex->owner.GetOwner() != tid) + { + return CELL_EPERM; // caller must own this lwmutex + } + + sq->push(tid_le); + + mutex->owner.unlock(tid); u32 counter = 0; - const u32 max_counter = timeout ? (timeout / 1000) : 20000; - bool was_locked = true; - do + const u32 max_counter = timeout ? (timeout / 1000) : ~0; + while (true) { - if (Emu.IsStopped()) + /* switch (mutex->trylock(tid)) { - ConLog.Warning("sys_lwcond_wait(sq id=%d, ...) aborted", id); - return CELL_ETIMEDOUT; + case SMR_OK: mutex->unlock(tid); break; + case SMR_SIGNAL: return CELL_OK; + } */ + if (mutex->owner.GetOwner() == tid) + { + _mm_mfence(); + return CELL_OK; } - if (was_locked) lwmutex->unlock(tid); + Sleep(1); - if (was_locked = (lwmutex->trylock(tid) == CELL_OK)) - { - if (lwc->check(tid)) - { - return CELL_OK; - } - } if (counter++ > max_counter) { - if (!timeout) - { - sys_lwcond.Warning("sys_lwcond_wait(lwcond_addr=0x%x): TIMEOUT", lwcond.GetAddr()); - counter = 0; - } - else - { - lwc->stop_waiting(tid); - return CELL_ETIMEDOUT; - } - } - } while (true); + sq->invalidate(tid_le); + return CELL_ETIMEDOUT; + } + if (Emu.IsStopped()) + { + ConLog.Warning("sys_lwcond_wait(sq=%d) aborted", (u32)lwcond->lwcond_queue); + return CELL_OK; + } + } } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.h b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.h index 037f47f67b..f7d8369c13 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.h @@ -13,108 +13,4 @@ struct sys_lwcond_t { be_t lwmutex; be_t lwcond_queue; -}; - -#pragma pack() - -struct LWCond -{ - std::mutex m_lock; - Array waiters; // list of waiting threads - Array signaled; // list of signaled threads - u64 m_name; // not used - - LWCond(u64 name) - : m_name(name) - { - } - - void signal(u32 _protocol) - { - std::lock_guard lock(m_lock); - - if (waiters.GetCount()) - { - if ((_protocol & SYS_SYNC_ATTR_PROTOCOL_MASK) == SYS_SYNC_PRIORITY) - { - u64 max_prio = 0; - u32 sel = 0; - for (u32 i = 0; i < waiters.GetCount(); i++) - { - CPUThread* t = Emu.GetCPU().GetThread(waiters[i]); - if (!t) continue; - - u64 prio = t->GetPrio(); - if (prio > max_prio) - { - max_prio = prio; - sel = i; - } - } - signaled.AddCpy(waiters[sel]); - waiters.RemoveAt(sel); - } - else // SYS_SYNC_FIFO - { - signaled.AddCpy(waiters[0]); - waiters.RemoveAt(0); - } - } - } - - void signal_all() - { - std::lock_guard lock(m_lock); - - signaled.AppendFrom(waiters); // "nobody cares" protocol (!) - waiters.Clear(); - } - - bool signal_to(u32 id) // returns false if not found - { - std::lock_guard lock(m_lock); - for (u32 i = waiters.GetCount() - 1; ~i; i--) - { - if (waiters[i] == id) - { - waiters.RemoveAt(i); - signaled.AddCpy(id); - return true; - } - } - return false; - } - - void begin_waiting(u32 id) - { - std::lock_guard lock(m_lock); - waiters.AddCpy(id); - } - - void stop_waiting(u32 id) - { - std::lock_guard lock(m_lock); - for (u32 i = waiters.GetCount() - 1; ~i; i--) - { - if (waiters[i] == id) - { - waiters.RemoveAt(i); - break; - } - } - } - - bool check(u32 id) // returns true if signaled - { - std::lock_guard lock(m_lock); - for (u32 i = signaled.GetCount() - 1; ~i; i--) - { - if (signaled[i] == id) - { - signaled.RemoveAt(i); - return true; - } - } - return false; - } }; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp index 223b720045..331019093b 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp @@ -6,7 +6,7 @@ SysCallBase sc_lwmutex("sys_lwmutex"); int sys_lwmutex_create(mem_ptr_t lwmutex, mem_ptr_t attr) { - sc_lwmutex.Log("sys_lwmutex_create(lwmutex_addr=0x%x, lwmutex_attr_addr=0x%x)", + sc_lwmutex.Warning("sys_lwmutex_create(lwmutex_addr=0x%x, lwmutex_attr_addr=0x%x)", lwmutex.GetAddr(), attr.GetAddr()); if (!lwmutex.IsGood() || !attr.IsGood()) return CELL_EFAULT; @@ -15,7 +15,7 @@ int sys_lwmutex_create(mem_ptr_t lwmutex, mem_ptr_tattr_recursive); return CELL_EINVAL; + default: sc_lwmutex.Error("Unknown recursive attribute(0x%x)", (u32)attr->attr_recursive); return CELL_EINVAL; } switch (attr->attr_protocol.ToBE()) @@ -24,7 +24,7 @@ int sys_lwmutex_create(mem_ptr_t lwmutex, mem_ptr_tattr_protocol); return CELL_EINVAL; + default: sc_lwmutex.Error("Unknown protocol attribute(0x%x)", (u32)attr->attr_protocol); return CELL_EINVAL; } lwmutex->attribute = attr->attr_protocol | attr->attr_recursive; @@ -35,7 +35,7 @@ int sys_lwmutex_create(mem_ptr_t lwmutex, mem_ptr_tname_u64)); lwmutex->sleep_queue = sq_id; - sc_lwmutex.Log("*** lwmutex created [%s] (attribute=0x%x): sq_id = %d", + sc_lwmutex.Warning("*** lwmutex created [%s] (attribute=0x%x): sq_id = %d", wxString(attr->name, 8).wx_str(), (u32)lwmutex->attribute, sq_id); return CELL_OK; @@ -43,7 +43,7 @@ int sys_lwmutex_create(mem_ptr_t lwmutex, mem_ptr_t lwmutex) { - sc_lwmutex.Log("sys_lwmutex_destroy(lwmutex_addr=0x%x)", lwmutex.GetAddr()); + sc_lwmutex.Warning("sys_lwmutex_destroy(lwmutex_addr=0x%x)", lwmutex.GetAddr()); if (!lwmutex.IsGood()) return CELL_EFAULT; @@ -160,18 +160,38 @@ u32 SleepQueue::pop_prio_inherit() // (TODO) return 0; } -void SleepQueue::invalidate(u32 tid) +bool SleepQueue::invalidate(u32 tid) { SMutexLocker lock(m_mutex); - for (u32 i = 0; i < list.GetCount(); i++) + if (tid) for (u32 i = 0; i < list.GetCount(); i++) { if (list[i] = tid) { list[i] = 0; - return; + return true; } } + + return false; +} + +bool SleepQueue::finalize() +{ + u32 tid = GetCurrentPPUThread().GetId(); + + m_mutex.lock(tid); + + for (u32 i = 0; i < list.GetCount(); i++) + { + if (list[i]) + { + m_mutex.unlock(tid); + return false; + } + } + + return true; } int sys_lwmutex_t::trylock(be_t tid) diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h index 8898024a8b..4d104a556b 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h @@ -8,7 +8,7 @@ enum SYS_SYNC_FIFO = 1, // Priority Order SYS_SYNC_PRIORITY = 2, - // Basic Priority Inheritance Protocol + // Basic Priority Inheritance Protocol (probably not implemented) SYS_SYNC_PRIORITY_INHERIT = 3, // Not selected while unlocking SYS_SYNC_RETRY = 4, @@ -59,7 +59,8 @@ struct SleepQueue u32 pop(); // SYS_SYNC_FIFO u32 pop_prio(); // SYS_SYNC_PRIORITY u32 pop_prio_inherit(); // (TODO) - void invalidate(u32 tid); + bool invalidate(u32 tid); + bool finalize(); }; struct sys_lwmutex_t @@ -84,26 +85,4 @@ struct sys_lwmutex_t int trylock(be_t tid); int unlock(be_t tid); int lock(be_t tid, u64 timeout); -}; -/* -class lwmutex_locker -{ - mem_ptr_t m_mutex; - be_t m_id; - - lwmutex_locker(mem_ptr_t lwmutex, be_t tid, u64 timeout = 0) - : m_id(tid) - , m_mutex(lwmutex) - { - if (int res = m_mutex->lock(m_id, timeout)) - { - ConLog.Error("lwmutex_locker: m_mutex->lock failed(res=0x%x)", res); - Emu.Pause(); - } - } - - ~lwmutex_locker() - { - m_mutex->unlock(m_id); - } -};*/ \ No newline at end of file +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp index 415d2f2ccc..3467c949f1 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp @@ -5,39 +5,74 @@ SysCallBase sys_mtx("sys_mutex"); -int sys_mutex_create(u32 mutex_id_addr, u32 attr_addr) +int sys_mutex_create(mem32_t mutex_id, mem_ptr_t attr) { - sys_mtx.Warning("sys_mutex_create(mutex_id_addr=0x%x, attr_addr=0x%x)", - mutex_id_addr, attr_addr); + sys_mtx.Warning("sys_mutex_create(mutex_id_addr=0x%x, attr_addr=0x%x)", mutex_id.GetAddr(), attr.GetAddr()); - if(!Memory.IsGoodAddr(mutex_id_addr) || !Memory.IsGoodAddr(attr_addr)) return CELL_EFAULT; + if (!mutex_id.IsGood() || !attr.IsGood()) + { + return CELL_EFAULT; + } - mutex_attr attr = (mutex_attr&)Memory[attr_addr]; - attr.protocol = re(attr.protocol); - attr.recursive = re(attr.recursive); - attr.pshared = re(attr.pshared); - attr.adaptive = re(attr.adaptive); - attr.ipc_key = re(attr.ipc_key); - attr.flags = re(attr.flags); - - sys_mtx.Log("*** protocol = %d", attr.protocol); - sys_mtx.Log("*** recursive = %d", attr.recursive); - sys_mtx.Log("*** pshared = %d", attr.pshared); - sys_mtx.Log("*** ipc_key = 0x%llx", attr.ipc_key); - sys_mtx.Log("*** flags = 0x%x", attr.flags); - sys_mtx.Log("*** name = %s", attr.name); + switch (attr->protocol.ToBE()) + { + case se32(SYS_SYNC_FIFO): break; + case se32(SYS_SYNC_PRIORITY): break; + case se32(SYS_SYNC_PRIORITY_INHERIT): sys_mtx.Warning("TODO: SYS_SYNC_PRIORITY_INHERIT protocol"); break; + case se32(SYS_SYNC_RETRY): sys_mtx.Error("Invalid SYS_SYNC_RETRY protocol"); return CELL_EINVAL; + default: sys_mtx.Error("Unknown protocol attribute(0x%x)", (u32)attr->protocol); return CELL_EINVAL; + } - Memory.Write32(mutex_id_addr, sys_mtx.GetNewId(new mutex(attr))); + bool is_recursive; + switch (attr->recursive.ToBE()) + { + case se32(SYS_SYNC_RECURSIVE): is_recursive = true; break; + case se32(SYS_SYNC_NOT_RECURSIVE): is_recursive = false; break; + default: sys_mtx.Error("Unknown recursive attribute(0x%x)", (u32)attr->recursive); return CELL_EINVAL; + } + + if (attr->pshared.ToBE() != se32(0x200)) + { + sys_mtx.Error("Unknown pshared attribute(0x%x)", (u32)attr->pshared); + return CELL_EINVAL; + } + + mutex_id = sys_mtx.GetNewId(new Mutex((u32)attr->protocol, is_recursive, attr->name_u64)); + sys_mtx.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%d): id = %d", + wxString(attr->name, 8).wx_str(), (u32)attr->protocol, is_recursive, mutex_id.GetValue()); return CELL_OK; } int sys_mutex_destroy(u32 mutex_id) { - sys_mtx.Log("sys_mutex_destroy(mutex_id=0x%x)", mutex_id); + sys_mtx.Warning("sys_mutex_destroy(mutex_id=0x%x)", mutex_id); - if(!sys_mtx.CheckId(mutex_id)) return CELL_ESRCH; + Mutex* mutex; + if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + { + return CELL_ESRCH; + } + if ((u32&)mutex->cond_count) // check if associated condition variable exists + { + return CELL_EPERM; + } + + u32 tid = GetCurrentPPUThread().GetId(); + + if (mutex->m_mutex.trylock(tid)) // check if locked + { + return CELL_EBUSY; + } + + if (!mutex->m_queue.finalize()) + { + mutex->m_mutex.unlock(tid); + return CELL_EBUSY; + } + + mutex->m_mutex.unlock(tid, ~0); Emu.GetIdManager().RemoveID(mutex_id); return CELL_OK; } @@ -46,56 +81,113 @@ int sys_mutex_lock(u32 mutex_id, u64 timeout) { sys_mtx.Log("sys_mutex_lock(mutex_id=0x%x, timeout=0x%llx)", mutex_id, timeout); - mutex* mtx_data = nullptr; - if(!sys_mtx.CheckId(mutex_id, mtx_data)) return CELL_ESRCH; - - u32 counter = 0; - const u32 max_counter = timeout ? (timeout / 1000) : 20000; - do + Mutex* mutex; + if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) { - if (Emu.IsStopped()) + return CELL_ESRCH; + } + + u32 tid = GetCurrentPPUThread().GetId(); + + if (mutex->m_mutex.GetOwner() == tid) + { + if (mutex->is_recursive) { - ConLog.Warning("sys_mutex_lock(mutex_id=%d, ...) aborted", mutex_id); - return CELL_ETIMEDOUT; + if (mutex->recursive++ == 0) + { + return CELL_EKRESOURCE; + } + return CELL_OK; } - - if (mtx_data->mtx.TryLock() == wxMUTEX_NO_ERROR) return CELL_OK; - Sleep(1); - - if (counter++ > max_counter) + else { - if (!timeout) - { - counter = 0; - } - else - { - return CELL_ETIMEDOUT; - } - } - } while (true); + return CELL_EDEADLK; + } + } + + switch (mutex->m_mutex.trylock(tid)) + { + case SMR_OK: return CELL_OK; + case SMR_FAILED: break; + default: goto abort; + } + + mutex->m_queue.push(tid); + + switch (mutex->m_mutex.lock(tid, timeout ? ((timeout < 1000) ? 1 : (timeout / 1000)) : 0)) + { + case SMR_OK: mutex->m_queue.invalidate(tid); + case SMR_SIGNAL: mutex->recursive = 1; return CELL_OK; + case SMR_TIMEOUT: return CELL_ETIMEDOUT; + default: goto abort; + } + +abort: + if (Emu.IsStopped()) + { + ConLog.Warning("sys_mutex_lock(id=%d) aborted", mutex_id); + return CELL_OK; + } + return CELL_ESRCH; } int sys_mutex_trylock(u32 mutex_id) { sys_mtx.Log("sys_mutex_trylock(mutex_id=0x%x)", mutex_id); - mutex* mtx_data = nullptr; - if(!sys_mtx.CheckId(mutex_id, mtx_data)) return CELL_ESRCH; + Mutex* mutex; + if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + { + return CELL_ESRCH; + } - if (mtx_data->mtx.TryLock() != wxMUTEX_NO_ERROR) return CELL_EBUSY; + u32 tid = GetCurrentPPUThread().GetId(); - return CELL_OK; + if (mutex->m_mutex.GetOwner() == tid) + { + if (mutex->is_recursive) + { + if (++mutex->recursive == 0) + { + return CELL_EKRESOURCE; + } + return CELL_OK; + } + else + { + return CELL_EDEADLK; + } + } + + switch (mutex->m_mutex.trylock(tid)) + { + case SMR_OK: return CELL_OK; + } + + return CELL_EBUSY; } int sys_mutex_unlock(u32 mutex_id) { sys_mtx.Log("sys_mutex_unlock(mutex_id=0x%x)", mutex_id); - mutex* mtx_data = nullptr; - if(!sys_mtx.CheckId(mutex_id, mtx_data)) return CELL_ESRCH; + Mutex* mutex; + if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + { + return CELL_ESRCH; + } - mtx_data->mtx.Unlock(); + u32 tid = GetCurrentPPUThread().GetId(); - return CELL_OK; + if (mutex->m_mutex.GetOwner() == tid) + { + mutex->recursive--; + if (!mutex->recursive) + { + mutex->m_mutex.unlock(tid, mutex->protocol == SYS_SYNC_PRIORITY ? mutex->m_queue.pop_prio() : mutex->m_queue.pop()); + } + return CELL_OK; + } + + return CELL_EPERM; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Mutex.h b/rpcs3/Emu/SysCalls/lv2/SC_Mutex.h index b191061889..2366d1656a 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Mutex.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_Mutex.h @@ -1,25 +1,36 @@ #pragma once -struct mutex_attr +struct sys_mutex_attribute { - u32 protocol; - u32 recursive; - u32 pshared; - u32 adaptive; - u64 ipc_key; - int flags; - u32 pad; - char name[8]; + be_t protocol; // SYS_SYNC_FIFO, SYS_SYNC_PRIORITY or SYS_SYNC_PRIORITY_INHERIT + be_t recursive; // SYS_SYNC_RECURSIVE or SYS_SYNC_NOT_RECURSIVE + be_t pshared; // always 0x200 (not shared) + be_t adaptive; + be_t ipc_key; + be_t flags; + be_t pad; + union + { + char name[8]; + u64 name_u64; + }; }; -struct mutex +struct Mutex { - wxMutex mtx; - mutex_attr attr; + SMutex m_mutex; + SleepQueue m_queue; + u32 recursive; // recursive locks count + std::atomic cond_count; // count of condition variables associated - mutex(const mutex_attr& attr) - : mtx() - , attr(attr) + const u32 protocol; + const bool is_recursive; + + Mutex(u32 protocol, bool is_recursive, u64 name) + : protocol(protocol) + , is_recursive(is_recursive) + , m_queue(name) + , cond_count(0) { } }; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp index 4b14b10c31..fb39296f6e 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp @@ -32,7 +32,8 @@ void sys_ppu_thread_exit(int errorcode) int sys_ppu_thread_yield() { - sysPrxForUser.Log("sys_ppu_thread_yield()"); + sysPrxForUser.Log("sys_ppu_thread_yield()"); + Sleep(1); return CELL_OK; } From e066bcf2616a2566b1b59f4a80230e307a754c85 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 15 Feb 2014 00:08:02 +0400 Subject: [PATCH 2/5] Small cellAudio update --- rpcs3/Emu/Audio/sysutil_audio.h | 24 ++++----- rpcs3/Emu/CPU/CPUThread.cpp | 6 +-- rpcs3/Emu/Cell/SPUInterpreter.h | 7 ++- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 38 +++++++++++---- rpcs3/Emu/SysCalls/Modules/cellResc.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 57 +++++++++++----------- 6 files changed, 77 insertions(+), 57 deletions(-) diff --git a/rpcs3/Emu/Audio/sysutil_audio.h b/rpcs3/Emu/Audio/sysutil_audio.h index b8c1061e54..ea470c4779 100644 --- a/rpcs3/Emu/Audio/sysutil_audio.h +++ b/rpcs3/Emu/Audio/sysutil_audio.h @@ -158,7 +158,7 @@ struct CellAudioOutConfiguration u8 channel; u8 encoder; u8 reserved[10]; - u32 downMixer; + be_t downMixer; }; struct CellAudioOutSoundMode @@ -167,7 +167,7 @@ struct CellAudioOutSoundMode u8 channel; u8 fs; u8 reserved; - u32 layout; + be_t layout; }; struct CellAudioOutDeviceInfo @@ -175,9 +175,9 @@ struct CellAudioOutDeviceInfo u8 portType; u8 availableModeCount; u8 state; - u8 reserved[3]; - u16 latency; - CellAudioOutSoundMode availableModes[16]; + u8 reserved[3]; + be_t latency; + CellAudioOutSoundMode availableModes[16]; }; struct CellAudioOutState @@ -185,7 +185,7 @@ struct CellAudioOutState u8 state; u8 encoder; u8 reserved[6]; - u32 downMixer; + be_t downMixer; CellAudioOutSoundMode soundMode; }; @@ -193,7 +193,7 @@ struct CellAudioOutSoundMode2 { u8 type; u8 channel; - u16 fs; + be_t fs; u8 reserved[4]; }; @@ -204,8 +204,8 @@ struct CellAudioOutDeviceInfo2 u8 state; u8 deviceNumber; u8 reserved[12]; - u64 deviceId; - u64 type; + be_t deviceId; + be_t type; char name[64]; CellAudioOutSoundMode2 availableModes2[16]; }; @@ -229,7 +229,7 @@ struct CellAudioInSoundMode { u8 type; u8 channel; - u16 fs; + be_t fs; u8 reserved[4]; }; @@ -240,8 +240,8 @@ struct CellAudioInDeviceInfo u8 state; u8 deviceNumber; u8 reserved[12]; - u64 deviceId; - u64 type; + be_t deviceId; + be_t type; char name[64]; CellAudioInSoundMode availableModes[16]; }; diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 1e881bcd91..dff8da61f6 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -96,7 +96,7 @@ bool CPUThread::Sync() int CPUThread::ThreadStatus() { - if(Emu.IsStopped() || IsStopped() ) + if (Emu.IsStopped() || IsStopped()) { return CPUThread_Stopped; } @@ -106,12 +106,12 @@ int CPUThread::ThreadStatus() return CPUThread_Step; } - if (TestDestroy()) + if (TestDestroy() || IsPaused()) { return CPUThread_Break; } - if(Emu.IsPaused() || Sync()) + if (Emu.IsPaused() || Sync()) { return CPUThread_Sleeping; } diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index 361e8c7e27..2f087d0fac 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -32,8 +32,11 @@ private: //0 - 10 void STOP(u32 code) { - ConLog.Warning("STOP: 0x%x (m_exit_status -> 0)", code); - CPU.SetExitStatus(0); + if (CPU.SPU.Out_MBox.GetCount()) // the real exit status is probably stored there + ConLog.Warning("STOP: 0x%x (message=0x%x)", code, CPU.SPU.Out_MBox.GetValue()); + else + ConLog.Warning("STOP: 0x%x (no message)", code); + CPU.SetExitStatus(code); CPU.Stop(); } void LNOP() diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index e8a886f930..8cf5a2bbe6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -91,7 +91,7 @@ struct AudioPortConfig AudioPortConfig(); - ~AudioPortConfig(); + void finalize(); }; struct AudioConfig //custom structure @@ -127,15 +127,15 @@ struct AudioConfig //custom structure AudioPortConfig::AudioPortConfig() : m_is_audio_port_started(false) - , m_buffer(Memory.Alloc(1024 * 128, 1024)) - , m_index(Memory.Alloc(16, 16)) + , m_buffer(Memory.Alloc(1024 * 128, 1024)) // max 128K size + , m_index(Memory.Alloc(16, 16)) // allocation for u64 value "read index" { m_config.m_port_in_use++; mem64_t index(m_index); index = 0; } -AudioPortConfig::~AudioPortConfig() +void AudioPortConfig::finalize() { m_config.m_port_in_use--; Memory.Free(m_buffer); @@ -330,12 +330,11 @@ int cellAudioGetPortConfig(u32 portNum, mem_ptr_t portConfi portConfig->status = CELL_AUDIO_STATUS_READY; portConfig->nChannel = ref.nChannel; portConfig->nBlock = ref.nBlock; - portConfig->portSize = ref.nChannel * ref.nBlock * 256; + portConfig->portSize = ref.nChannel * ref.nBlock * 256 * sizeof(float); portConfig->portAddr = m_config.m_ports[portNum]->m_buffer; // 0x20020000 portConfig->readIndexAddr = m_config.m_ports[portNum]->m_index; // 0x20010010 on ps3 // portAddr - readIndexAddr == 0xFFF0 on ps3 - // Memory.Write64(portConfig->readIndexAddr, 1); } return CELL_OK; @@ -361,6 +360,25 @@ int cellAudioPortStart(u32 portNum) } m_config.m_ports[portNum]->m_is_audio_port_started = true; + + std::string t_name = "AudioPort0"; + t_name[9] += portNum; + + thread t(t_name, [portNum]() + { + AudioPortConfig& ref = *m_config.m_ports[portNum]; + mem64_t index(ref.m_index); + + ConLog.Write("Port started"); + while (ref.m_is_audio_port_started && !Emu.IsStopped()) + { + Sleep(5); + index = (index.GetValue() + 1) % ref.m_param.nBlock; + } + ConLog.Write("Port finished"); + }); + t.detach(); + return CELL_OK; } @@ -378,8 +396,8 @@ int cellAudioPortClose(u32 portNum) return CELL_AUDIO_ERROR_PORT_NOT_OPEN; } - delete m_config.m_ports[portNum]; - m_config.m_ports[portNum] = nullptr; + m_config.m_ports[portNum]->finalize(); + safe_delete(m_config.m_ports[portNum]); return CELL_OK; } @@ -402,7 +420,7 @@ int cellAudioPortStop(u32 portNum) return CELL_AUDIO_ERROR_PORT_NOT_RUN; } - m_config.m_ports[portNum]->m_is_audio_port_started = false; + m_config.m_ports[portNum]->m_is_audio_port_started = false; return CELL_OK; } @@ -449,7 +467,7 @@ int cellAudioSetNotifyEventQueue(u64 key) return CELL_AUDIO_ERROR_PARAM; } - eq->events.push(0, 0, 0, 0); + // eq->events.push(0, 0, 0, 0); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index cfa5459a24..f30fbc0e98 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -713,7 +713,7 @@ int cellRescSetConvertAndFlip(mem_ptr_t cntxt, s32 idx) int cellRescSetWaitFlip() { cellResc.Log("cellRescSetWaitFlip()"); - GSLockCurrent lock(GS_LOCK_WAIT_FLIP); + GSLockCurrent lock(GS_LOCK_WAIT_FLIP); // could stall on exit return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 4b13707b9a..2c16b024ec 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -641,11 +641,13 @@ int cellMsgDialogOpenErrorCode(u32 errorCode, mem_func_ptr_t config, mem_ptr_t option, u32 waitForEvent) { - cellSysutil.Warning("cellAudioOutConfigure(audioOut=%d, config_addr=0x%x, option_addr=0x%x, waitForEvent=0x%x)", - audioOut, config_addr, option_addr, waitForEvent); + cellSysutil.Warning("cellAudioOutConfigure(audioOut=%d, config_addr=0x%x, option_addr=0x%x, (!)waitForEvent=%d)", + audioOut, config.GetAddr(), option.GetAddr(), waitForEvent); - if(!Memory.IsGoodAddr(config_addr, sizeof(CellAudioOutConfiguration))) + if (!config.IsGood()) { return CELL_EFAULT; } - CellAudioOutConfiguration& config = (CellAudioOutConfiguration&)Memory[config_addr]; - switch(audioOut) { case CELL_AUDIO_OUT_PRIMARY: - if(config.channel) + if (config->channel) { - Emu.GetAudioManager().GetInfo().mode.channel = config.channel; + Emu.GetAudioManager().GetInfo().mode.channel = config->channel; } - Emu.GetAudioManager().GetInfo().mode.encoder = config.encoder; + Emu.GetAudioManager().GetInfo().mode.encoder = config->encoder; - if(config.downMixer) + if(config->downMixer) { - Emu.GetAudioManager().GetInfo().mode.downMixer = config.downMixer; + Emu.GetAudioManager().GetInfo().mode.downMixer = config->downMixer; } return CELL_AUDIO_OUT_SUCCEEDED; From 848c5dadf0eecccf1ce86b22e525316c7121e67c Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 16 Feb 2014 01:16:35 +0400 Subject: [PATCH 3/5] Fixed some problems --- rpcs3/Emu/Cell/SPUThread.h | 2 +- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 6 +++- rpcs3/Emu/SysCalls/Modules/cellPamf.cpp | 4 +-- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 10 +++--- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 11 +++++-- rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 38 +++++++++++++++++----- rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp | 11 +++++-- rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp | 20 ++++++++---- rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp | 13 ++++---- rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp | 18 ++++++++-- rpcs3/Gui/ConLog.cpp | 2 +- 12 files changed, 95 insertions(+), 42 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 81450ad14b..89f39c32ce 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -611,7 +611,7 @@ public: case SPU_RdInMbox: count = SPU.In_MBox.GetCount(); - ConLog.Warning("GetChannelCount(%s) -> %d", wxString(spu_ch_name[ch]).wx_str(), count); + //ConLog.Warning("GetChannelCount(%s) -> %d", wxString(spu_ch_name[ch]).wx_str(), count); return count; case SPU_WrOutIntrMbox: diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 8cf5a2bbe6..b794ea53b5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -334,6 +334,8 @@ int cellAudioGetPortConfig(u32 portNum, mem_ptr_t portConfi portConfig->portAddr = m_config.m_ports[portNum]->m_buffer; // 0x20020000 portConfig->readIndexAddr = m_config.m_ports[portNum]->m_index; // 0x20010010 on ps3 + ConLog.Write("*** nChannel=%d, nBlock=%d, portSize=0x%x, portAddr=0x%x, readIndexAddr=0x%x", + (u32)portConfig->nChannel, (u32)portConfig->nBlock, (u32)portConfig->portSize, (u32)portConfig->portAddr, (u32)portConfig->readIndexAddr); // portAddr - readIndexAddr == 0xFFF0 on ps3 } @@ -446,6 +448,7 @@ int cellAudioSetPortLevel(u32 portNum, float level) int cellAudioCreateNotifyEventQueue(mem32_t id, mem64_t key) { cellAudio.Error("cellAudioCreateNotifyEventQueue(id_addr=0x%x, key_addr=0x%x)", id.GetAddr(), key.GetAddr()); + key = 0x123456789ABCDEF0; return CELL_OK; } @@ -464,7 +467,8 @@ int cellAudioSetNotifyEventQueue(u64 key) EventQueue* eq; if (!Emu.GetEventManager().GetEventQueue(key, eq)) { - return CELL_AUDIO_ERROR_PARAM; + //return CELL_AUDIO_ERROR_PARAM; + return CELL_OK; } // eq->events.push(0, 0, 0, 0); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp index 1559788875..c8a7dbe26d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp @@ -118,8 +118,8 @@ int cellPamfGetHeaderSize(mem_ptr_t pAddr, u64 fileSize, mem64_t pSi cellPamf.Warning("cellPamfGetHeaderSize(pAddr=0x%x, fileSize=%d, pSize_addr=0x%x)", pAddr.GetAddr(), fileSize, pSize.GetAddr()); - //if ((u32)pAddr->magic != 0x464d4150) - //return CELL_PAMF_ERROR_UNKNOWN_TYPE; + if ((u32)pAddr->magic != 0x464d4150) + return CELL_PAMF_ERROR_UNKNOWN_TYPE; const u64 offset = (u64)pAddr->data_offset << 11; pSize = offset /*? offset : 2048*/; //hack diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 4a7cb65e63..95ecd1e8d2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -95,15 +95,13 @@ int cellSyncMutexLock(mem_ptr_t mutex) } } - int counter = 0; - while (*(u16*)&old_order != *(u16*)&mutex->m_freed) + while (old_order != Memory.Read16(mutex.GetAddr())) { Sleep(1); - if (++counter >= 5000) + if (Emu.IsStopped()) { - counter = 0; - cellSync.Warning("cellSyncMutexLock(mutex=0x%x, old_order=%d, order=%d, freed=%d): TIMEOUT", - mutex.GetAddr(), (u16)old_order, (u16)mutex->m_order, (u16)mutex->m_freed); + ConLog.Warning("cellSyncMutexLock(mutex=0x%x) aborted", mutex.GetAddr()); + break; } } _mm_mfence(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 2c16b024ec..2ce2fd58cf 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -458,12 +458,15 @@ int cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, u32 as int cellSysutilCheckCallback() { cellSysutil.Log("cellSysutilCheckCallback()"); + Emu.GetCallbackManager().m_exit_callback.Check(); CPUThread& thr = Emu.GetCallbackThread(); - while(Emu.IsRunning() && thr.IsAlive()) + while (Emu.IsRunning() && thr.IsAlive()) + { Sleep(1); + } return CELL_OK; } @@ -471,6 +474,7 @@ int cellSysutilCheckCallback() int cellSysutilRegisterCallback(int slot, u64 func_addr, u64 userdata) { cellSysutil.Warning("cellSysutilRegisterCallback(slot=%d, func_addr=0x%llx, userdata=0x%llx)", slot, func_addr, userdata); + Emu.GetCallbackManager().m_exit_callback.Register(slot, func_addr, userdata); wxGetApp().SendDbgCommand(DID_REGISTRED_CALLBACK); @@ -481,6 +485,7 @@ int cellSysutilRegisterCallback(int slot, u64 func_addr, u64 userdata) int cellSysutilUnregisterCallback(int slot) { cellSysutil.Warning("cellSysutilUnregisterCallback(slot=%d)", slot); + Emu.GetCallbackManager().m_exit_callback.Unregister(slot); wxGetApp().SendDbgCommand(DID_UNREGISTRED_CALLBACK); @@ -646,7 +651,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) option = 0; - int available = 2; + int available = 2; // should be at least 2 switch(fs) { @@ -687,7 +692,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3 option = 0; - int available = 2; + int available = 2; // should be at least 2 switch(fs) { diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index b1845e9ecc..33bc0b1b80 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -137,8 +137,13 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) return CELL_OK; } +SMutex aio_mutex; +bool aio_init; + void fsAioRead(u32 fd, mem_ptr_t aio, int xid, mem_func_ptr_t xaio, u32 error, int xid, u64 size)> func) { + //SMutexLocker lock (aio_mutex); + vfsFileBase* orig_file; if(!sys_fs.CheckId(fd, orig_file)) return; @@ -175,30 +180,43 @@ void fsAioRead(u32 fd, mem_ptr_t aio, int xid, mem_func_ptr_toffset, buf_addr, (u64)aio->size, res, xid, path.wx_str()); + //start callback thread if(func) func.async(aio, error, xid, res); - - ConLog.Warning("*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%x, res=0x%x, xid=0x%x [%s])", - fd, (u64)aio->offset, buf_addr, (u64)aio->size, res, xid, path.wx_str()); } int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, mem_func_ptr_t xaio, u32 error, int xid, u64 size)> func) { sys_fs.Warning("cellFsAioRead(aio_addr=0x%x, id_addr=0x%x, func_addr=0x%x)", aio.GetAddr(), aio_id.GetAddr(), func.GetAddr()); + + if (!aio.IsGood() || !aio_id.IsGood() || !func.IsGood()) + { + return CELL_EFAULT; + } + + if (!aio_init) + { + return CELL_ENXIO; + } + vfsFileBase* orig_file; u32 fd = aio->fd; - if(!sys_fs.CheckId(fd, orig_file)) return CELL_ESRCH; + if (!sys_fs.CheckId(fd, orig_file)) return CELL_EBADF; //get a unique id for the callback (may be used by cellFsAioCancel) const u32 xid = g_FsAioReadID++; - - thread t("fsAioRead", std::bind(fsAioRead, fd, aio, xid, func)); - t.detach(); - //fsAioRead(fd, aio, xid, func); - aio_id = xid; + { + //SMutexLocker lock(aio_mutex); + thread t("fsAioRead", std::bind(fsAioRead, fd, aio, xid, func)); + t.detach(); + //fsAioRead(fd, aio, xid, func); + } + return CELL_OK; } @@ -206,6 +224,7 @@ int cellFsAioInit(mem8_ptr_t mount_point) { wxString mp = Memory.ReadString(mount_point.GetAddr()); sys_fs.Warning("cellFsAioInit(mount_point_addr=0x%x (%s))", mount_point.GetAddr(), mp.wx_str()); + aio_init = true; return CELL_OK; } @@ -239,4 +258,5 @@ void sys_fs_init() sys_fs.AddFunc(0xc1c507e7, cellFsAioRead); sys_fs.AddFunc(0xdb869f20, cellFsAioInit); sys_fs.AddFunc(0x9f951810, cellFsAioFinish); + aio_init = false; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp index a8af86c9e1..f26061e19f 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp @@ -6,7 +6,7 @@ SysCallBase sys_cond("sys_cond"); int sys_cond_create(mem32_t cond_id, u32 mutex_id, mem_ptr_t attr) { - sys_cond.Warning("sys_cond_create(cond_id_addr=0x%x, mutex_id=%d, attr_addr=%d)", + sys_cond.Log("sys_cond_create(cond_id_addr=0x%x, mutex_id=%d, attr_addr=%d)", cond_id.GetAddr(), mutex_id, attr.GetAddr()); if (!cond_id.IsGood() || !attr.IsGood()) @@ -30,7 +30,7 @@ int sys_cond_create(mem32_t cond_id, u32 mutex_id, mem_ptr_t u32 id = sys_cond.GetNewId(cond); cond_id = id; mutex->cond_count++; - sys_cond.Warning("*** condition created [%s]: id = %d", wxString(attr->name, 8).wx_str(), cond_id.GetValue()); + sys_cond.Warning("*** condition created [%s] (mutex_id=%d): id = %d", wxString(attr->name, 8).wx_str(), mutex_id, cond_id.GetValue()); return CELL_OK; } @@ -75,6 +75,7 @@ int sys_cond_wait(u32 cond_id, u64 timeout) cond->m_queue.push(tid); + mutex->recursive = 0; mutex->m_mutex.unlock(tid); u32 counter = 0; @@ -85,11 +86,12 @@ int sys_cond_wait(u32 cond_id, u64 timeout) /* switch (mutex->m_mutex.trylock(tid)) { case SMR_OK: mutex->m_mutex.unlock(tid); break; - case SMR_SIGNAL: return CELL_OK; + case SMR_SIGNAL: mutex->recursive = 1; return CELL_OK; } */ if (mutex->m_mutex.GetOwner() == tid) { _mm_mfence(); + mutex->recursive = 1; return CELL_OK; } @@ -126,6 +128,7 @@ int sys_cond_signal(u32 cond_id) if (mutex->m_mutex.trylock(target) != SMR_OK) { mutex->m_mutex.lock(tid); + mutex->recursive = 1; mutex->m_mutex.unlock(tid, target); } } @@ -156,6 +159,7 @@ int sys_cond_signal_all(u32 cond_id) if (mutex->m_mutex.trylock(target) != SMR_OK) { mutex->m_mutex.lock(tid); + mutex->recursive = 1; mutex->m_mutex.unlock(tid, target); } } @@ -189,6 +193,7 @@ int sys_cond_signal_to(u32 cond_id, u32 thread_id) if (mutex->m_mutex.trylock(thread_id) != SMR_OK) { mutex->m_mutex.lock(tid); + mutex->recursive = 1; mutex->m_mutex.unlock(tid, thread_id); } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp index 8ec6903349..3c8af68051 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp @@ -7,10 +7,10 @@ SysCallBase sys_lwcond("sys_lwcond"); int sys_lwcond_create(mem_ptr_t lwcond, mem_ptr_t lwmutex, mem_ptr_t attr) { - sys_lwcond.Warning("sys_lwcond_create(lwcond_addr=0x%x, lwmutex_addr=0x%x, attr_addr=0x%x)", + sys_lwcond.Log("sys_lwcond_create(lwcond_addr=0x%x, lwmutex_addr=0x%x, attr_addr=0x%x)", lwcond.GetAddr(), lwmutex.GetAddr(), attr.GetAddr()); - if (!lwcond.IsGood() || !lwmutex.IsGood() || !attr.IsGood()) + if (!lwcond.IsGood() /*|| !lwmutex.IsGood()*/ || !attr.IsGood()) { return CELL_EFAULT; } @@ -18,13 +18,16 @@ int sys_lwcond_create(mem_ptr_t lwcond, mem_ptr_t l lwcond->lwmutex = lwmutex.GetAddr(); lwcond->lwcond_queue = sys_lwcond.GetNewId(new SleepQueue(attr->name_u64)); - if (lwmutex->attribute.ToBE() == se32(SYS_SYNC_RETRY)) + if (lwmutex.IsGood()) { - sys_lwcond.Warning("Unsupported SYS_SYNC_RETRY lwmutex protocol"); + if (lwmutex->attribute.ToBE() == se32(SYS_SYNC_RETRY)) + { + sys_lwcond.Warning("Unsupported SYS_SYNC_RETRY lwmutex protocol"); + } } - sys_lwcond.Warning("*** lwcond created [%s] (lwmutex.attr=0x%x): id = %d", - wxString(attr->name, 8).wx_str(), (u32)lwmutex->attribute, (u32)lwcond->lwcond_queue); + sys_lwcond.Warning("*** lwcond created [%s] (lwmutex_addr=0x%x): id = %d", + wxString(attr->name, 8).wx_str(), lwmutex.GetAddr(), (u32)lwcond->lwcond_queue); return CELL_OK; } @@ -78,6 +81,7 @@ int sys_lwcond_signal(mem_ptr_t lwcond) if (mutex->owner.trylock(target) != SMR_OK) { mutex->owner.lock(tid); + mutex->recursive_count = 1; mutex->owner.unlock(tid, target); } } @@ -113,6 +117,7 @@ int sys_lwcond_signal_all(mem_ptr_t lwcond) if (mutex->owner.trylock(target) != SMR_OK) { mutex->owner.lock(tid); + mutex->recursive_count = 1; mutex->owner.unlock(tid, target); } } @@ -153,6 +158,7 @@ int sys_lwcond_signal_to(mem_ptr_t lwcond, u32 ppu_thread_id) if (mutex->owner.trylock(target) != SMR_OK) { mutex->owner.lock(tid); + mutex->recursive_count = 1; mutex->owner.unlock(tid, target); } @@ -190,6 +196,7 @@ int sys_lwcond_wait(mem_ptr_t lwcond, u64 timeout) sq->push(tid_le); + mutex->recursive_count = 0; mutex->owner.unlock(tid); u32 counter = 0; @@ -204,6 +211,7 @@ int sys_lwcond_wait(mem_ptr_t lwcond, u64 timeout) if (mutex->owner.GetOwner() == tid) { _mm_mfence(); + mutex->recursive_count = 1; return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp index 331019093b..65dc341fa1 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp @@ -6,7 +6,7 @@ SysCallBase sc_lwmutex("sys_lwmutex"); int sys_lwmutex_create(mem_ptr_t lwmutex, mem_ptr_t attr) { - sc_lwmutex.Warning("sys_lwmutex_create(lwmutex_addr=0x%x, lwmutex_attr_addr=0x%x)", + sc_lwmutex.Log("sys_lwmutex_create(lwmutex_addr=0x%x, lwmutex_attr_addr=0x%x)", lwmutex.GetAddr(), attr.GetAddr()); if (!lwmutex.IsGood() || !attr.IsGood()) return CELL_EFAULT; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp index 3467c949f1..777130fefd 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp @@ -7,7 +7,7 @@ SysCallBase sys_mtx("sys_mutex"); int sys_mutex_create(mem32_t mutex_id, mem_ptr_t attr) { - sys_mtx.Warning("sys_mutex_create(mutex_id_addr=0x%x, attr_addr=0x%x)", mutex_id.GetAddr(), attr.GetAddr()); + sys_mtx.Log("sys_mutex_create(mutex_id_addr=0x%x, attr_addr=0x%x)", mutex_id.GetAddr(), attr.GetAddr()); if (!mutex_id.IsGood() || !attr.IsGood()) { @@ -38,8 +38,9 @@ int sys_mutex_create(mem32_t mutex_id, mem_ptr_t attr) } mutex_id = sys_mtx.GetNewId(new Mutex((u32)attr->protocol, is_recursive, attr->name_u64)); - sys_mtx.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%d): id = %d", - wxString(attr->name, 8).wx_str(), (u32)attr->protocol, is_recursive, mutex_id.GetValue()); + sys_mtx.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%s): id = %d", + wxString(attr->name, 8).wx_str(), (u32)attr->protocol, + wxString(is_recursive ? "true" : "false").wx_str(), mutex_id.GetValue()); return CELL_OK; } @@ -93,7 +94,7 @@ int sys_mutex_lock(u32 mutex_id, u64 timeout) { if (mutex->is_recursive) { - if (mutex->recursive++ == 0) + if (++mutex->recursive == 0) { return CELL_EKRESOURCE; } @@ -107,7 +108,7 @@ int sys_mutex_lock(u32 mutex_id, u64 timeout) switch (mutex->m_mutex.trylock(tid)) { - case SMR_OK: return CELL_OK; + case SMR_OK: mutex->recursive = 1; return CELL_OK; case SMR_FAILED: break; default: goto abort; } @@ -161,7 +162,7 @@ int sys_mutex_trylock(u32 mutex_id) switch (mutex->m_mutex.trylock(tid)) { - case SMR_OK: return CELL_OK; + case SMR_OK: mutex->recursive = 1; return CELL_OK; } return CELL_EBUSY; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp index dad727e32d..a3adbb1270 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp @@ -625,7 +625,6 @@ int sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup) { return CELL_ESRCH; } - /* for(int j=0; jpos; ++j) { @@ -656,9 +655,22 @@ int sys_spu_thread_throw_event(u8 spup, u24 data0, u32 data1); int sys_spu_thread_tryreceive_event(u32 spuq_num, mem32_t d1, mem32_t d2, mem32_t d3); */ -int sys_spu_thread_bind_queue(u32 id, u32 equeue_id, u32 spuq_num) +int sys_spu_thread_bind_queue(u32 id, u32 eq, u32 spuq_num) { - sc_spu.Error("sys_spu_thread_bind_queue(id=%d, equeue_id=%d, spuq_num=%d)", id, equeue_id, spuq_num); + sc_spu.Error("sys_spu_thread_bind_queue(id=%d, equeue_id=%d, spuq_num=%d)", id, eq, spuq_num); + + EventQueue* equeue; + if(!sys_event.CheckId(eq, equeue)) + { + return CELL_ESRCH; + } + + CPUThread* thr = Emu.GetCPU().GetThread(id); + + if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU)) + { + return CELL_ESRCH; + } return CELL_OK; } diff --git a/rpcs3/Gui/ConLog.cpp b/rpcs3/Gui/ConLog.cpp index c42f173364..ca658c0813 100644 --- a/rpcs3/Gui/ConLog.cpp +++ b/rpcs3/Gui/ConLog.cpp @@ -265,7 +265,7 @@ void LogFrame::Task() m_log.InsertItem(cur_item, wxString(item.m_prefix).wx_str()); m_log.SetItem(cur_item, 1, wxString(item.m_text).wx_str()); m_log.SetItemTextColour(cur_item, wxString(item.m_colour).wx_str()); - m_log.SetColumnWidth(0, -1); + m_log.SetColumnWidth(0, -1); // crashes on exit m_log.SetColumnWidth(1, -1); ::SendMessage((HWND)m_log.GetHWND(), WM_VSCROLL, SB_BOTTOM, 0); From 4375b9dd2a4d947d325e832a3e83dbb110987cb3 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 16 Feb 2014 19:23:58 +0400 Subject: [PATCH 4/5] Audio port output in .wav file --- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 122 ++++++++++++++++++++- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 7 +- rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 21 ++-- rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp | 10 +- rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp | 4 +- rpcs3/Emu/SysCalls/lv2/SC_Time.cpp | 35 ++++-- 6 files changed, 168 insertions(+), 31 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index b794ea53b5..65260d72eb 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -8,6 +8,8 @@ void cellAudio_load(); void cellAudio_unload(); Module cellAudio(0x0011, cellAudio_init, cellAudio_load, cellAudio_unload); +extern u64 get_system_time(); + enum { //libaudio Error Codes @@ -61,6 +63,56 @@ enum CELL_SOUND_SYNTH2_ERROR_ALREADY_INITIALIZED = 0x80310203, }; +struct WAVHeader +{ + struct RIFFHeader + { + u32 ID; // "RIFF" + u32 Size; // FileSize - 8 + u32 WAVE; // "WAVE" + + RIFFHeader(u32 size) + : ID(*(u32*)"RIFF") + , WAVE(*(u32*)"WAVE") + , Size(size) + { + } + } RIFF; + struct FMTHeader + { + u32 ID; // "fmt " + u32 Size; // 16 + u16 AudioFormat; // 1 for PCM, 3 for IEEE Floating Point + u16 NumChannels; // 1, 2, 6, 8 + u32 SampleRate; // 48000 + u32 ByteRate; // SampleRate * NumChannels * BitsPerSample/8 + u16 BlockAlign; // NumChannels * BitsPerSample/8 + u16 BitsPerSample; // sizeof(float) * 8 + + FMTHeader(u8 ch) + : ID(*(u32*)"fmt ") + , Size(16) + , AudioFormat(3) + , NumChannels(ch) + , SampleRate(48000) + , ByteRate(SampleRate * ch * sizeof(float)) + , BlockAlign(ch * sizeof(float)) + , BitsPerSample(sizeof(float) * 8) + { + } + } FMT; + u32 ID; // "data" + u32 Size; // size of data (256 * NumChannels * sizeof(float)) + + WAVHeader(u8 ch) + : ID(*(u32*)"data") + , Size(0) + , FMT(ch) + , RIFF(sizeof(RIFFHeader) + sizeof(FMTHeader)) + { + } +}; + //libaudio datatypes struct CellAudioPortParam @@ -368,16 +420,76 @@ int cellAudioPortStart(u32 portNum) thread t(t_name, [portNum]() { - AudioPortConfig& ref = *m_config.m_ports[portNum]; - mem64_t index(ref.m_index); + AudioPortConfig& port = *m_config.m_ports[portNum]; + mem64_t index(port.m_index); // index storage + + if (port.m_param.nChannel > 8) + { + ConLog.Error("Port aborted: invalid channel count (%d)", port.m_param.nChannel); + return; + } + + WAVHeader header(port.m_param.nChannel); // WAV file header + + wxString output_name = "audioport0.wav"; + output_name[9] = '0' + portNum; + + wxFile output(output_name, wxFile::write); // create output file + if (!output.IsOpened()) + { + ConLog.Error("Port aborted: cannot write %s", output_name.wx_str()); + return; + } ConLog.Write("Port started"); - while (ref.m_is_audio_port_started && !Emu.IsStopped()) + + u64 start_time = get_system_time(); + u32 counter = 0; + + output.Write(&header, sizeof(header)); // write file header + + const u32 block_size = port.m_param.nChannel * 256 * sizeof(float); + + u32 buffer[32*256]; // buffer for max channel count (8) + + while (port.m_is_audio_port_started) { - Sleep(5); - index = (index.GetValue() + 1) % ref.m_param.nBlock; + // Sleep(5); // precise time of sleeping: 5,(3) ms (or 256/48000 sec) + if ((u64)counter * 256000000 / 48000 >= get_system_time() - start_time) + { + Sleep(1); + continue; + } + + counter++; + + u32 position = index.GetValue(); // get old value + + memcpy(buffer, Memory + port.m_buffer + position * block_size, block_size); + + index = (position + 1) % port.m_param.nBlock; // write new value + + for (u32 i = 0; i < block_size; i++) + { + buffer[i] = re(buffer[i]); // reverse byte order + } + + output.Write(&buffer, block_size); // write file data + header.Size += block_size; // update file header + header.RIFF.Size += block_size; + + if (Emu.IsStopped()) + { + ConLog.Warning("Port aborted"); + goto abort; + } } ConLog.Write("Port finished"); + abort: + output.Seek(0); + output.Write(&header, sizeof(header)); // write fixed file header + + output.Close(); }); t.detach(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 2ce2fd58cf..355cc277ff 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -463,9 +463,14 @@ int cellSysutilCheckCallback() CPUThread& thr = Emu.GetCallbackThread(); - while (Emu.IsRunning() && thr.IsAlive()) + while (thr.IsAlive()) { Sleep(1); + if (Emu.IsStopped()) + { + ConLog.Warning("cellSysutilCheckCallback() aborted"); + break; + } } return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 33bc0b1b80..ac29d660f5 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -5,8 +5,6 @@ void sys_fs_init(); Module sys_fs(0x000e, sys_fs_init); -std::atomic g_FsAioReadID = 0; - bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp) { if (version > 4 || flags & 0x7EFFFFC0){ @@ -137,12 +135,21 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) return CELL_OK; } -SMutex aio_mutex; +std::atomic g_FsAioReadID = 0; +std::atomic g_FsAioReadCur = 0; bool aio_init; void fsAioRead(u32 fd, mem_ptr_t aio, int xid, mem_func_ptr_t xaio, u32 error, int xid, u64 size)> func) { - //SMutexLocker lock (aio_mutex); + while (g_FsAioReadCur != xid) + { + Sleep(1); + if (Emu.IsStopped()) + { + ConLog.Warning("fsAioRead() aborted"); + return; + } + } vfsFileBase* orig_file; if(!sys_fs.CheckId(fd, orig_file)) return; @@ -186,6 +193,8 @@ void fsAioRead(u32 fd, mem_ptr_t aio, int xid, mem_func_ptr_t aio, mem32_t aio_id, mem_func_ptr_t xaio, u32 error, int xid, u64 size)> func) @@ -199,7 +208,7 @@ int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, mem_func_ptr_t aio, mem32_t aio_id, mem_func_ptr_t attr) wxString(attr->name, 8).wx_str(), (u32)attr->protocol, wxString(is_recursive ? "true" : "false").wx_str(), mutex_id.GetValue()); + // TODO: unlock mutex when owner thread does exit + return CELL_OK; } int sys_mutex_destroy(u32 mutex_id) { - sys_mtx.Warning("sys_mutex_destroy(mutex_id=0x%x)", mutex_id); + sys_mtx.Warning("sys_mutex_destroy(mutex_id=%d)", mutex_id); Mutex* mutex; if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) @@ -80,7 +82,7 @@ int sys_mutex_destroy(u32 mutex_id) int sys_mutex_lock(u32 mutex_id, u64 timeout) { - sys_mtx.Log("sys_mutex_lock(mutex_id=0x%x, timeout=0x%llx)", mutex_id, timeout); + sys_mtx.Log("sys_mutex_lock(mutex_id=%d, timeout=0x%llx)", mutex_id, timeout); Mutex* mutex; if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) @@ -134,7 +136,7 @@ abort: int sys_mutex_trylock(u32 mutex_id) { - sys_mtx.Log("sys_mutex_trylock(mutex_id=0x%x)", mutex_id); + sys_mtx.Log("sys_mutex_trylock(mutex_id=%d)", mutex_id); Mutex* mutex; if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) @@ -170,7 +172,7 @@ int sys_mutex_trylock(u32 mutex_id) int sys_mutex_unlock(u32 mutex_id) { - sys_mtx.Log("sys_mutex_unlock(mutex_id=0x%x)", mutex_id); + sys_mtx.Log("sys_mutex_unlock(mutex_id=%d)", mutex_id); Mutex* mutex; if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp index c70d43838d..e4259ab0f1 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp @@ -247,12 +247,12 @@ int cellPadSetPortSetting(u32 port_no, u32 port_setting) int cellPadInfoPressMode(u32 port_no) { - sys_io.Log("cellPadInfoPressMode(port_no=%d)", port_no); + sys_io.Error("cellPadInfoPressMode(port_no=%d)", port_no); return CELL_OK; } int cellPadInfoSensorMode(u32 port_no) { - sys_io.Log("cellPadInfoSensorMode(port_no=%d)", port_no); + sys_io.Error("cellPadInfoSensorMode(port_no=%d)", port_no); return CELL_OK; } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Time.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Time.cpp index f6b7c7912a..045a17172f 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Time.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Time.cpp @@ -10,7 +10,8 @@ #include SysCallBase sys_time("sys_time"); -static const u64 timebase_frequency = 79800000; + +//static const u64 timebase_frequency = 79800000; extern int cellSysutilGetSystemParamInt(int id, mem32_t value); int sys_time_get_timezone(mem32_t timezone, mem32_t summertime) @@ -23,11 +24,26 @@ int sys_time_get_timezone(mem32_t timezone, mem32_t summertime) return CELL_OK; } +u64 get_system_time() +{ +#ifdef _WIN32 + LARGE_INTEGER cycle; + LARGE_INTEGER freq; + QueryPerformanceCounter(&cycle); + QueryPerformanceFrequency(&freq); + return cycle.QuadPart * 1000000 / freq.QuadPart; +#else + struct timespec ts; + if (!clock_gettime(CLOCK_MONOTONIC, &ts)) + return ts.tv_sec * (s64)10000000 + (s64)ts.tv_nsec / (s64)100; +#endif +} + int sys_time_get_current_time(u32 sec_addr, u32 nsec_addr) { sys_time.Log("sys_time_get_current_time(sec_addr=0x%x, nsec_addr=0x%x)", sec_addr, nsec_addr); - u64 time = sys_time_get_system_time(); + u64 time = get_system_time(); Memory.Write64(sec_addr, time / 1000000); Memory.Write64(nsec_addr, time % 1000000); @@ -38,21 +54,15 @@ int sys_time_get_current_time(u32 sec_addr, u32 nsec_addr) s64 sys_time_get_system_time() { sys_time.Log("sys_time_get_system_time()"); -#ifdef _WIN32 - LARGE_INTEGER cycle; - QueryPerformanceCounter(&cycle); - return cycle.QuadPart; -#else - struct timespec ts; - if (!clock_gettime(CLOCK_MONOTONIC, &ts)) - return ts.tv_sec * (s64)10000000 + (s64)ts.tv_nsec / (s64)100; -#endif + return get_system_time(); } u64 sys_time_get_timebase_frequency() { sys_time.Log("sys_time_get_timebase_frequency()"); + return 1000000; + /* #ifdef _WIN32 static LARGE_INTEGER frequency = {0ULL}; @@ -60,6 +70,7 @@ u64 sys_time_get_timebase_frequency() return frequency.QuadPart; #else - return 10000000; + return 10000000; #endif + */ } From d849e083b65688ca009c813fd7a54ab7bd94045d Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 18 Feb 2014 22:45:51 +0400 Subject: [PATCH 5/5] Small changes --- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 49 +++++++++++++++++++----- rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp | 5 +++ rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp | 7 ++++ rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp | 10 ++++- rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp | 6 +++ 5 files changed, 66 insertions(+), 11 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 430694380a..84a3b735c6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -136,6 +136,7 @@ struct CellAudioPortConfig struct AudioPortConfig { bool m_is_audio_port_started; + bool m_is_audio_port_stopped; CellAudioPortParam m_param; const u32 m_buffer; // 64 KB or 128 KB with 8x16 config @@ -414,6 +415,7 @@ int cellAudioPortStart(u32 portNum) } m_config.m_ports[portNum]->m_is_audio_port_started = true; + m_config.m_ports[portNum]->m_is_audio_port_stopped = false; std::string t_name = "AudioPort0"; t_name[9] += portNum; @@ -426,6 +428,7 @@ int cellAudioPortStart(u32 portNum) if (port.m_param.nChannel > 8) { ConLog.Error("Port aborted: invalid channel count (%d)", port.m_param.nChannel); + port.m_is_audio_port_stopped = true; return; } @@ -437,14 +440,15 @@ int cellAudioPortStart(u32 portNum) wxFile output(output_name, wxFile::write); // create output file if (!output.IsOpened()) { - ConLog.Error("Port aborted: cannot write %s", output_name.wx_str()); + ConLog.Error("Port aborted: cannot create %s", output_name.wx_str()); + port.m_is_audio_port_stopped = true; return; } ConLog.Write("Port started"); u64 start_time = get_system_time(); - u32 counter = 0; + u64 counter = 0; output.Write(&header, sizeof(header)); // write file header @@ -454,8 +458,16 @@ int cellAudioPortStart(u32 portNum) while (port.m_is_audio_port_started) { + if (Emu.IsStopped()) + { + ConLog.Warning("Port aborted"); + goto abort; + } + + // TODO: send beforemix event (in ~2,6 ms before mixing) + // Sleep(5); // precise time of sleeping: 5,(3) ms (or 256/48000 sec) - if ((u64)counter * 256000000 / 48000 >= get_system_time() - start_time) + if (counter * 256000000 / 48000 >= get_system_time() - start_time) { Sleep(1); continue; @@ -463,27 +475,34 @@ int cellAudioPortStart(u32 portNum) counter++; + if (Emu.IsPaused()) + { + continue; + } + u32 position = index.GetValue(); // get old value memcpy(buffer, Memory + port.m_buffer + position * block_size, block_size); + memset(Memory + port.m_buffer + position * block_size, 0, block_size); index = (position + 1) % port.m_param.nBlock; // write new value + // TODO: send aftermix event (normal audio event) + for (u32 i = 0; i < block_size; i++) { // reverse byte order (TODO: use port.m_param.level) buffer[i] = re(buffer[i]); } - output.Write(&buffer, block_size); // write file data - header.Size += block_size; // update file header - header.RIFF.Size += block_size; - - if (Emu.IsStopped()) + if (output.Write(&buffer, block_size) != (size_t)block_size) // write file data { - ConLog.Write("Port aborted"); + ConLog.Error("Port aborted: cannot write %s", output_name.wx_str()); goto abort; } + + header.Size += block_size; // update file header + header.RIFF.Size += block_size; } ConLog.Write("Port finished"); abort: @@ -491,6 +510,7 @@ int cellAudioPortStart(u32 portNum) output.Write(&header, sizeof(header)); // write fixed file header output.Close(); + port.m_is_audio_port_stopped = true; }); t.detach(); @@ -535,7 +555,16 @@ int cellAudioPortStop(u32 portNum) return CELL_AUDIO_ERROR_PORT_NOT_RUN; } - m_config.m_ports[portNum]->m_is_audio_port_started = false; + m_config.m_ports[portNum]->m_is_audio_port_started = false; + while (!m_config.m_ports[portNum]->m_is_audio_port_stopped) + { + Sleep(1); + if (Emu.IsStopped()) + { + ConLog.Warning("cellAudioPortStop(%d) aborted", portNum); + break; + } + } return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp index f26061e19f..650673abf9 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp @@ -26,6 +26,11 @@ int sys_cond_create(mem32_t cond_id, u32 mutex_id, mem_ptr_t return CELL_ESRCH; } + if (mutex->is_recursive) + { + sys_cond.Warning("Recursive mutex(%d)", mutex_id); + } + Cond* cond = new Cond(mutex, attr->name_u64); u32 id = sys_cond.GetNewId(cond); cond_id = id; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index 7ec0e6f3c8..fde9c0f339 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -216,6 +216,13 @@ int cellFsStat(const u32 path_addr, mem_ptr_t sb) } } + if (path == "/dev_bdvd/PS3_GAME/USRDIR") + { + sys_fs.Warning("cellFsStat: /dev_bdvd/PS3_GAME/USRDIR mount point hack"); + sb->st_mode |= CELL_FS_S_IFDIR; + return CELL_OK; + } + // TODO: Temporary solution until vfsDir is implemented wxString real_path; Emu.GetVFS().GetDevice(path, real_path); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp index 3c8af68051..89dd8c7409 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp @@ -20,10 +20,18 @@ int sys_lwcond_create(mem_ptr_t lwcond, mem_ptr_t l if (lwmutex.IsGood()) { - if (lwmutex->attribute.ToBE() == se32(SYS_SYNC_RETRY)) + if (lwmutex->attribute.ToBE() & se32(SYS_SYNC_RETRY)) { sys_lwcond.Warning("Unsupported SYS_SYNC_RETRY lwmutex protocol"); } + if (lwmutex->attribute.ToBE() & se32(SYS_SYNC_RECURSIVE)) + { + sys_lwcond.Warning("Recursive lwmutex(sq=%d)", (u32)lwmutex->sleep_queue); + } + } + else + { + sys_lwcond.Warning("Invalid lwmutex address(0x%x)", lwmutex.GetAddr()); } sys_lwcond.Warning("*** lwcond created [%s] (lwmutex_addr=0x%x): id = %d", diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp index 65dc341fa1..db07fbed3b 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp @@ -67,6 +67,9 @@ int sys_lwmutex_lock(mem_ptr_t lwmutex, u64 timeout) if (!lwmutex.IsGood()) return CELL_EFAULT; + //ConLog.Write("*** lock mutex (addr=0x%x, attr=0x%x, Nrec=%d, owner=%d, waiter=%d)", + //lwmutex.GetAddr(), (u32)lwmutex->attribute, (u32)lwmutex->recursive_count, lwmutex->owner.GetOwner(), (u32)lwmutex->waiter); + return lwmutex->lock(GetCurrentPPUThread().GetId(), timeout ? ((timeout < 1000) ? 1 : (timeout / 1000)) : 0); } @@ -85,6 +88,9 @@ int sys_lwmutex_unlock(mem_ptr_t lwmutex) if (!lwmutex.IsGood()) return CELL_EFAULT; + //ConLog.Write("*** unlocking mutex (addr=0x%x, attr=0x%x, Nrec=%d, owner=%d, waiter=%d)", + //lwmutex.GetAddr(), (u32)lwmutex->attribute, (u32)lwmutex->recursive_count, (u32)lwmutex->owner.GetOwner(), (u32)lwmutex->waiter); + return lwmutex->unlock(GetCurrentPPUThread().GetId()); }