mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-05 14:37:08 +00:00
CELL: Rewrite reservation notification postponing
This commit is contained in:
parent
729826ec40
commit
a4ea71d18f
6 changed files with 60 additions and 33 deletions
|
|
@ -3541,49 +3541,62 @@ static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, u64 reg_value)
|
|||
// Avoid notifications from lwmutex or sys_spinlock
|
||||
if (new_data != old_data && (ppu.cia < liblv2_begin || ppu.cia >= liblv2_end))
|
||||
{
|
||||
const u32 notify = ppu.res_notify;
|
||||
u32 notify = ppu.res_notify;
|
||||
|
||||
if (notify)
|
||||
{
|
||||
bool notified = false;
|
||||
|
||||
if (ppu.res_notify_time == (vm::reservation_acquire(notify) & -128))
|
||||
if (ppu.res_notify_time == vm::reservation_notifier_count_index(notify).second)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
vm::reservation_notifier_notify(notify);
|
||||
notified = true;
|
||||
}
|
||||
|
||||
if (vm::reservation_notifier_count(addr))
|
||||
{
|
||||
if (!notified)
|
||||
{
|
||||
ppu.res_notify = addr;
|
||||
ppu.res_notify_time = rtime + 128;
|
||||
}
|
||||
else if ((addr ^ notify) & -128)
|
||||
{
|
||||
vm::reservation_notifier_notify(addr);
|
||||
ppu.res_notify = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ppu.res_notify = 0;
|
||||
notify = 0;
|
||||
}
|
||||
|
||||
static_cast<void>(ppu.test_stopped());
|
||||
ppu.res_notify = 0;
|
||||
}
|
||||
else
|
||||
|
||||
if ((addr ^ notify) & -128)
|
||||
{
|
||||
// Try to postpone notification to when PPU is asleep or join notifications on the same address
|
||||
// This also optimizes a mutex - won't notify after lock is aqcuired (prolonging the critical section duration), only notifies on unlock
|
||||
if (vm::reservation_notifier_count(addr))
|
||||
const auto [count, index] = vm::reservation_notifier_count_index(addr);
|
||||
|
||||
switch (count)
|
||||
{
|
||||
ppu.res_notify = addr;
|
||||
ppu.res_notify_time = rtime + 128;
|
||||
case 0:
|
||||
{
|
||||
// Nothing to do
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (!notify)
|
||||
{
|
||||
ppu.res_notify = addr;
|
||||
ppu.res_notify_time = index;
|
||||
break;
|
||||
}
|
||||
|
||||
// Notify both
|
||||
[[fallthrough]];
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (!notify)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
}
|
||||
|
||||
vm::reservation_notifier_notify(addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static_cast<void>(ppu.test_stopped());
|
||||
}
|
||||
|
||||
if (addr == ppu.last_faddr)
|
||||
|
|
@ -3601,7 +3614,7 @@ static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, u64 reg_value)
|
|||
// And on failure it has some time to do something else
|
||||
if (notify && ((addr ^ notify) & -128))
|
||||
{
|
||||
if (ppu.res_notify_time == (vm::reservation_acquire(notify) & -128))
|
||||
if (ppu.res_notify_time == vm::reservation_notifier_count_index(notify).second)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
vm::reservation_notifier_notify(notify);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue