mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-13 02:08:49 +12:00
SPU: Fix events ACK, minor optimizations (#8771)
This commit is contained in:
parent
190822c2b2
commit
47b545282e
4 changed files with 30 additions and 39 deletions
|
@ -2346,7 +2346,7 @@ bool spu_thread::process_mfc_cmd()
|
|||
ch_mfc_cmd.cmd, ch_mfc_cmd.lsa, ch_mfc_cmd.eal, ch_mfc_cmd.tag, ch_mfc_cmd.size);
|
||||
}
|
||||
|
||||
u32 spu_thread::get_events(bool waiting)
|
||||
u32 spu_thread::get_events(u32 mask_hint)
|
||||
{
|
||||
const u32 mask1 = ch_event_mask;
|
||||
|
||||
|
@ -2356,36 +2356,29 @@ u32 spu_thread::get_events(bool waiting)
|
|||
}
|
||||
|
||||
// Check reservation status and set SPU_EVENT_LR if lost
|
||||
if (raddr && ((vm::reservation_acquire(raddr, sizeof(rdata)) & -128) != rtime || !cmp_rdata(rdata, vm::_ref<decltype(rdata)>(raddr))))
|
||||
if (mask_hint & SPU_EVENT_LR && raddr && ((vm::reservation_acquire(raddr, sizeof(rdata)) & -128) != rtime || !cmp_rdata(rdata, vm::_ref<decltype(rdata)>(raddr))))
|
||||
{
|
||||
ch_event_stat |= SPU_EVENT_LR;
|
||||
raddr = 0;
|
||||
}
|
||||
|
||||
// SPU Decrementer Event on underflow (use the upper 32-bits to determine it)
|
||||
if (const u64 res = (ch_dec_value - (get_timebased_time() - ch_dec_start_timestamp)) >> 32)
|
||||
if (mask_hint & SPU_EVENT_TM)
|
||||
{
|
||||
// Set next event to the next time the decrementer underflows
|
||||
ch_dec_start_timestamp -= res << 32;
|
||||
|
||||
if ((ch_event_stat & SPU_EVENT_TM) == 0)
|
||||
if (const u64 res = (ch_dec_value - (get_timebased_time() - ch_dec_start_timestamp)) >> 32)
|
||||
{
|
||||
ch_event_stat |= SPU_EVENT_TM;
|
||||
// Set next event to the next time the decrementer underflows
|
||||
ch_dec_start_timestamp -= res << 32;
|
||||
|
||||
if ((ch_event_stat & SPU_EVENT_TM) == 0)
|
||||
{
|
||||
ch_event_stat |= SPU_EVENT_TM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Simple polling or polling with atomically set/removed SPU_EVENT_WAITING flag
|
||||
return !waiting ? ch_event_stat & mask1 : ch_event_stat.atomic_op([&](u32& stat) -> u32
|
||||
{
|
||||
if (u32 res = stat & mask1)
|
||||
{
|
||||
stat &= ~SPU_EVENT_WAITING;
|
||||
return res;
|
||||
}
|
||||
|
||||
stat |= SPU_EVENT_WAITING;
|
||||
return 0;
|
||||
});
|
||||
return ch_event_stat & mask1;
|
||||
}
|
||||
|
||||
void spu_thread::set_events(u32 mask)
|
||||
|
@ -2580,7 +2573,9 @@ s64 spu_thread::get_ch_value(u32 ch)
|
|||
|
||||
case SPU_RdEventStat:
|
||||
{
|
||||
u32 res = get_events();
|
||||
const u32 mask1 = ch_event_mask;
|
||||
|
||||
u32 res = get_events(mask1);
|
||||
|
||||
if (res)
|
||||
{
|
||||
|
@ -2589,8 +2584,6 @@ s64 spu_thread::get_ch_value(u32 ch)
|
|||
|
||||
spu_function_logger logger(*this, "MFC Events read");
|
||||
|
||||
const u32 mask1 = ch_event_mask;
|
||||
|
||||
if (mask1 & SPU_EVENT_LR && raddr)
|
||||
{
|
||||
if (mask1 != SPU_EVENT_LR && mask1 != SPU_EVENT_LR + SPU_EVENT_TM)
|
||||
|
@ -2599,7 +2592,7 @@ s64 spu_thread::get_ch_value(u32 ch)
|
|||
fmt::throw_exception("Not supported: event mask 0x%x" HERE, mask1);
|
||||
}
|
||||
|
||||
while (res = get_events(), !res)
|
||||
while (res = get_events(mask1), !res)
|
||||
{
|
||||
state += cpu_flag::wait;
|
||||
|
||||
|
@ -2615,7 +2608,7 @@ s64 spu_thread::get_ch_value(u32 ch)
|
|||
return res;
|
||||
}
|
||||
|
||||
while (res = get_events(true), !res)
|
||||
while (res = get_events(mask1), !res)
|
||||
{
|
||||
state += cpu_flag::wait;
|
||||
|
||||
|
@ -2928,6 +2921,7 @@ bool spu_thread::set_ch_value(u32 ch, u32 value)
|
|||
|
||||
case SPU_WrDec:
|
||||
{
|
||||
get_events(SPU_EVENT_TM); // Don't discard possibly occured old event
|
||||
ch_dec_start_timestamp = get_timebased_time();
|
||||
ch_dec_value = value;
|
||||
return true;
|
||||
|
@ -2941,6 +2935,8 @@ bool spu_thread::set_ch_value(u32 ch, u32 value)
|
|||
|
||||
case SPU_WrEventAck:
|
||||
{
|
||||
// "Collect" events before final acknowledgment
|
||||
get_events(value);
|
||||
ch_event_stat &= ~value;
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue