mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 05:51:27 +12:00
SPU: Regression fix after #12648
This commit is contained in:
parent
ec7b18dab5
commit
2807be7080
2 changed files with 37 additions and 20 deletions
|
@ -4314,7 +4314,23 @@ s64 spu_thread::get_ch_value(u32 ch)
|
||||||
// Don't busy-wait with TSX - memory is sensitive
|
// Don't busy-wait with TSX - memory is sensitive
|
||||||
if (!reservation_busy_waiting)
|
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());
|
const auto _this = static_cast<spu_thread*>(cpu_thread::get_current());
|
||||||
AUDIT(_this->id_type() == 1);
|
AUDIT(_this->id_type() == 1);
|
||||||
|
@ -4326,6 +4342,12 @@ s64 spu_thread::get_ch_value(u32 ch)
|
||||||
return false;
|
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))
|
if (!vm::check_addr(_this->raddr) || !cmp_rdata(_this->rdata, *_this->resrv_mem))
|
||||||
{
|
{
|
||||||
_this->set_events(SPU_EVENT_LR);
|
_this->set_events(SPU_EVENT_LR);
|
||||||
|
@ -4336,14 +4358,6 @@ s64 spu_thread::get_ch_value(u32 ch)
|
||||||
return true;
|
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});
|
vm::reservation_notifier(raddr).wait(rtime, -128, atomic_wait_timeout{80'000});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -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))
|
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
|
#ifdef USE_FUTEX
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
ts.tv_sec = timeout / 1'000'000'000;
|
ts.tv_sec = timeout / 1'000'000'000;
|
||||||
|
@ -1191,19 +1199,14 @@ SAFE_BUFFERS(void) atomic_wait_engine::wait(const void* data, u32 size, u128 old
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_tls_one_time_wait_cb)
|
|
||||||
{
|
|
||||||
if (!s_tls_one_time_wait_cb(attempts))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
if (timeout + 1)
|
||||||
{
|
{
|
||||||
|
if (s_tls_one_time_wait_cb)
|
||||||
|
{
|
||||||
|
// The condition of the callback overrides timeout escape because it makes little sense to do so when a custom condition is passed
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: reduce timeout instead
|
// TODO: reduce timeout instead
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue