Skip to content

Commit

Permalink
SPU: Regression fix after #12648
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 authored and Nekotekina committed Sep 13, 2022
1 parent ec7b18d commit 2807be7
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 18 deletions.
32 changes: 23 additions & 9 deletions rpcs3/Emu/Cell/SPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4314,7 +4314,23 @@ s64 spu_thread::get_ch_value(u32 ch)
// Don't busy-wait with TSX - memory is sensitive
if (!reservation_busy_waiting)
{
atomic_wait_engine::set_one_time_use_wait_callback(mask1 != SPU_EVENT_LR ? nullptr : +[](u64) -> bool
if (raddr - spurs_addr <= 0x80 && !g_cfg.core.spu_accurate_reservations && mask1 == SPU_EVENT_LR)
{
atomic_wait_engine::set_one_time_use_wait_callback(+[](u64) -> bool
{
const auto _this = static_cast<spu_thread*>(cpu_thread::get_current());
AUDIT(_this->id_type() == 1);

return !_this->is_stopped();
});

// Wait without timeout, in this situation we have notifications for all writes making it possible
// Abort notifications are handled specially for performance reasons
vm::reservation_notifier(raddr).wait(rtime, -128);
continue;
}

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());
AUDIT(_this->id_type() == 1);
Expand All @@ -4326,6 +4342,12 @@ s64 spu_thread::get_ch_value(u32 ch)
return false;
}

if (!attempts)
{
// Skip checks which have been done already
return true;
}

if (!vm::check_addr(_this->raddr) || !cmp_rdata(_this->rdata, *_this->resrv_mem))
{
_this->set_events(SPU_EVENT_LR);
Expand All @@ -4336,14 +4358,6 @@ s64 spu_thread::get_ch_value(u32 ch)
return true;
});

if (raddr - spurs_addr <= 0x80 && !g_cfg.core.spu_accurate_reservations && mask1 == SPU_EVENT_LR)
{
// Wait without timeout, in this situation we have notifications for all writes making it possible
// Abort notifications are handled specially for performance reasons
vm::reservation_notifier(raddr).wait(rtime, -128);
continue;
}

vm::reservation_notifier(raddr).wait(rtime, -128, atomic_wait_timeout{80'000});
}
else
Expand Down
21 changes: 12 additions & 9 deletions rpcs3/util/atomic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,14 @@ SAFE_BUFFERS(void) atomic_wait_engine::wait(const void* data, u32 size, u128 old

while (ptr_cmp(data, size, old_value, mask, ext))
{
if (s_tls_one_time_wait_cb)
{
if (!s_tls_one_time_wait_cb(attempts))
{
break;
}
}

#ifdef USE_FUTEX
struct timespec ts;
ts.tv_sec = timeout / 1'000'000'000;
Expand Down Expand Up @@ -1191,19 +1199,14 @@ SAFE_BUFFERS(void) atomic_wait_engine::wait(const void* data, u32 size, u128 old
break;
}

if (s_tls_one_time_wait_cb)
if (timeout + 1)
{
if (!s_tls_one_time_wait_cb(attempts))
if (s_tls_one_time_wait_cb)
{
break;
// The condition of the callback overrides timeout escape because it makes little sense to do so when a custom condition is passed
continue;
}

// The condition of the callback overrides timeout escape because it makes little sense to do so when a custom condition is passed
continue;
}

if (timeout + 1)
{
// TODO: reduce timeout instead
break;
}
Expand Down

0 comments on commit 2807be7

Please sign in to comment.