mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-04-29 23:41:12 -06:00
SPU LLVM: Fix RCHCNT write channel looping
This commit is contained in:
parent
1ca8ab393a
commit
7d0df300ea
@ -4353,6 +4353,16 @@ public:
|
||||
{
|
||||
switch (op.ra)
|
||||
{
|
||||
case SPU_WrOutMbox:
|
||||
{
|
||||
res.value = wait_rchcnt(::offset32(&spu_thread::ch_out_mbox), true);
|
||||
break;
|
||||
}
|
||||
case SPU_WrOutIntrMbox:
|
||||
{
|
||||
res.value = wait_rchcnt(::offset32(&spu_thread::ch_out_intr_mbox), true);
|
||||
break;
|
||||
}
|
||||
case SPU_RdSigNotify1:
|
||||
{
|
||||
res.value = wait_rchcnt(::offset32(&spu_thread::ch_snr1));
|
||||
|
||||
@ -7219,6 +7219,12 @@ s64 spu_channel::pop_wait(cpu_thread& spu, bool pop)
|
||||
{
|
||||
if (u64 v = jostling_value.exchange(0); !(v & bit_occupy))
|
||||
{
|
||||
while (data & bit_wait)
|
||||
{
|
||||
// Wait until notifying thread finishes operation
|
||||
busy_wait(500);
|
||||
}
|
||||
|
||||
return static_cast<u32>(v);
|
||||
}
|
||||
|
||||
|
||||
@ -197,11 +197,12 @@ struct alignas(16) spu_channel
|
||||
|
||||
public:
|
||||
static constexpr u32 off_wait = 32;
|
||||
static constexpr u32 off_occupy = 32;
|
||||
static constexpr u32 off_occupy = 33;
|
||||
static constexpr u32 off_count = 63;
|
||||
static constexpr u64 bit_wait = 1ull << off_wait;
|
||||
static constexpr u64 bit_occupy = 1ull << off_occupy;
|
||||
static constexpr u64 bit_count = 1ull << off_count;
|
||||
static constexpr u64 occupy_ored_wait = bit_wait | bit_occupy;
|
||||
|
||||
// Returns true on success
|
||||
bool try_push(u32 value)
|
||||
@ -252,17 +253,20 @@ public:
|
||||
// Other thread has inserted a value through jostling_value, retry
|
||||
continue;
|
||||
}
|
||||
|
||||
// Turn off waiting bit manually (must succeed because waiting bit can only be resetted by the thread pushed to jostling_value)
|
||||
if (~this->data.fetch_and(~occupy_ored_wait) & bit_wait)
|
||||
{
|
||||
// Could be fatal or at emulation stopping, to be checked by the caller
|
||||
ensure(false);
|
||||
}
|
||||
|
||||
// Fallthrough to notification
|
||||
ensure(old & bit_wait);
|
||||
}
|
||||
|
||||
if (old & bit_wait)
|
||||
{
|
||||
// Turn off waiting bit manually (must succeed because waiting bit can only be resetted by the thread pushed to jostling_value)
|
||||
if (!this->data.bit_test_reset(off_wait))
|
||||
{
|
||||
// Could be fatal or at emulation stopping, to be checked by the caller
|
||||
return { (old & bit_count) == 0, 0, false, false };
|
||||
}
|
||||
|
||||
if (!postpone_notify)
|
||||
{
|
||||
utils::bless<atomic_t<u32>>(&data)[1].notify_one();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user