diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index ecf52c7c49..e25cb587b9 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -135,6 +135,7 @@ struct CellAudioPortConfig struct AudioPortConfig { + SMutex m_mutex; bool m_is_audio_port_opened; bool m_is_audio_port_started; u8 channel; @@ -366,10 +367,12 @@ int cellAudioInit() memcpy(buffer2, Memory + buf_addr, block_size * sizeof(float)); memset(Memory + buf_addr, 0, block_size * sizeof(float)); - // TODO: atomic - port.counter = m_config.counter; - port.tag++; // absolute index of block that will be read - index = (position + 1) % port.block; // write new value + { + SMutexLocker lock(port.m_mutex); + port.counter = m_config.counter; + port.tag++; // absolute index of block that will be read + index = (position + 1) % port.block; // write new value + } if (first_mix) { @@ -599,7 +602,7 @@ int cellAudioPortStop(u32 portNum) int cellAudioGetPortTimestamp(u32 portNum, u64 tag, mem64_t stamp) { - cellAudio.Warning("cellAudioGetPortTimestamp(portNum=0x%x, tag=0x%llx, stamp_addr=0x%x)", portNum, tag, stamp.GetAddr()); + cellAudio.Log("cellAudioGetPortTimestamp(portNum=0x%x, tag=0x%llx, stamp_addr=0x%x)", portNum, tag, stamp.GetAddr()); if (portNum >= m_config.AUDIO_PORT_COUNT) { @@ -618,7 +621,8 @@ int cellAudioGetPortTimestamp(u32 portNum, u64 tag, mem64_t stamp) AudioPortConfig& port = m_config.m_ports[portNum]; - // TODO: atomic + SMutexLocker lock(port.m_mutex); + stamp = m_config.start_time + (port.counter + (tag - port.tag)) * 256000000 / 48000; return CELL_OK; @@ -626,7 +630,7 @@ int cellAudioGetPortTimestamp(u32 portNum, u64 tag, mem64_t stamp) int cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, mem64_t tag) { - cellAudio.Warning("cellAudioGetPortBlockTag(portNum=0x%x, blockNo=0x%llx, tag_addr=0x%x)", portNum, blockNo, tag.GetAddr()); + cellAudio.Log("cellAudioGetPortBlockTag(portNum=0x%x, blockNo=0x%llx, tag_addr=0x%x)", portNum, blockNo, tag.GetAddr()); if (portNum >= m_config.AUDIO_PORT_COUNT) { @@ -651,7 +655,8 @@ int cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, mem64_t tag) return CELL_AUDIO_ERROR_PARAM; } - // TODO: atomic + SMutexLocker lock(port.m_mutex); + u64 tag_base = port.tag; if (tag_base % port.block > blockNo) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index b7b81bef2c..fe558d0ae8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -149,7 +149,7 @@ u32 dmuxOpen(Demuxer* data) if (pes.size) { - //ConLog.Write("*** AVC AU detected (pts=0x%x, dts=0x%x)", pes.pts, pes.dts); + ConLog.Write("*** AVC AU detected (pts=0x%x, dts=0x%x)", pes.pts, pes.dts); } es.push(stream, len - pes.size - 3, pes); @@ -658,6 +658,7 @@ int cellDmuxEnableEs(u32 demuxerHandle, const mem_ptr_t esF u32 id = cellDmux.GetNewId(es); es->id = id; + esHandle = id; cellDmux.Warning("*** New ES(dmux=%d, addr=0x%x, size=0x%x, filter(0x%x, 0x%x, 0x%x, 0x%x), cb=0x%x(arg=0x%x), spec=0x%x): id = %d", demuxerHandle, es->memAddr, es->memSize, es->fidMajor, es->fidMinor, es->sup1, es->sup2, (u32)esCb->cbEsMsgFunc, es->cbArg, es->spec, id); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp index 051653afdf..97555928d8 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp @@ -28,7 +28,7 @@ int sys_cond_create(mem32_t cond_id, u32 mutex_id, mem_ptr_t if (mutex->is_recursive) { - sys_cond.Warning("Recursive mutex(%d)", mutex_id); + sys_cond.Warning("*** condition on recursive mutex(%d)", mutex_id); } Cond* cond = new Cond(mutex, attr->name_u64); @@ -60,6 +60,136 @@ int sys_cond_destroy(u32 cond_id) return CELL_OK; } +int sys_cond_signal(u32 cond_id) +{ + sys_cond.Log("sys_cond_signal(cond_id=%d)", cond_id); + + Cond* cond; + if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + { + return CELL_ESRCH; + } + + Mutex* mutex = cond->mutex; + u32 tid = GetCurrentPPUThread().GetId(); + + bool was_locked = (mutex->m_mutex.GetOwner() == tid); + + if (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop())) + { + if (!was_locked) // mutex hasn't been locked (don't care about mutex state) + { + mutex->m_mutex.lock(tid); + mutex->recursive = 1; + mutex->m_mutex.unlock(tid, target); + } + else // mutex has been locked (should preserve original mutex state) + { + mutex->recursive = 1; + mutex->m_mutex.unlock(tid, target); + mutex->m_mutex.lock(tid); + mutex->recursive = 1; + } + } + + 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.Log("sys_cond_signal_all(cond_id=%d)", cond_id); + + Cond* cond; + if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + { + return CELL_ESRCH; + } + + Mutex* mutex = cond->mutex; + u32 tid = GetCurrentPPUThread().GetId(); + + bool was_locked = (mutex->m_mutex.GetOwner() == tid); + + while (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop())) + { + if (!was_locked) + { + mutex->m_mutex.lock(tid); + mutex->recursive = 1; + mutex->m_mutex.unlock(tid, target); + } + else + { + mutex->recursive = 1; + mutex->m_mutex.unlock(tid, target); + mutex->m_mutex.lock(tid); + mutex->recursive = 1; + } + } + + 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.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 (!Emu.GetIdManager().CheckID(thread_id)) + { + return CELL_ESRCH; + } + + if (!cond->m_queue.invalidate(thread_id)) + { + return CELL_EPERM; + } + + Mutex* mutex = cond->mutex; + u32 tid = GetCurrentPPUThread().GetId(); + + bool was_locked = (mutex->m_mutex.GetOwner() == tid); + + u32 target = thread_id; + { + if (!was_locked) + { + mutex->m_mutex.lock(tid); + mutex->recursive = 1; + mutex->m_mutex.unlock(tid, target); + } + else + { + mutex->recursive = 1; + mutex->m_mutex.unlock(tid, target); + mutex->m_mutex.lock(tid); + mutex->recursive = 1; + } + } + + if (Emu.IsStopped()) + { + ConLog.Warning("sys_cond_signal_to(id=%d, to=%d) aborted", cond_id, thread_id); + } + + return CELL_OK; +} + int sys_cond_wait(u32 cond_id, u64 timeout) { sys_cond.Log("sys_cond_wait(cond_id=%d, timeout=%lld)", cond_id, timeout); @@ -113,99 +243,4 @@ int sys_cond_wait(u32 cond_id, u64 timeout) return CELL_OK; } } -} - -int sys_cond_signal(u32 cond_id) -{ - sys_cond.Log("sys_cond_signal(cond_id=%d)", cond_id); - - Cond* cond; - if (!Emu.GetIdManager().GetIDData(cond_id, cond)) - { - return CELL_ESRCH; - } - - 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->recursive = 1; - 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.Log("sys_cond_signal_all(cond_id=%d)", cond_id); - - Cond* cond; - if (!Emu.GetIdManager().GetIDData(cond_id, cond)) - { - return CELL_ESRCH; - } - - 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->recursive = 1; - 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.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->recursive = 1; - 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_Lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp index fc367333a3..e071687992 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp @@ -84,14 +84,23 @@ int sys_lwcond_signal(mem_ptr_t lwcond) mem_ptr_t mutex(lwcond->lwmutex); be_t tid = GetCurrentPPUThread().GetId(); + bool was_locked = (mutex->owner.GetOwner() == tid); + if (be_t target = (mutex->attribute.ToBE() == se32(SYS_SYNC_PRIORITY) ? sq->pop_prio() : sq->pop())) { - if (mutex->owner.trylock(target) != SMR_OK) + if (!was_locked) { mutex->owner.lock(tid); mutex->recursive_count = 1; mutex->owner.unlock(tid, target); } + else + { + mutex->recursive_count = 1; + mutex->owner.unlock(tid, target); + mutex->owner.lock(tid); + mutex->recursive_count = 1; + } } if (Emu.IsStopped()) @@ -120,14 +129,23 @@ int sys_lwcond_signal_all(mem_ptr_t lwcond) mem_ptr_t mutex(lwcond->lwmutex); be_t tid = GetCurrentPPUThread().GetId(); + bool was_locked = (mutex->owner.GetOwner() == tid); + while (be_t target = (mutex->attribute.ToBE() == se32(SYS_SYNC_PRIORITY) ? sq->pop_prio() : sq->pop())) { - if (mutex->owner.trylock(target) != SMR_OK) + if (!was_locked) { mutex->owner.lock(tid); mutex->recursive_count = 1; mutex->owner.unlock(tid, target); } + else + { + mutex->recursive_count = 1; + mutex->owner.unlock(tid, target); + mutex->owner.lock(tid); + mutex->recursive_count = 1; + } } if (Emu.IsStopped()) @@ -153,6 +171,11 @@ int sys_lwcond_signal_to(mem_ptr_t lwcond, u32 ppu_thread_id) return CELL_ESRCH; } + if (!Emu.GetIdManager().CheckID(ppu_thread_id)) + { + return CELL_ESRCH; + } + if (!sq->invalidate(ppu_thread_id)) { return CELL_EPERM; @@ -161,13 +184,23 @@ int sys_lwcond_signal_to(mem_ptr_t lwcond, u32 ppu_thread_id) mem_ptr_t mutex(lwcond->lwmutex); be_t tid = GetCurrentPPUThread().GetId(); - be_t target = ppu_thread_id; + bool was_locked = (mutex->owner.GetOwner() == tid); - if (mutex->owner.trylock(target) != SMR_OK) + be_t target = ppu_thread_id; { - mutex->owner.lock(tid); - mutex->recursive_count = 1; - mutex->owner.unlock(tid, target); + if (!was_locked) + { + mutex->owner.lock(tid); + mutex->recursive_count = 1; + mutex->owner.unlock(tid, target); + } + else + { + mutex->recursive_count = 1; + mutex->owner.unlock(tid, target); + mutex->owner.lock(tid); + mutex->recursive_count = 1; + } } if (Emu.IsStopped())