sys_lwmutex/lwcond: track lwcond waiters (#7826)

In lwmutex destroy syscall, wait for pending waiters.
This commit is contained in:
Eladash 2020-03-23 09:30:17 +02:00 committed by GitHub
parent 9de9ec1f01
commit cccc32fa9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 111 additions and 23 deletions

View file

@ -140,7 +140,7 @@ error_code _sys_lwcond_signal(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id, u3
{
verify(HERE), !mutex->signaled;
std::lock_guard lock(mutex->mutex);
mutex->sq.emplace_back(result);
verify(HERE), mutex->add_waiter(result);
}
else
{
@ -228,7 +228,7 @@ error_code _sys_lwcond_signal_all(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
{
verify(HERE), !mutex->signaled;
std::lock_guard lock(mutex->mutex);
mutex->sq.emplace_back(cpu);
verify(HERE), mutex->add_waiter(cpu);
}
else
{
@ -283,6 +283,23 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
return;
}
// Try to increment lwmutex's lwcond's waiters count
if (!mutex->lwcond_waiters.fetch_op([](s32& val)
{
if (val == INT32_MIN)
{
return false;
}
val++;
return true;
}).second)
{
// Failed - lwmutex was detroyed and all waiters have quit
mutex.reset();
return;
}
std::lock_guard lock(cond.mutex);
// Add a waiter
@ -343,6 +360,12 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
}
}
if (--mutex->lwcond_waiters == INT32_MIN)
{
// Notify the thread destroying lwmutex on last waiter
mutex->lwcond_waiters.notify_all();
}
// Return cause
return not_an_error(ppu.gpr[3]);
}