Implement vm::reservation_op

Implement vm::reservation_peek (memory load)
Implement vm::unsafe_ptr_cast helper
Example use in cellSpurs.cpp
Fix dma_lockb value and description
This commit is contained in:
Nekotekina 2020-10-07 01:14:35 +03:00
parent 59be63167f
commit 89f1248140
5 changed files with 388 additions and 71 deletions

View file

@ -13,6 +13,7 @@
#include "Emu/CPU/CPUThread.h"
#include "Emu/Cell/lv2/sys_memory.h"
#include "Emu/RSX/GSRender.h"
#include "Emu/Cell/SPURecompiler.h"
#include <atomic>
#include <thread>
#include <deque>
@ -470,6 +471,52 @@ namespace vm
}
}
void reservation_op_internal(u32 addr, std::function<bool()> func)
{
const auto _cpu = get_current_cpu_thread();
// Acknowledge contender if necessary (TODO: check)
_cpu->state += cpu_flag::wait;
{
cpu_thread::suspend_all cpu_lock(_cpu);
// Wait to acquire PUTLLUC lock
while (vm::reservation_acquire(addr, 128).bts(std::countr_zero<u32>(vm::putlluc_lockb)))
{
busy_wait(100);
}
if (func())
{
// Success, release PUTLLUC and PUTLLC locks if necessary
vm::reservation_acquire(addr, 128) += 63;
}
else
{
// Fake update (TODO)
vm::reservation_acquire(addr, 128) += 63;
}
}
vm::reservation_notifier(addr, 128).notify_all();
}
void reservation_escape_internal()
{
const auto _cpu = get_current_cpu_thread();
if (_cpu && _cpu->id_type() == 1)
{
thread_ctrl::emergency_exit("vm::reservation_escape");
}
if (_cpu && _cpu->id_type() == 2)
{
spu_runtime::g_escape(static_cast<spu_thread*>(_cpu));
}
}
static void _page_map(u32 addr, u8 flags, u32 size, utils::shm* shm)
{
if (!size || (size | addr) % 4096 || flags & page_allocated)