lv2: Wait for rescheduling before confirming timeouts (#7875)

This commit is contained in:
Eladash 2020-03-28 06:16:59 +03:00 committed by GitHub
parent d96dabcd60
commit 66bd8308d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 84 additions and 26 deletions

View File

@ -291,12 +291,17 @@ error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_e
{
if (lv2_obj::wait_timeout(timeout, &ppu))
{
// Wait for rescheduling
if (ppu.check_state())
{
return 0;
}
std::lock_guard lock(queue->mutex);
if (!queue->unqueue(queue->sq, &ppu))
{
timeout = 0;
continue;
break;
}
ppu.gpr[3] = CELL_ETIMEDOUT;

View File

@ -170,12 +170,17 @@ error_code sys_event_flag_wait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode, vm
{
if (lv2_obj::wait_timeout(timeout, &ppu))
{
// Wait for rescheduling
if (ppu.check_state())
{
return 0;
}
std::lock_guard lock(flag->mutex);
if (!flag->unqueue(flag->sq, &ppu))
{
timeout = 0;
continue;
break;
}
flag->waiters--;

View File

@ -356,19 +356,32 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
{
if (lv2_obj::wait_timeout(timeout, &ppu))
{
std::lock_guard lock(cond->mutex);
if (!cond->unqueue(cond->sq, &ppu))
// Wait for rescheduling
if (ppu.check_state())
{
timeout = 0;
continue;
return 0;
}
cond->waiters--;
std::lock_guard lock(cond->mutex);
if (cond->unqueue(cond->sq, &ppu))
{
cond->waiters--;
ppu.gpr[3] = CELL_ETIMEDOUT;
break;
}
std::lock_guard lock2(mutex->mutex);
if (std::find(mutex->sq.cbegin(), mutex->sq.cend(), &ppu) == mutex->sq.cend())
{
break;
}
mutex->sleep(ppu);
timeout = 0;
continue;
}
}
else
{

View File

@ -164,12 +164,17 @@ error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout)
{
if (lv2_obj::wait_timeout(timeout, &ppu))
{
// Wait for rescheduling
if (ppu.check_state())
{
return 0;
}
std::lock_guard lock(mutex->mutex);
if (!mutex->unqueue(mutex->sq, &ppu))
{
timeout = 0;
continue;
break;
}
ppu.gpr[3] = CELL_ETIMEDOUT;

View File

@ -164,12 +164,17 @@ error_code sys_mutex_lock(ppu_thread& ppu, u32 mutex_id, u64 timeout)
{
if (lv2_obj::wait_timeout(timeout, &ppu))
{
// Wait for rescheduling
if (ppu.check_state())
{
return 0;
}
std::lock_guard lock(mutex->mutex);
if (!mutex->unqueue(mutex->sq, &ppu))
{
timeout = 0;
continue;
break;
}
ppu.gpr[3] = CELL_ETIMEDOUT;

View File

@ -1889,12 +1889,17 @@ error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr<sys_net_pollfd> fds, s32 n
{
if (lv2_obj::wait_timeout(timeout, &ppu))
{
// Wait for rescheduling
if (ppu.check_state())
{
return 0;
}
std::lock_guard nw_lock(g_fxo->get<network_context>()->s_nw_mutex);
if (signaled)
{
timeout = 0;
continue;
break;
}
network_clear_queue(ppu);
@ -2080,12 +2085,17 @@ error_code sys_net_bnet_select(ppu_thread& ppu, s32 nfds, vm::ptr<sys_net_fd_set
{
if (lv2_obj::wait_timeout(timeout, &ppu))
{
// Wait for rescheduling
if (ppu.check_state())
{
return 0;
}
std::lock_guard nw_lock(g_fxo->get<network_context>()->s_nw_mutex);
if (signaled)
{
timeout = 0;
continue;
break;
}
network_clear_queue(ppu);

View File

@ -139,12 +139,17 @@ error_code sys_rwlock_rlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout)
{
if (lv2_obj::wait_timeout(timeout, &ppu))
{
// Wait for rescheduling
if (ppu.check_state())
{
return 0;
}
std::lock_guard lock(rwlock->mutex);
if (!rwlock->unqueue(rwlock->rq, &ppu))
{
timeout = 0;
continue;
break;
}
ppu.gpr[3] = CELL_ETIMEDOUT;
@ -336,12 +341,17 @@ error_code sys_rwlock_wlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout)
{
if (lv2_obj::wait_timeout(timeout, &ppu))
{
// Wait for rescheduling
if (ppu.check_state())
{
return 0;
}
std::lock_guard lock(rwlock->mutex);
if (!rwlock->unqueue(rwlock->wq, &ppu))
{
timeout = 0;
continue;
break;
}
// If the last waiter quit the writer sleep queue, wake blocked readers

View File

@ -130,12 +130,17 @@ error_code sys_semaphore_wait(ppu_thread& ppu, u32 sem_id, u64 timeout)
{
if (lv2_obj::wait_timeout(timeout, &ppu))
{
// Wait for rescheduling
if (ppu.check_state())
{
return 0;
}
std::lock_guard lock(sem->mutex);
if (!sem->unqueue(sem->sq, &ppu))
{
timeout = 0;
continue;
break;
}
verify(HERE), 0 > sem->val.fetch_op([](s32& val)