rpcsx/rpcs3/Emu/Cell/PPUCallback.cpp

104 lines
1.7 KiB
C++
Raw Normal View History

#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
2015-07-01 01:25:52 +03:00
#include "Emu/IdManager.h"
2016-04-14 02:09:41 +03:00
#include "PPUThread.h"
#include "PPUCallback.h"
2016-05-13 16:55:34 +03:00
#include <condition_variable>
2015-07-04 22:23:10 +03:00
void CallbackManager::Register(check_cb_t func)
{
std::lock_guard<std::mutex> lock(m_mutex);
2015-03-16 03:21:40 +03:00
2015-07-04 22:23:10 +03:00
m_check_cb.emplace(std::move(func));
}
2015-07-04 22:23:10 +03:00
void CallbackManager::Async(async_cb_t func)
{
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_cb_thread)
{
throw EXCEPTION("Callback thread not found");
}
2015-07-04 22:23:10 +03:00
m_async_cb.emplace(std::move(func));
2015-03-16 03:21:40 +03:00
2016-05-13 16:55:34 +03:00
(*m_cb_thread)->notify();
}
2016-05-13 16:55:34 +03:00
extern std::condition_variable& get_current_thread_cv();
2015-07-04 22:23:10 +03:00
CallbackManager::check_cb_t CallbackManager::Check()
{
2015-07-04 22:23:10 +03:00
std::lock_guard<std::mutex> lock(m_mutex);
2015-03-16 03:21:40 +03:00
2015-07-04 22:23:10 +03:00
if (m_check_cb.size())
{
2015-07-04 22:23:10 +03:00
check_cb_t func = std::move(m_check_cb.front());
2014-09-11 23:18:19 +04:00
2015-07-04 22:23:10 +03:00
m_check_cb.pop();
return func;
}
2015-07-04 22:23:10 +03:00
return nullptr;
2014-09-11 23:18:19 +04:00
}
2014-09-11 23:18:19 +04:00
void CallbackManager::Init()
{
std::lock_guard<std::mutex> lock(m_mutex);
auto task = [this](PPUThread& ppu)
{
2015-03-16 03:21:40 +03:00
std::unique_lock<std::mutex> lock(m_mutex);
2015-07-04 22:23:10 +03:00
while (true)
{
2015-07-04 22:23:10 +03:00
CHECK_EMU_STATUS;
2014-09-11 23:18:19 +04:00
2015-07-08 20:45:26 +03:00
if (!lock)
{
lock.lock();
continue;
}
2014-09-11 23:18:19 +04:00
2015-07-04 22:23:10 +03:00
if (m_async_cb.size())
2014-09-11 23:18:19 +04:00
{
2015-07-04 22:23:10 +03:00
async_cb_t func = std::move(m_async_cb.front());
m_async_cb.pop();
2015-07-01 01:25:52 +03:00
if (lock) lock.unlock();
func(ppu);
2015-07-04 22:23:10 +03:00
2014-09-11 23:18:19 +04:00
continue;
}
get_current_thread_cv().wait(lock);
}
2015-07-01 01:25:52 +03:00
};
2016-04-14 02:09:41 +03:00
auto thread = idm::make_ptr<PPUThread>("Callback Thread");
2015-07-01 01:25:52 +03:00
2016-04-14 02:09:41 +03:00
thread->prio = 1001;
thread->stack_size = 0x10000;
thread->custom_task = task;
thread->cpu_init();
2015-07-01 01:25:52 +03:00
2016-04-14 02:09:41 +03:00
m_cb_thread = thread;
}
2014-09-11 23:18:19 +04:00
void CallbackManager::Clear()
{
2014-09-11 23:18:19 +04:00
std::lock_guard<std::mutex> lock(m_mutex);
m_check_cb = decltype(m_check_cb){};
m_async_cb = decltype(m_async_cb){};
2015-07-01 20:09:26 +03:00
m_cb_thread.reset();
}