Skip to content

Commit e2e6e89

Browse files
committed
sys_rsx: Add fast path for sys_rsx_context_iomap
1 parent 884f164 commit e2e6e89

1 file changed

Lines changed: 45 additions & 1 deletion

File tree

rpcs3/Emu/Cell/lv2/sys_rsx.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,56 @@ error_code sys_rsx_context_iomap(cpu_thread& cpu, u32 context_id, u32 io, u32 ea
414414
sys_rsx.warning("sys_rsx_context_iomap(): RSX is not idle while mapping io");
415415
}
416416

417+
constexpr u32 _1m = 1u << 20;
418+
419+
std::unique_lock fast_lock(render->sys_rsx_mtx, std::defer_lock);
420+
421+
// Fast path for when mapping is the same
422+
for (u32 attempts = 0;; attempts++)
423+
{
424+
if (attempts == 2)
425+
{
426+
// Nothing to do
427+
return CELL_OK;
428+
}
429+
430+
if (attempts == 1 && size >= _1m * 2)
431+
{
432+
// Confirm mapped the same by rechecking with mutex
433+
fast_lock.lock();
434+
}
435+
436+
for (u32 i = 0; i < size; i += _1m)
437+
{
438+
const auto& table = render->iomap_table;
439+
440+
const u32 prev_ea = table.ea[(io + i) / _1m];
441+
const u32 prev_io = table.io[(ea + i) / _1m];
442+
443+
if (prev_ea != ea + i || prev_io != io + i)
444+
{
445+
attempts = umax;
446+
break;
447+
}
448+
}
449+
450+
if (attempts == umax)
451+
{
452+
break;
453+
}
454+
}
455+
456+
if (fast_lock.owns_lock())
457+
{
458+
fast_lock.unlock();
459+
}
460+
417461
// Wait until we have no active RSX locks and reserve iomap for use. Must do so before acquiring vm lock to avoid deadlocks
418462
rsx::reservation_lock<true> rsx_lock(ea, size);
419463

420464
vm::writer_lock rlock;
421465

422-
for (u32 addr = ea, end = ea + size; addr < end; addr += 0x100000)
466+
for (u32 addr = ea, end = ea + size; addr < end; addr += _1m)
423467
{
424468
if (!vm::check_addr(addr, vm::page_readable | (addr < 0x20000000 ? 0 : vm::page_1m_size)))
425469
{

0 commit comments

Comments
 (0)