mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 08:09:26 +01:00
Create a new thread for AX and make it handle the command lists
This commit is contained in:
parent
3195916744
commit
9e813502ac
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
CUCode_NewAX::CUCode_NewAX(DSPHLE* dsp_hle, u32 crc)
|
CUCode_NewAX::CUCode_NewAX(DSPHLE* dsp_hle, u32 crc)
|
||||||
: IUCode(dsp_hle, crc)
|
: IUCode(dsp_hle, crc)
|
||||||
|
, m_cmdlist_addr(0)
|
||||||
|
, m_axthread(&CUCode_NewAX::AXThread, this)
|
||||||
{
|
{
|
||||||
m_rMailHandler.PushMail(DSP_INIT);
|
m_rMailHandler.PushMail(DSP_INIT);
|
||||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
@ -27,14 +29,46 @@ CUCode_NewAX::CUCode_NewAX(DSPHLE* dsp_hle, u32 crc)
|
|||||||
|
|
||||||
CUCode_NewAX::~CUCode_NewAX()
|
CUCode_NewAX::~CUCode_NewAX()
|
||||||
{
|
{
|
||||||
|
m_cmdlist_addr = (u32)-1; // Special value to signal end
|
||||||
|
NotifyAXThread();
|
||||||
|
m_axthread.join();
|
||||||
|
|
||||||
m_rMailHandler.Clear();
|
m_rMailHandler.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CUCode_NewAX::AXThread()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lk(m_cmdlist_mutex);
|
||||||
|
while (m_cmdlist_addr == 0)
|
||||||
|
m_cmdlist_cv.wait(lk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_cmdlist_addr == (u32)-1) // End of thread signal
|
||||||
|
break;
|
||||||
|
|
||||||
|
m_processing.lock();
|
||||||
|
HandleCommandList(m_cmdlist_addr);
|
||||||
|
m_cmdlist_addr = 0;
|
||||||
|
|
||||||
|
// Signal end of processing
|
||||||
|
m_rMailHandler.PushMail(DSP_YIELD);
|
||||||
|
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
|
m_processing.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CUCode_NewAX::NotifyAXThread()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lk(m_cmdlist_mutex);
|
||||||
|
m_cmdlist_cv.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
void CUCode_NewAX::HandleCommandList(u32 addr)
|
void CUCode_NewAX::HandleCommandList(u32 addr)
|
||||||
{
|
{
|
||||||
// Signal end of processing
|
WARN_LOG(DSPHLE, "TODO: HandleCommandList(%08x)", addr);
|
||||||
m_rMailHandler.PushMail(DSP_YIELD);
|
|
||||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CUCode_NewAX::HandleMail(u32 mail)
|
void CUCode_NewAX::HandleMail(u32 mail)
|
||||||
@ -43,9 +77,15 @@ void CUCode_NewAX::HandleMail(u32 mail)
|
|||||||
static bool next_is_cmdlist = false;
|
static bool next_is_cmdlist = false;
|
||||||
bool set_next_is_cmdlist = false;
|
bool set_next_is_cmdlist = false;
|
||||||
|
|
||||||
|
// Wait for DSP processing to be done before answering any mail. This is
|
||||||
|
// safe to do because it matches what the DSP does on real hardware: there
|
||||||
|
// is no interrupt when a mail from CPU is received.
|
||||||
|
m_processing.lock();
|
||||||
|
|
||||||
if (next_is_cmdlist)
|
if (next_is_cmdlist)
|
||||||
{
|
{
|
||||||
HandleCommandList(mail);
|
m_cmdlist_addr = mail;
|
||||||
|
NotifyAXThread();
|
||||||
}
|
}
|
||||||
else if (m_UploadSetupInProgress)
|
else if (m_UploadSetupInProgress)
|
||||||
{
|
{
|
||||||
@ -81,6 +121,7 @@ void CUCode_NewAX::HandleMail(u32 mail)
|
|||||||
ERROR_LOG(DSPHLE, "Unknown mail sent to AX::HandleMail: %08x", mail);
|
ERROR_LOG(DSPHLE, "Unknown mail sent to AX::HandleMail: %08x", mail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_processing.unlock();
|
||||||
next_is_cmdlist = set_next_is_cmdlist;
|
next_is_cmdlist = set_next_is_cmdlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,5 +143,7 @@ void CUCode_NewAX::Update(int cycles)
|
|||||||
|
|
||||||
void CUCode_NewAX::DoState(PointerWrap& p)
|
void CUCode_NewAX::DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(m_processing);
|
||||||
|
|
||||||
DoStateShared(p);
|
DoStateShared(p);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,22 @@ private:
|
|||||||
MAIL_CMDLIST_MASK = 0xFFFF0000
|
MAIL_CMDLIST_MASK = 0xFFFF0000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Volatile because it's set by HandleMail and accessed in
|
||||||
|
// HandleCommandList, which are running in two different threads.
|
||||||
|
volatile u32 m_cmdlist_addr;
|
||||||
|
|
||||||
|
std::thread m_axthread;
|
||||||
|
|
||||||
|
// Sync objects
|
||||||
|
std::mutex m_processing;
|
||||||
|
std::condition_variable m_cmdlist_cv;
|
||||||
|
std::mutex m_cmdlist_mutex;
|
||||||
|
|
||||||
|
// Send a notification to the AX thread to tell him a new cmdlist addr is
|
||||||
|
// available for processing.
|
||||||
|
void NotifyAXThread();
|
||||||
|
|
||||||
|
void AXThread();
|
||||||
void HandleCommandList(u32 addr);
|
void HandleCommandList(u32 addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user