mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 14:01:25 +12:00
Fix _sys_lwcond_signal, _sys_lwcond_signal_all
This commit is contained in:
parent
93db420f80
commit
bf14cbdb27
2 changed files with 21 additions and 12 deletions
|
@ -24,7 +24,7 @@ error_code _sys_lwcond_create(vm::ptr<u32> lwcond_id, u32 lwmutex_id, vm::ptr<sy
|
||||||
return CELL_ESRCH;
|
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;
|
*lwcond_id = id;
|
||||||
return CELL_OK;
|
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);
|
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;
|
cpu_thread* result = nullptr;
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ error_code _sys_lwcond_signal(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id, u3
|
||||||
}
|
}
|
||||||
else
|
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)
|
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;
|
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);
|
mutex->sq.emplace_back(result);
|
||||||
result = nullptr;
|
result = nullptr;
|
||||||
mode = 2; // Enforce CELL_OK
|
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);
|
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;
|
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--;
|
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;
|
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);
|
mutex->sq.emplace_back(cpu);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -237,13 +241,15 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
semaphore_lock lock(mutex->mutex);
|
semaphore_lock lock(cond.mutex);
|
||||||
|
|
||||||
// Add a waiter
|
// Add a waiter
|
||||||
cond.waiters++;
|
cond.waiters++;
|
||||||
cond.sq.emplace_back(&ppu);
|
cond.sq.emplace_back(&ppu);
|
||||||
cond.sleep(ppu, timeout);
|
cond.sleep(ppu, timeout);
|
||||||
|
|
||||||
|
semaphore_lock lock2(mutex->mutex);
|
||||||
|
|
||||||
// Process lwmutex sleep queue
|
// Process lwmutex sleep queue
|
||||||
if (const auto cpu = mutex->schedule<ppu_thread>(mutex->sq, mutex->protocol))
|
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)
|
if (passed >= timeout)
|
||||||
{
|
{
|
||||||
semaphore_lock lock(mutex->mutex);
|
semaphore_lock lock(cond->mutex);
|
||||||
|
|
||||||
if (!cond->unqueue(cond->sq, &ppu))
|
if (!cond->unqueue(cond->sq, &ppu))
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,13 +25,16 @@ struct lv2_lwcond final : lv2_obj
|
||||||
|
|
||||||
const u64 name;
|
const u64 name;
|
||||||
const u32 lwid;
|
const u32 lwid;
|
||||||
|
vm::ps3::ptr<sys_lwcond_t> control;
|
||||||
|
|
||||||
|
semaphore<> mutex;
|
||||||
atomic_t<u32> waiters{0};
|
atomic_t<u32> waiters{0};
|
||||||
std::deque<cpu_thread*> sq;
|
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)
|
: name(name)
|
||||||
, lwid(lwid)
|
, lwid(lwid)
|
||||||
|
, control(control)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue