cond/lwcond fixed

This commit is contained in:
Nekotekina 2014-02-26 14:35:30 +04:00
parent 0bd5dc5363
commit 8048c70bc8
4 changed files with 186 additions and 112 deletions

View File

@ -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)
{

View File

@ -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<CellCodecEsFilterId> 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);

View File

@ -28,7 +28,7 @@ int sys_cond_create(mem32_t cond_id, u32 mutex_id, mem_ptr_t<sys_cond_attribute>
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;
}

View File

@ -84,14 +84,23 @@ int sys_lwcond_signal(mem_ptr_t<sys_lwcond_t> lwcond)
mem_ptr_t<sys_lwmutex_t> mutex(lwcond->lwmutex);
be_t<u32> tid = GetCurrentPPUThread().GetId();
bool was_locked = (mutex->owner.GetOwner() == tid);
if (be_t<u32> 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<sys_lwcond_t> lwcond)
mem_ptr_t<sys_lwmutex_t> mutex(lwcond->lwmutex);
be_t<u32> tid = GetCurrentPPUThread().GetId();
bool was_locked = (mutex->owner.GetOwner() == tid);
while (be_t<u32> 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<sys_lwcond_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<sys_lwcond_t> lwcond, u32 ppu_thread_id)
mem_ptr_t<sys_lwmutex_t> mutex(lwcond->lwmutex);
be_t<u32> tid = GetCurrentPPUThread().GetId();
be_t<u32> target = ppu_thread_id;
bool was_locked = (mutex->owner.GetOwner() == tid);
if (mutex->owner.trylock(target) != SMR_OK)
be_t<u32> 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())