sys_cond: Fix spurious EBUSY in sys_cond_destroy

Increment waiters count inside IDM's mutex lock scope.
This commit is contained in:
Eladash 2020-06-04 13:27:25 +03:00 committed by Ivan
parent a0f0f58fc5
commit 314dc4c5de

View File

@ -205,16 +205,35 @@ error_code sys_cond_wait(ppu_thread& ppu, u32 cond_id, u64 timeout)
sys_cond.trace("sys_cond_wait(cond_id=0x%x, timeout=%lld)", cond_id, timeout); sys_cond.trace("sys_cond_wait(cond_id=0x%x, timeout=%lld)", cond_id, timeout);
const auto cond = idm::get<lv2_obj, lv2_cond>(cond_id, [&](lv2_cond& cond) // Further function result
ppu.gpr[3] = CELL_OK;
const auto cond = idm::get<lv2_obj, lv2_cond>(cond_id, [&](lv2_cond& cond) -> s64
{ {
if (cond.mutex->owner >> 1 == ppu.id) if (cond.mutex->owner >> 1 != ppu.id)
{ {
// Add a "promise" to add a waiter return -1;
cond.waiters++;
} }
std::lock_guard lock(cond.mutex->mutex);
// Register waiter
cond.sq.emplace_back(&ppu);
cond.waiters++;
// Unlock the mutex
const auto count = cond.mutex->lock_count.exchange(0);
if (auto cpu = cond.mutex->reown<ppu_thread>())
{
cond.mutex->append(cpu);
}
// Sleep current thread and schedule mutex waiter
cond.sleep(ppu, timeout);
// Save the recursive value // Save the recursive value
return cond.mutex->lock_count.load(); return count;
}); });
if (!cond) if (!cond)
@ -222,32 +241,10 @@ error_code sys_cond_wait(ppu_thread& ppu, u32 cond_id, u64 timeout)
return CELL_ESRCH; return CELL_ESRCH;
} }
// Verify ownership if (cond.ret < 0)
if (cond->mutex->owner >> 1 != ppu.id)
{ {
return CELL_EPERM; return CELL_EPERM;
} }
else
{
// Further function result
ppu.gpr[3] = CELL_OK;
std::lock_guard lock(cond->mutex->mutex);
// Register waiter
cond->sq.emplace_back(&ppu);
// Unlock the mutex
cond->mutex->lock_count = 0;
if (auto cpu = cond->mutex->reown<ppu_thread>())
{
cond->mutex->append(cpu);
}
// Sleep current thread and schedule mutex waiter
cond->sleep(ppu, timeout);
}
while (!ppu.state.test_and_reset(cpu_flag::signal)) while (!ppu.state.test_and_reset(cpu_flag::signal))
{ {