1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-23 11:13:19 +01:00

SPU: Notify threads if data changed in RdEventStat

This commit is contained in:
Elad Ashkenazi 2024-06-12 09:56:27 +03:00
parent 5693cc9eb3
commit d5935a37bb
2 changed files with 39 additions and 11 deletions

View File

@ -444,6 +444,12 @@ waitpkg_func static void __tpause(u32 cycles, u32 cstate)
} }
#endif #endif
static inline atomic_t<u8>& get_resrv_waiters_count(u32 raddr)
{
// Storage efficient method to distinguish different nearby addresses (which are likely)
return spu_thread::g_reservation_waiters[std::popcount(raddr) + ((raddr / 128) % 4) * 32];
}
void do_cell_atomic_128_store(u32 addr, const void* to_write); void do_cell_atomic_128_store(u32 addr, const void* to_write);
extern thread_local u64 g_tls_fault_spu; extern thread_local u64 g_tls_fault_spu;
@ -4586,11 +4592,11 @@ bool spu_thread::process_mfc_cmd()
state += cpu_flag::wait; state += cpu_flag::wait;
// Storage efficient method to distinguish different nearby addresses (which are likely) // Storage efficient method to distinguish different nearby addresses (which are likely)
g_reservation_waiters[std::popcount(addr)]++; get_resrv_waiters_count(addr)++;
vm::reservation_notifier(addr).wait(this_time, atomic_wait_timeout{100'000}); vm::reservation_notifier(addr).wait(this_time, atomic_wait_timeout{100'000});
g_reservation_waiters[std::popcount(addr)]--; get_resrv_waiters_count(addr)--;
// Reset perf // Reset perf
perf0.restart(); perf0.restart();
@ -4628,8 +4634,8 @@ bool spu_thread::process_mfc_cmd()
{ {
spu_log.trace("RTIME unchanged on address 0x%x", addr); spu_log.trace("RTIME unchanged on address 0x%x", addr);
// Try to forcefully change in order to notify threads // Try to forcefully change timestamp in order to notify threads
if (g_reservation_waiters[std::popcount(addr)] && res.compare_and_swap_test(this_time, this_time + 128)) if (get_resrv_waiters_count(addr) && res.compare_and_swap_test(this_time, this_time + 128))
{ {
vm::reservation_notifier(addr).notify_all(); vm::reservation_notifier(addr).notify_all();
} }
@ -4639,8 +4645,8 @@ bool spu_thread::process_mfc_cmd()
if (this_time == rtime) if (this_time == rtime)
{ {
// Try to forcefully change in order to notify threads // Try to forcefully change timestamp in order to notify threads
if (g_reservation_waiters[std::popcount(addr)] && res.compare_and_swap_test(this_time, this_time + 128)) if (get_resrv_waiters_count(addr) && res.compare_and_swap_test(this_time, this_time + 128))
{ {
vm::reservation_notifier(addr).notify_all(); vm::reservation_notifier(addr).notify_all();
} }
@ -5431,12 +5437,32 @@ s64 spu_thread::get_ch_value(u32 ch)
} }
// Optimized check // Optimized check
if (raddr && (!vm::check_addr(raddr) || rtime != vm::reservation_acquire(raddr) || !cmp_rdata(rdata, *resrv_mem))) if (raddr)
{
bool set_lr = false;
if (!vm::check_addr(raddr) || rtime != vm::reservation_acquire(raddr))
{
set_lr = true;
}
else if (!cmp_rdata(rdata, *resrv_mem))
{
// Only data changed, try to notify waiters
if (get_resrv_waiters_count(raddr) && vm::reservation_acquire(raddr).compare_and_swap_test(rtime, rtime + 128))
{
vm::reservation_notifier(raddr).notify_all();
}
set_lr = true;
}
if (set_lr)
{ {
raddr = 0; raddr = 0;
set_events(SPU_EVENT_LR); set_events(SPU_EVENT_LR);
continue; continue;
} }
}
if (raddr && (mask1 & ~SPU_EVENT_TM) == SPU_EVENT_LR) if (raddr && (mask1 & ~SPU_EVENT_TM) == SPU_EVENT_LR)
{ {
@ -5507,7 +5533,9 @@ s64 spu_thread::get_ch_value(u32 ch)
return true; return true;
}); });
get_resrv_waiters_count(raddr)++;
vm::reservation_notifier(raddr).wait(rtime, atomic_wait_timeout{80'000}); vm::reservation_notifier(raddr).wait(rtime, atomic_wait_timeout{80'000});
get_resrv_waiters_count(raddr)--;
#endif #endif
} }
else else

View File

@ -896,7 +896,7 @@ public:
static atomic_t<u32> g_raw_spu_ctr; static atomic_t<u32> g_raw_spu_ctr;
static atomic_t<u32> g_raw_spu_id[5]; static atomic_t<u32> g_raw_spu_id[5];
static atomic_t<u32> g_spu_work_count; static atomic_t<u32> g_spu_work_count;
static atomic_t<u8> g_reservation_waiters[32]; static atomic_t<u8> g_reservation_waiters[128];
static u32 find_raw_spu(u32 id) static u32 find_raw_spu(u32 id)
{ {