mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-14 10:48:36 +12:00
PPU/SPU: give up on conditional stores if locking fails
Restores Non-TSX behaviour partially.
This commit is contained in:
parent
1b89ad00e7
commit
494953997e
2 changed files with 25 additions and 60 deletions
|
@ -1595,27 +1595,20 @@ static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, u64 reg_value)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
while (res.bts(std::countr_zero<u32>(vm::rsrv_unique_lock)))
|
auto [_oldd, _ok] = res.fetch_op([&](u64& r)
|
||||||
{
|
{
|
||||||
// Give up if reservation has been updated
|
if ((r & -128) != rtime || (r & 127))
|
||||||
if ((res & -128) != rtime)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ppu.state && ppu.check_state())
|
r += vm::rsrv_unique_lock;
|
||||||
{
|
return true;
|
||||||
return false;
|
});
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busy_wait(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((res & -128) != rtime)
|
if (!_ok)
|
||||||
{
|
{
|
||||||
res -= vm::rsrv_unique_lock;
|
// Already locked or updated: give up
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1661,43 +1654,22 @@ static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, u64 reg_value)
|
||||||
// Aligned 8-byte reservations will be used here
|
// Aligned 8-byte reservations will be used here
|
||||||
addr &= -8;
|
addr &= -8;
|
||||||
|
|
||||||
for (u64 count = 0;; count++)
|
auto [_oldd, _ok] = res.fetch_op([&](u64& r)
|
||||||
{
|
{
|
||||||
auto [_old, _ok] = res.fetch_op([&](u64& r)
|
if ((r & -128) != rtime || (r & 127))
|
||||||
{
|
|
||||||
if ((r & -128) != rtime || (r & vm::rsrv_unique_lock))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
r += 1;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Give up if reservation has been updated
|
|
||||||
if ((_old & -128) != rtime)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_ok)
|
// Despite using shared lock, doesn't allow other shared locks (TODO)
|
||||||
{
|
r += 1;
|
||||||
if (count >= 20)
|
return true;
|
||||||
{
|
});
|
||||||
ppu_log.notice("%s took too long (%u):", sizeof(T) == 4 ? "STWCX" : "STDCX", count);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
// Give up if reservation has been locked or updated
|
||||||
}
|
if (!_ok)
|
||||||
|
{
|
||||||
if (ppu.state && ppu.check_state())
|
return false;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busy_wait(100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.compare_and_swap_test(old_data, reg_value))
|
if (data.compare_and_swap_test(old_data, reg_value))
|
||||||
|
@ -1706,7 +1678,7 @@ static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, u64 reg_value)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
res -=1;
|
res -= 1;
|
||||||
return false;
|
return false;
|
||||||
}())
|
}())
|
||||||
{
|
{
|
||||||
|
|
|
@ -2118,27 +2118,20 @@ bool spu_thread::do_putllc(const spu_mfc_cmd& args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (res.bts(std::countr_zero<u32>(vm::rsrv_unique_lock)))
|
auto [_oldd, _ok] = res.fetch_op([&](u64& r)
|
||||||
{
|
{
|
||||||
// Give up if reservation has been updated
|
if ((r & -128) != rtime || (r & 127))
|
||||||
if ((res & -128) != rtime)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state && check_state())
|
r += vm::rsrv_unique_lock;
|
||||||
{
|
return true;
|
||||||
return false;
|
});
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busy_wait(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((res & -128) != rtime)
|
if (!_ok)
|
||||||
{
|
{
|
||||||
res -= vm::rsrv_unique_lock;
|
// Already locked or updated: give up
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue