2013-11-03 20:23:16 +01:00
|
|
|
#include "stdafx.h"
|
2014-06-02 19:27:24 +02:00
|
|
|
#include "Emu/Memory/Memory.h"
|
|
|
|
|
#include "Emu/System.h"
|
2014-07-12 09:02:39 +02:00
|
|
|
#include "Emu/DbgCommand.h"
|
2014-06-02 19:27:24 +02:00
|
|
|
|
2014-08-26 01:55:37 +02:00
|
|
|
#include "Emu/IdManager.h"
|
2013-11-03 20:23:16 +01:00
|
|
|
#include "CPUThreadManager.h"
|
2013-11-19 11:30:58 +01:00
|
|
|
#include "Emu/Cell/PPUThread.h"
|
|
|
|
|
#include "Emu/Cell/SPUThread.h"
|
|
|
|
|
#include "Emu/Cell/RawSPUThread.h"
|
|
|
|
|
#include "Emu/ARMv7/ARMv7Thread.h"
|
2013-11-03 20:23:16 +01:00
|
|
|
|
|
|
|
|
CPUThreadManager::CPUThreadManager()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CPUThreadManager::~CPUThreadManager()
|
|
|
|
|
{
|
|
|
|
|
Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CPUThreadManager::Close()
|
|
|
|
|
{
|
2014-04-10 00:54:32 +02:00
|
|
|
while(m_threads.size()) RemoveThread(m_threads[0]->GetId());
|
2013-11-03 20:23:16 +01:00
|
|
|
}
|
|
|
|
|
|
2015-03-04 22:51:14 +01:00
|
|
|
std::shared_ptr<CPUThread> CPUThreadManager::AddThread(CPUThreadType type)
|
2013-11-03 20:23:16 +01:00
|
|
|
{
|
2015-03-04 22:51:14 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2013-11-03 20:23:16 +01:00
|
|
|
|
2014-12-24 00:38:13 +01:00
|
|
|
std::shared_ptr<CPUThread> new_thread;
|
2013-11-03 20:23:16 +01:00
|
|
|
|
|
|
|
|
switch(type)
|
|
|
|
|
{
|
2014-07-16 14:06:58 +02:00
|
|
|
case CPU_THREAD_PPU:
|
|
|
|
|
{
|
2015-05-27 05:11:59 +02:00
|
|
|
new_thread = std::make_shared<PPUThread>();
|
2014-07-16 14:06:58 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case CPU_THREAD_SPU:
|
|
|
|
|
{
|
2015-05-27 05:11:59 +02:00
|
|
|
new_thread = std::make_shared<SPUThread>();
|
2014-07-16 14:06:58 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case CPU_THREAD_RAW_SPU:
|
|
|
|
|
{
|
2015-03-04 22:51:14 +01:00
|
|
|
for (u32 i = 0; i < m_raw_spu.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
if (!m_raw_spu[i])
|
|
|
|
|
{
|
2015-05-27 05:11:59 +02:00
|
|
|
new_thread = std::make_shared<RawSPUThread>();
|
2015-03-04 22:51:14 +01:00
|
|
|
new_thread->index = i;
|
|
|
|
|
|
|
|
|
|
m_raw_spu[i] = new_thread;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-07-16 14:06:58 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case CPU_THREAD_ARMv7:
|
|
|
|
|
{
|
2014-12-24 00:38:13 +01:00
|
|
|
new_thread.reset(new ARMv7Thread());
|
2014-07-16 14:06:58 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2013-11-03 20:23:16 +01:00
|
|
|
default: assert(0);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 22:51:14 +01:00
|
|
|
if (new_thread)
|
|
|
|
|
{
|
2015-05-27 05:11:59 +02:00
|
|
|
new_thread->SetId(Emu.GetIdManager().add(new_thread));
|
2015-03-04 22:51:14 +01:00
|
|
|
|
|
|
|
|
m_threads.push_back(new_thread);
|
|
|
|
|
SendDbgCommand(DID_CREATE_THREAD, new_thread.get());
|
|
|
|
|
}
|
2013-11-03 20:23:16 +01:00
|
|
|
|
2015-03-04 22:51:14 +01:00
|
|
|
return new_thread;
|
2013-11-03 20:23:16 +01:00
|
|
|
}
|
|
|
|
|
|
2015-03-04 22:51:14 +01:00
|
|
|
void CPUThreadManager::RemoveThread(u32 id)
|
2013-11-03 20:23:16 +01:00
|
|
|
{
|
2015-03-04 22:51:14 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2013-11-03 20:23:16 +01:00
|
|
|
|
2014-12-24 00:38:13 +01:00
|
|
|
std::shared_ptr<CPUThread> thr;
|
2014-04-15 16:12:15 +02:00
|
|
|
u32 thread_index = 0;
|
|
|
|
|
|
|
|
|
|
for (u32 i = 0; i < m_threads.size(); ++i)
|
2013-11-03 20:23:16 +01:00
|
|
|
{
|
2014-04-15 16:12:15 +02:00
|
|
|
if (m_threads[i]->GetId() != id) continue;
|
2013-11-03 20:23:16 +01:00
|
|
|
|
2014-04-15 16:12:15 +02:00
|
|
|
thr = m_threads[i];
|
|
|
|
|
thread_index = i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (thr)
|
|
|
|
|
{
|
2014-12-24 00:38:13 +01:00
|
|
|
SendDbgCommand(DID_REMOVE_THREAD, thr.get());
|
2014-01-31 19:40:18 +01:00
|
|
|
thr->Close();
|
2013-11-03 20:23:16 +01:00
|
|
|
|
2014-04-15 16:12:15 +02:00
|
|
|
m_threads.erase(m_threads.begin() + thread_index);
|
2015-03-04 22:51:14 +01:00
|
|
|
|
|
|
|
|
if (thr->GetType() == CPU_THREAD_RAW_SPU)
|
|
|
|
|
{
|
|
|
|
|
assert(thr->index < m_raw_spu.size());
|
|
|
|
|
m_raw_spu[thr->index] = nullptr;
|
|
|
|
|
}
|
2013-11-03 20:23:16 +01:00
|
|
|
}
|
|
|
|
|
|
2014-04-15 16:12:15 +02:00
|
|
|
// Removing the ID should trigger the actual deletion of the thread
|
2015-05-27 05:11:59 +02:00
|
|
|
Emu.GetIdManager().remove<CPUThread>(id);
|
2013-11-03 20:23:16 +01:00
|
|
|
Emu.CheckStatus();
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-24 00:38:13 +01:00
|
|
|
std::shared_ptr<CPUThread> CPUThreadManager::GetThread(u32 id)
|
2013-11-03 20:23:16 +01:00
|
|
|
{
|
2015-05-27 05:11:59 +02:00
|
|
|
return Emu.GetIdManager().get<CPUThread>(id);
|
2013-11-03 20:23:16 +01:00
|
|
|
}
|
|
|
|
|
|
2015-01-23 22:48:14 +01:00
|
|
|
std::shared_ptr<CPUThread> CPUThreadManager::GetThread(u32 id, CPUThreadType type)
|
|
|
|
|
{
|
2015-04-14 04:00:31 +02:00
|
|
|
const auto res = GetThread(id);
|
2015-01-23 22:48:14 +01:00
|
|
|
|
2015-04-14 04:00:31 +02:00
|
|
|
return res && res->GetType() == type ? res : nullptr;
|
2015-01-23 22:48:14 +01:00
|
|
|
}
|
|
|
|
|
|
2015-03-04 22:51:14 +01:00
|
|
|
std::shared_ptr<CPUThread> CPUThreadManager::GetRawSPUThread(u32 index)
|
2014-06-23 03:03:16 +02:00
|
|
|
{
|
2015-03-04 22:51:14 +01:00
|
|
|
if (index >= m_raw_spu.size())
|
2014-07-10 02:13:04 +02:00
|
|
|
{
|
|
|
|
|
return nullptr;
|
2014-06-23 03:03:16 +02:00
|
|
|
}
|
2015-03-04 22:51:14 +01:00
|
|
|
|
|
|
|
|
return m_raw_spu[index];
|
2014-06-23 03:03:16 +02:00
|
|
|
}
|
|
|
|
|
|
2013-11-03 20:23:16 +01:00
|
|
|
void CPUThreadManager::Exec()
|
|
|
|
|
{
|
2015-03-04 22:51:14 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2014-02-02 20:49:10 +01:00
|
|
|
|
2014-12-19 12:31:52 +01:00
|
|
|
for(u32 i = 0; i < m_threads.size(); ++i)
|
2013-11-03 20:23:16 +01:00
|
|
|
{
|
2014-04-10 00:54:32 +02:00
|
|
|
m_threads[i]->Exec();
|
2013-11-03 20:23:16 +01:00
|
|
|
}
|
2013-11-19 11:30:58 +01:00
|
|
|
}
|