Fix _sys_lwcond_signal, _sys_lwcond_signal_all

This commit is contained in:
Nekotekina 2017-07-29 21:24:57 +03:00
parent 93db420f80
commit bf14cbdb27
2 changed files with 21 additions and 12 deletions

View File

@ -24,7 +24,7 @@ error_code _sys_lwcond_create(vm::ptr<u32> lwcond_id, u32 lwmutex_id, vm::ptr<sy
return CELL_ESRCH;
}
if (const u32 id = idm::make<lv2_obj, lv2_lwcond>(name, lwmutex_id))
if (const u32 id = idm::make<lv2_obj, lv2_lwcond>(name, lwmutex_id, control))
{
*lwcond_id = id;
return CELL_OK;
@ -79,9 +79,9 @@ error_code _sys_lwcond_signal(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id, u3
{
mutex = idm::check_unlocked<lv2_obj, lv2_lwmutex>(lwmutex_id);
if (mutex && cond.waiters)
if (cond.waiters)
{
semaphore_lock lock(mutex->mutex);
semaphore_lock lock(cond.mutex);
cpu_thread* result = nullptr;
@ -99,7 +99,7 @@ error_code _sys_lwcond_signal(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id, u3
}
else
{
result = cond.schedule<ppu_thread>(cond.sq, mutex->protocol);
result = cond.schedule<ppu_thread>(cond.sq, cond.control->lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK);
}
if (result)
@ -111,8 +111,10 @@ error_code _sys_lwcond_signal(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id, u3
static_cast<ppu_thread*>(result)->gpr[3] = CELL_EBUSY;
}
if (mode != 2 && !mutex->signaled.fetch_op([](u32& v) { if (v) v--; }))
if (mode == 1)
{
verify(HERE), !mutex->signaled;
semaphore_lock lock(mutex->mutex);
mutex->sq.emplace_back(result);
result = nullptr;
mode = 2; // Enforce CELL_OK
@ -170,13 +172,13 @@ error_code _sys_lwcond_signal_all(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
{
mutex = idm::check_unlocked<lv2_obj, lv2_lwmutex>(lwmutex_id);
if (mutex && cond.waiters)
if (cond.waiters)
{
semaphore_lock lock(mutex->mutex);
semaphore_lock lock(cond.mutex);
u32 result = 0;
while (const auto cpu = cond.schedule<ppu_thread>(cond.sq, mutex->protocol))
while (const auto cpu = cond.schedule<ppu_thread>(cond.sq, cond.control->lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK))
{
cond.waiters--;
@ -185,8 +187,10 @@ error_code _sys_lwcond_signal_all(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
static_cast<ppu_thread*>(cpu)->gpr[3] = CELL_EBUSY;
}
if (mode != 2 && !mutex->signaled.fetch_op([](u32& v) { if (v) v--; }))
if (mode == 1)
{
verify(HERE), !mutex->signaled;
semaphore_lock lock(mutex->mutex);
mutex->sq.emplace_back(cpu);
}
else
@ -237,13 +241,15 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
return nullptr;
}
semaphore_lock lock(mutex->mutex);
semaphore_lock lock(cond.mutex);
// Add a waiter
cond.waiters++;
cond.sq.emplace_back(&ppu);
cond.sleep(ppu, timeout);
semaphore_lock lock2(mutex->mutex);
// Process lwmutex sleep queue
if (const auto cpu = mutex->schedule<ppu_thread>(mutex->sq, mutex->protocol))
{
@ -274,7 +280,7 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
if (passed >= timeout)
{
semaphore_lock lock(mutex->mutex);
semaphore_lock lock(cond->mutex);
if (!cond->unqueue(cond->sq, &ppu))
{

View File

@ -25,13 +25,16 @@ struct lv2_lwcond final : lv2_obj
const u64 name;
const u32 lwid;
vm::ps3::ptr<sys_lwcond_t> control;
semaphore<> mutex;
atomic_t<u32> waiters{0};
std::deque<cpu_thread*> sq;
lv2_lwcond(u64 name, u32 lwid)
lv2_lwcond(u64 name, u32 lwid, vm::ps3::ptr<sys_lwcond_t> control)
: name(name)
, lwid(lwid)
, control(control)
{
}
};