Skip to content

Commit 45b23b1

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

File tree

1 file changed

+46
-1
lines changed

1 file changed

+46
-1
lines changed

rpcs3/Emu/Cell/lv2/sys_rsx.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,57 @@ 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+
// TODO: Investigate relaxed memory ordering
441+
const u32 prev_ea = table.ea[(io + i) / _1m];
442+
const u32 prev_io = table.io[(ea + i) / _1m];
443+
444+
if (prev_ea != ea + i || prev_io != io + i)
445+
{
446+
attempts = umax;
447+
break;
448+
}
449+
}
450+
451+
if (attempts == umax)
452+
{
453+
break;
454+
}
455+
}
456+
457+
if (fast_lock.owns_lock())
458+
{
459+
fast_lock.unlock();
460+
}
461+
417462
// Wait until we have no active RSX locks and reserve iomap for use. Must do so before acquiring vm lock to avoid deadlocks
418463
rsx::reservation_lock<true> rsx_lock(ea, size);
419464

420465
vm::writer_lock rlock;
421466

422-
for (u32 addr = ea, end = ea + size; addr < end; addr += 0x100000)
467+
for (u32 addr = ea, end = ea + size; addr < end; addr += _1m)
423468
{
424469
if (!vm::check_addr(addr, vm::page_readable | (addr < 0x20000000 ? 0 : vm::page_1m_size)))
425470
{

0 commit comments

Comments
 (0)