2013-06-30 10:46:29 +02:00
|
|
|
#include "stdafx.h"
|
2014-06-17 17:44:03 +02:00
|
|
|
#include "Utilities/Log.h"
|
2014-06-02 19:27:24 +02:00
|
|
|
#include "Emu/Memory/Memory.h"
|
|
|
|
|
#include "Emu/System.h"
|
2014-09-11 21:18:19 +02:00
|
|
|
#include "Emu/CPU/CPUThreadManager.h"
|
2014-07-13 21:05:28 +02:00
|
|
|
#include "Emu/Cell/PPUThread.h"
|
2014-11-10 01:21:50 +01:00
|
|
|
#include "Emu/ARMv7/ARMv7Thread.h"
|
2014-08-23 22:40:04 +02:00
|
|
|
#include "Callback.h"
|
2013-06-30 10:46:29 +02:00
|
|
|
|
2015-01-11 11:43:40 +01:00
|
|
|
void CallbackManager::Register(const std::function<s32(PPUThread& PPU)>& func)
|
2013-08-17 00:22:26 +02:00
|
|
|
{
|
2014-09-11 21:18:19 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2013-08-17 00:22:26 +02:00
|
|
|
|
2015-01-11 11:43:40 +01:00
|
|
|
m_cb_list.push_back([=](CPUThread& CPU) -> s32
|
|
|
|
|
{
|
|
|
|
|
assert(CPU.GetType() == CPU_THREAD_PPU);
|
|
|
|
|
return func(static_cast<PPUThread&>(CPU));
|
|
|
|
|
});
|
2013-08-17 00:22:26 +02:00
|
|
|
}
|
|
|
|
|
|
2015-01-11 11:43:40 +01:00
|
|
|
void CallbackManager::Async(const std::function<void(PPUThread& PPU)>& func)
|
2013-08-17 00:22:26 +02:00
|
|
|
{
|
2014-09-11 21:18:19 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2013-08-17 00:22:26 +02:00
|
|
|
|
2015-01-11 11:43:40 +01:00
|
|
|
m_async_list.push_back([=](CPUThread& CPU)
|
|
|
|
|
{
|
|
|
|
|
assert(CPU.GetType() == CPU_THREAD_PPU);
|
|
|
|
|
func(static_cast<PPUThread&>(CPU));
|
|
|
|
|
});
|
|
|
|
|
|
2014-09-11 21:18:19 +02:00
|
|
|
m_cb_thread->Notify();
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
|
2015-01-11 11:43:40 +01:00
|
|
|
bool CallbackManager::Check(CPUThread& CPU, s32& result)
|
2013-06-30 10:46:29 +02:00
|
|
|
{
|
2015-01-11 11:43:40 +01:00
|
|
|
std::function<s32(CPUThread& CPU)> func;
|
2014-02-26 08:51:00 +01:00
|
|
|
{
|
2014-09-11 21:18:19 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
|
|
|
|
|
|
if (m_cb_list.size())
|
2014-02-26 08:51:00 +01:00
|
|
|
{
|
2014-09-11 21:18:19 +02:00
|
|
|
func = m_cb_list[0];
|
|
|
|
|
m_cb_list.erase(m_cb_list.begin());
|
2014-02-26 08:51:00 +01:00
|
|
|
}
|
|
|
|
|
}
|
2014-09-11 21:18:19 +02:00
|
|
|
|
|
|
|
|
if (func)
|
2014-02-26 08:51:00 +01:00
|
|
|
{
|
2015-01-11 11:43:40 +01:00
|
|
|
result = func(CPU);
|
2014-09-11 21:18:19 +02:00
|
|
|
return true;
|
2014-02-26 08:51:00 +01:00
|
|
|
}
|
2014-09-11 21:18:19 +02:00
|
|
|
else
|
2014-02-26 08:51:00 +01:00
|
|
|
{
|
2014-09-11 21:18:19 +02:00
|
|
|
return false;
|
2014-02-26 08:51:00 +01:00
|
|
|
}
|
2014-09-11 21:18:19 +02:00
|
|
|
}
|
2013-06-30 10:46:29 +02:00
|
|
|
|
2014-09-11 21:18:19 +02:00
|
|
|
void CallbackManager::Init()
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2013-06-30 10:46:29 +02:00
|
|
|
|
2014-11-10 01:21:50 +01:00
|
|
|
if (Memory.PSV.RAM.GetStartAddr())
|
|
|
|
|
{
|
|
|
|
|
m_cb_thread = &Emu.GetCPU().AddThread(CPU_THREAD_ARMv7);
|
|
|
|
|
m_cb_thread->SetName("Callback Thread");
|
|
|
|
|
m_cb_thread->SetEntry(0);
|
|
|
|
|
m_cb_thread->SetPrio(1001);
|
|
|
|
|
m_cb_thread->SetStackSize(0x10000);
|
|
|
|
|
m_cb_thread->InitStack();
|
|
|
|
|
m_cb_thread->InitRegs();
|
|
|
|
|
static_cast<ARMv7Thread*>(m_cb_thread)->DoRun();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_cb_thread = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
|
|
|
|
m_cb_thread->SetName("Callback Thread");
|
|
|
|
|
m_cb_thread->SetEntry(0);
|
|
|
|
|
m_cb_thread->SetPrio(1001);
|
|
|
|
|
m_cb_thread->SetStackSize(0x10000);
|
|
|
|
|
m_cb_thread->InitStack();
|
|
|
|
|
m_cb_thread->InitRegs();
|
|
|
|
|
static_cast<PPUThread*>(m_cb_thread)->DoRun();
|
|
|
|
|
}
|
2013-06-30 10:46:29 +02:00
|
|
|
|
2015-01-16 15:36:53 +01:00
|
|
|
thread_t cb_async_thread("CallbackManager thread", [this]()
|
2014-02-26 08:51:00 +01:00
|
|
|
{
|
2014-09-11 21:18:19 +02:00
|
|
|
SetCurrentNamedThread(m_cb_thread);
|
2014-02-26 08:51:00 +01:00
|
|
|
|
2014-09-11 21:18:19 +02:00
|
|
|
while (!Emu.IsStopped())
|
2014-02-26 08:51:00 +01:00
|
|
|
{
|
2015-01-11 11:43:40 +01:00
|
|
|
std::function<void(CPUThread& CPU)> func;
|
2014-09-11 21:18:19 +02:00
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
|
|
|
|
|
|
if (m_async_list.size())
|
|
|
|
|
{
|
|
|
|
|
func = m_async_list[0];
|
|
|
|
|
m_async_list.erase(m_async_list.begin());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (func)
|
|
|
|
|
{
|
2015-01-11 11:43:40 +01:00
|
|
|
func(*m_cb_thread);
|
2014-09-11 21:18:19 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
2015-01-11 11:43:40 +01:00
|
|
|
|
2014-09-11 21:18:19 +02:00
|
|
|
m_cb_thread->WaitForAnySignal();
|
2014-02-26 08:51:00 +01:00
|
|
|
}
|
2014-09-11 21:18:19 +02:00
|
|
|
});
|
2013-08-17 00:22:26 +02:00
|
|
|
}
|
|
|
|
|
|
2014-09-11 21:18:19 +02:00
|
|
|
void CallbackManager::Clear()
|
2014-01-07 21:11:02 +01:00
|
|
|
{
|
2014-09-11 21:18:19 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2014-01-07 21:11:02 +01:00
|
|
|
|
2014-09-11 21:18:19 +02:00
|
|
|
m_cb_list.clear();
|
|
|
|
|
m_async_list.clear();
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
2015-01-17 17:14:58 +01:00
|
|
|
|
|
|
|
|
u64 CallbackManager::AddPauseCallback(const std::function<PauseResumeCB>& func)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
|
|
|
|
|
|
m_pause_cb_list.push_back({ func, next_tag });
|
|
|
|
|
return next_tag++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CallbackManager::RemovePauseCallback(const u64 tag)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
|
|
|
|
|
|
for (auto& data : m_pause_cb_list)
|
|
|
|
|
{
|
|
|
|
|
if (data.tag == tag)
|
|
|
|
|
{
|
|
|
|
|
m_pause_cb_list.erase(m_pause_cb_list.begin() + (&data - m_pause_cb_list.data()));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(!"CallbackManager()::RemovePauseCallback(): tag not found");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CallbackManager::RunPauseCallbacks(const bool is_paused)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
|
|
|
|
|
|
for (auto& data : m_pause_cb_list)
|
|
|
|
|
{
|
|
|
|
|
if (data.cb)
|
|
|
|
|
{
|
|
|
|
|
data.cb(is_paused);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|