mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 22:11:26 +12:00
149 lines
2.1 KiB
C++
149 lines
2.1 KiB
C++
#include "stdafx.h"
|
|
#include "Utilities/Log.h"
|
|
#include "Emu/Memory/Memory.h"
|
|
#include "Emu/System.h"
|
|
#include "Callback.h"
|
|
|
|
#include "Emu/Cell/PPCThread.h"
|
|
|
|
Callback::Callback(u32 slot, u64 addr)
|
|
: m_addr(addr)
|
|
, m_slot(slot)
|
|
, a1(0)
|
|
, a2(0)
|
|
, a3(0)
|
|
, a4(0)
|
|
, m_has_data(false)
|
|
, m_name("Callback")
|
|
{
|
|
}
|
|
|
|
u32 Callback::GetSlot() const
|
|
{
|
|
return m_slot;
|
|
}
|
|
|
|
u64 Callback::GetAddr() const
|
|
{
|
|
return m_addr;
|
|
}
|
|
|
|
void Callback::SetSlot(u32 slot)
|
|
{
|
|
m_slot = slot;
|
|
}
|
|
|
|
void Callback::SetAddr(u64 addr)
|
|
{
|
|
m_addr = addr;
|
|
}
|
|
|
|
bool Callback::HasData() const
|
|
{
|
|
return m_has_data;
|
|
}
|
|
|
|
void Callback::Handle(u64 _a1, u64 _a2, u64 _a3, u64 _a4)
|
|
{
|
|
a1 = _a1;
|
|
a2 = _a2;
|
|
a3 = _a3;
|
|
a4 = _a4;
|
|
m_has_data = true;
|
|
}
|
|
|
|
u64 Callback::Branch(bool wait)
|
|
{
|
|
m_has_data = false;
|
|
|
|
static std::mutex cb_mutex;
|
|
|
|
CPUThread& thr = Emu.GetCallbackThread();
|
|
|
|
again:
|
|
|
|
while (thr.IsAlive())
|
|
{
|
|
if (Emu.IsStopped())
|
|
{
|
|
LOG_WARNING(HLE, "Callback::Branch() aborted");
|
|
return 0;
|
|
}
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(cb_mutex);
|
|
|
|
if (thr.IsAlive())
|
|
{
|
|
goto again;
|
|
}
|
|
if (Emu.IsStopped())
|
|
{
|
|
LOG_WARNING(HLE, "Callback::Branch() aborted");
|
|
return 0;
|
|
}
|
|
|
|
thr.Stop();
|
|
thr.Reset();
|
|
|
|
thr.SetEntry(m_addr);
|
|
thr.SetPrio(1001);
|
|
thr.SetStackSize(0x10000);
|
|
thr.SetName(m_name);
|
|
|
|
thr.SetArg(0, a1);
|
|
thr.SetArg(1, a2);
|
|
thr.SetArg(2, a3);
|
|
thr.SetArg(3, a4);
|
|
thr.Run();
|
|
|
|
thr.Exec();
|
|
|
|
if (!wait)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
while (thr.IsAlive())
|
|
{
|
|
if (Emu.IsStopped())
|
|
{
|
|
LOG_WARNING(HLE, "Callback::Branch(true) aborted (end)");
|
|
return 0;
|
|
}
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
}
|
|
|
|
return thr.GetExitStatus();
|
|
}
|
|
|
|
void Callback::SetName(const std::string& name)
|
|
{
|
|
m_name = name;
|
|
}
|
|
|
|
Callback::operator bool() const
|
|
{
|
|
return GetAddr() != 0;
|
|
}
|
|
|
|
Callback2::Callback2(u32 slot, u64 addr, u64 userdata) : Callback(slot, addr)
|
|
{
|
|
a2 = userdata;
|
|
}
|
|
|
|
void Callback2::Handle(u64 status)
|
|
{
|
|
Callback::Handle(status, a2, 0);
|
|
}
|
|
|
|
Callback3::Callback3(u32 slot, u64 addr, u64 userdata) : Callback(slot, addr)
|
|
{
|
|
a3 = userdata;
|
|
}
|
|
|
|
void Callback3::Handle(u64 status, u64 param)
|
|
{
|
|
Callback::Handle(status, param, a3);
|
|
}
|