mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 21:32:50 +00:00
Implement cpu_thread::if_suspended
Use it for opportunistic guaranteed GETLLAR execution (TSX-FA).
This commit is contained in:
parent
f5c575961f
commit
adf50b7c4b
@ -739,7 +739,7 @@ std::string cpu_thread::dump_misc() const
|
||||
return fmt::format("Type: %s\n" "State: %s\n", typeid(*this).name(), state.load());
|
||||
}
|
||||
|
||||
void cpu_thread::suspend_work::push(cpu_thread* _this) noexcept
|
||||
bool cpu_thread::suspend_work::push(cpu_thread* _this, bool cancel_if_not_suspended) noexcept
|
||||
{
|
||||
// Can't allow pre-set wait bit (it'd be a problem)
|
||||
verify(HERE), !_this || !(_this->state & cpu_flag::wait);
|
||||
@ -758,6 +758,12 @@ void cpu_thread::suspend_work::push(cpu_thread* _this) noexcept
|
||||
// Load current head
|
||||
next = queue.load();
|
||||
|
||||
if (!next && cancel_if_not_suspended) [[unlikely]]
|
||||
{
|
||||
// Give up if not suspended
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_this && next)
|
||||
{
|
||||
// If _this == nullptr, it only works if this is the first workload pushed
|
||||
@ -869,10 +875,11 @@ void cpu_thread::suspend_work::push(cpu_thread* _this) noexcept
|
||||
}
|
||||
|
||||
_this->check_state();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
g_suspend_counter.notify_all();
|
||||
return true;
|
||||
}
|
||||
|
||||
void cpu_thread::stop_all() noexcept
|
||||
|
@ -136,7 +136,7 @@ public:
|
||||
suspend_work* next;
|
||||
|
||||
// Internal method
|
||||
void push(cpu_thread* _this) noexcept;
|
||||
bool push(cpu_thread* _this, bool cancel_if_not_suspended = false) noexcept;
|
||||
};
|
||||
|
||||
// Suspend all threads and execute op (may be executed by other thread than caller!)
|
||||
@ -167,6 +167,21 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Push the workload only if threads are being suspended by suspend_all()
|
||||
template <s8 Prio = 0, typename F>
|
||||
static bool if_suspended(cpu_thread* _this, F op)
|
||||
{
|
||||
static_assert(std::is_void_v<std::invoke_result_t<F>>, "Unimplemented (must return void)");
|
||||
{
|
||||
suspend_work work{Prio, &op, nullptr, [](void* func, void*)
|
||||
{
|
||||
std::invoke(*static_cast<F*>(func));
|
||||
}};
|
||||
|
||||
return work.push(_this, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop all threads with cpu_flag::dbg_global_stop
|
||||
static void stop_all() noexcept;
|
||||
|
||||
|
@ -1189,10 +1189,27 @@ static T ppu_load_acquire_reservation(ppu_thread& ppu, u32 addr)
|
||||
ppu.use_full_rdata = false;
|
||||
}
|
||||
|
||||
for (u64 count = 0;; [&]()
|
||||
for (u64 count = 0; count != umax; [&]()
|
||||
{
|
||||
if (ppu.state)
|
||||
{
|
||||
if (ppu.state & cpu_flag::pause)
|
||||
{
|
||||
verify(HERE), cpu_thread::if_suspended<-1>(&ppu, [&]()
|
||||
{
|
||||
// Guaranteed success
|
||||
ppu.rtime = vm::reservation_acquire(addr, sizeof(T)) & -128;
|
||||
mov_rdata(ppu.rdata, *vm::get_super_ptr<spu_rdata_t>(addr & -128));
|
||||
});
|
||||
|
||||
// Exit loop
|
||||
if ((ppu.rtime & 127) == 0)
|
||||
{
|
||||
count = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ppu.check_state();
|
||||
}
|
||||
else if (++count < 20) [[likely]]
|
||||
@ -1275,6 +1292,10 @@ static T ppu_load_acquire_reservation(ppu_thread& ppu, u32 addr)
|
||||
return static_cast<T>(rdata << data_off >> size_off);
|
||||
}
|
||||
}
|
||||
|
||||
be_t<u64> rdata;
|
||||
std::memcpy(&rdata, &ppu.rdata[addr & 0x78], 8);
|
||||
return static_cast<T>(rdata << data_off >> size_off);
|
||||
}
|
||||
|
||||
extern u32 ppu_lwarx(ppu_thread& ppu, u32 addr)
|
||||
|
@ -2428,11 +2428,23 @@ bool spu_thread::process_mfc_cmd()
|
||||
mov_rdata(temp, rdata);
|
||||
}
|
||||
|
||||
for (u64 i = 0;; [&]()
|
||||
for (u64 i = 0; i != umax; [&]()
|
||||
{
|
||||
if (state & cpu_flag::pause)
|
||||
{
|
||||
check_state();
|
||||
verify(HERE), cpu_thread::if_suspended<-1>(this, [&]
|
||||
{
|
||||
// Guaranteed success
|
||||
ntime = vm::reservation_acquire(addr, 128);
|
||||
mov_rdata(rdata, *vm::get_super_ptr<spu_rdata_t>(addr));
|
||||
});
|
||||
|
||||
// Exit loop
|
||||
if ((ntime & 127) == 0)
|
||||
{
|
||||
i = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (++i < 25) [[likely]]
|
||||
|
Loading…
x
Reference in New Issue
Block a user