Skip to content

Commit

Permalink
SPU: Notify threads on RdEventStat properly
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Jun 18, 2024
1 parent 5e75a50 commit 0f4cfcc
Showing 1 changed file with 32 additions and 5 deletions.
37 changes: 32 additions & 5 deletions rpcs3/Emu/Cell/SPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5525,6 +5525,11 @@ s64 spu_thread::get_ch_value(u32 ch)
continue;
}

static thread_local bool s_tls_try_notify = false;
s_tls_try_notify = false;

const u32 _raddr = this->raddr;

atomic_wait_engine::set_one_time_use_wait_callback(mask1 != SPU_EVENT_LR ? nullptr : +[](u64 attempts) -> bool
{
const auto _this = static_cast<spu_thread*>(cpu_thread::get_current());
Expand All @@ -5543,20 +5548,42 @@ s64 spu_thread::get_ch_value(u32 ch)
return true;
}

if (!vm::check_addr(_this->raddr) || !cmp_rdata(_this->rdata, *_this->resrv_mem))
bool set_lr = false;
const u32 raddr = _this->raddr;

if (!vm::check_addr(raddr))
{
set_lr = true;
}
else if (!cmp_rdata(_this->rdata, *_this->resrv_mem))
{
// Only data changed, try to notify waiters
if (get_resrv_waiters_count(raddr) >= 2 && vm::reservation_acquire(raddr).compare_and_swap_test(_this->rtime, _this->rtime + 128))
{
s_tls_try_notify = true;
}

set_lr = true;
}

if (set_lr)
{
_this->set_events(SPU_EVENT_LR);
_this->raddr = 0;
_this->set_events(SPU_EVENT_LR);
return false;
}

return true;
});

get_resrv_waiters_count(raddr)++;
vm::reservation_notifier(raddr).wait(rtime, atomic_wait_timeout{80'000});
get_resrv_waiters_count(raddr)--;
get_resrv_waiters_count(_raddr)++;
vm::reservation_notifier(_raddr).wait(rtime, atomic_wait_timeout{80'000});
get_resrv_waiters_count(_raddr)--;
#endif
if (s_tls_try_notify && get_resrv_waiters_count(_raddr) && vm::reservation_acquire(_raddr) == rtime + 128)
{
vm::reservation_notifier(_raddr).notify_all();
}
}
else
{
Expand Down

0 comments on commit 0f4cfcc

Please sign in to comment.