mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-08 07:51:28 +12:00
sys_spu_thread_group_exit
This commit is contained in:
parent
1065eb17de
commit
d5aa7aae43
3 changed files with 70 additions and 11 deletions
|
@ -494,6 +494,7 @@ bool SPUThread::CheckEvents()
|
||||||
{
|
{
|
||||||
// checks events:
|
// checks events:
|
||||||
// SPU_EVENT_LR:
|
// SPU_EVENT_LR:
|
||||||
|
if (R_ADDR)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < 16; i++)
|
for (u32 i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
|
@ -949,11 +950,14 @@ void SPUThread::ReadChannel(SPU_GPR_hdr& r, u32 ch)
|
||||||
void SPUThread::StopAndSignal(u32 code)
|
void SPUThread::StopAndSignal(u32 code)
|
||||||
{
|
{
|
||||||
SetExitStatus(code); // exit code (not status)
|
SetExitStatus(code); // exit code (not status)
|
||||||
|
// TODO: process interrupts for RawSPU
|
||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case 0x110: /* ===== sys_spu_thread_receive_event ===== */
|
case 0x110:
|
||||||
{
|
{
|
||||||
|
/* ===== sys_spu_thread_receive_event ===== */
|
||||||
|
|
||||||
u32 spuq = 0;
|
u32 spuq = 0;
|
||||||
if (!SPU.Out_MBox.Pop(spuq))
|
if (!SPU.Out_MBox.Pop(spuq))
|
||||||
{
|
{
|
||||||
|
@ -1027,22 +1031,60 @@ void SPUThread::StopAndSignal(u32 code)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x101:
|
||||||
|
{
|
||||||
|
/* ===== sys_spu_thread_group_exit ===== */
|
||||||
|
|
||||||
|
if (!group)
|
||||||
|
{
|
||||||
|
LOG_ERROR(Log::SPU, "sys_spu_thread_group_exit(): group not set");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (!SPU.Out_MBox.GetCount())
|
||||||
|
{
|
||||||
|
LOG_ERROR(Log::SPU, "sys_spu_thread_group_exit(): Out_MBox is empty");
|
||||||
|
}
|
||||||
|
else if (Ini.HLELogging.GetValue())
|
||||||
|
{
|
||||||
|
LOG_NOTICE(Log::SPU, "sys_spu_thread_group_exit(status=0x%x)", SPU.Out_MBox.GetValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
group->m_group_exit = true;
|
||||||
|
group->m_exit_status = SPU.Out_MBox.GetValue();
|
||||||
|
for (auto& v : group->list)
|
||||||
|
{
|
||||||
|
if (CPUThread* t = Emu.GetCPU().GetThread(v))
|
||||||
|
{
|
||||||
|
t->Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x102:
|
case 0x102:
|
||||||
|
{
|
||||||
|
/* ===== sys_spu_thread_exit ===== */
|
||||||
|
|
||||||
if (!SPU.Out_MBox.GetCount())
|
if (!SPU.Out_MBox.GetCount())
|
||||||
{
|
{
|
||||||
LOG_ERROR(Log::SPU, "sys_spu_thread_exit (no status, code 0x102)");
|
LOG_ERROR(Log::SPU, "sys_spu_thread_exit(): Out_MBox is empty");
|
||||||
}
|
}
|
||||||
else if (Ini.HLELogging.GetValue())
|
else if (Ini.HLELogging.GetValue())
|
||||||
{
|
{
|
||||||
// the real exit status
|
// the real exit status
|
||||||
LOG_NOTICE(Log::SPU, "sys_spu_thread_exit (status=0x%x)", SPU.Out_MBox.GetValue());
|
LOG_NOTICE(Log::SPU, "sys_spu_thread_exit(status=0x%x)", SPU.Out_MBox.GetValue());
|
||||||
}
|
}
|
||||||
SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_STOP);
|
SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_STOP);
|
||||||
Stop();
|
Stop();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
if (!SPU.Out_MBox.GetCount())
|
if (!SPU.Out_MBox.GetCount())
|
||||||
{
|
{
|
||||||
LOG_ERROR(Log::SPU, "Unknown STOP code: 0x%x (no message)", code);
|
LOG_ERROR(Log::SPU, "Unknown STOP code: 0x%x (no message)", code);
|
||||||
|
@ -1051,8 +1093,8 @@ void SPUThread::StopAndSignal(u32 code)
|
||||||
{
|
{
|
||||||
LOG_ERROR(Log::SPU, "Unknown STOP code: 0x%x (message=0x%x)", code, SPU.Out_MBox.GetValue());
|
LOG_ERROR(Log::SPU, "Unknown STOP code: 0x%x (message=0x%x)", code, SPU.Out_MBox.GetValue());
|
||||||
}
|
}
|
||||||
SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_STOP);
|
|
||||||
Stop();
|
Stop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -387,6 +387,7 @@ s32 sys_spu_thread_group_terminate(u32 id, int value)
|
||||||
{
|
{
|
||||||
if (CPUThread* t = Emu.GetCPU().GetThread(group_info->list[i]))
|
if (CPUThread* t = Emu.GetCPU().GetThread(group_info->list[i]))
|
||||||
{
|
{
|
||||||
|
((SPUThread*)t)->SPU.Status.SetValue(SPU_STATUS_STOPPED);
|
||||||
t->Stop();
|
t->Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,15 +436,17 @@ s32 sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
|
||||||
return CELL_EBUSY;
|
return CELL_EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause.GetAddr()) cause = SYS_SPU_THREAD_GROUP_JOIN_ALL_THREADS_EXIT;
|
bool all_threads_exit = true;
|
||||||
if (status.GetAddr()) status = 0; //unspecified because of ALL_THREADS_EXIT
|
|
||||||
|
|
||||||
for (u32 i = 0; i < group_info->list.size(); i++)
|
for (u32 i = 0; i < group_info->list.size(); i++)
|
||||||
{
|
{
|
||||||
while (CPUThread* t = Emu.GetCPU().GetThread(group_info->list[i]))
|
while (CPUThread* t = Emu.GetCPU().GetThread(group_info->list[i]))
|
||||||
{
|
{
|
||||||
if (!t->IsRunning())
|
if (!t->IsRunning())
|
||||||
{
|
{
|
||||||
|
if (((SPUThread*)t)->SPU.Status.GetValue() != SPU_STATUS_STOPPED_BY_STOP)
|
||||||
|
{
|
||||||
|
all_threads_exit = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (Emu.IsStopped())
|
if (Emu.IsStopped())
|
||||||
|
@ -455,6 +458,17 @@ s32 sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cause.GetAddr())
|
||||||
|
{
|
||||||
|
cause = group_info->m_group_exit
|
||||||
|
? SYS_SPU_THREAD_GROUP_JOIN_GROUP_EXIT
|
||||||
|
: (all_threads_exit
|
||||||
|
? SYS_SPU_THREAD_GROUP_JOIN_ALL_THREADS_EXIT
|
||||||
|
: SYS_SPU_THREAD_GROUP_JOIN_TERMINATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.GetAddr()) status = group_info->m_exit_status;
|
||||||
|
|
||||||
group_info->m_state = SPU_THREAD_GROUP_STATUS_INITIALIZED;
|
group_info->m_state = SPU_THREAD_GROUP_STATUS_INITIALIZED;
|
||||||
group_info->lock = 0; // release lock TODO: this LOCK may be replaced.
|
group_info->lock = 0; // release lock TODO: this LOCK may be replaced.
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
|
|
@ -89,7 +89,8 @@ struct SpuGroupInfo
|
||||||
int m_ct;
|
int m_ct;
|
||||||
u32 m_count;
|
u32 m_count;
|
||||||
int m_state; //SPU Thread Group State.
|
int m_state; //SPU Thread Group State.
|
||||||
int m_exit_status;
|
u32 m_exit_status;
|
||||||
|
bool m_group_exit;
|
||||||
|
|
||||||
SpuGroupInfo(const std::string& name, u32 num, int prio, int type, u32 ct)
|
SpuGroupInfo(const std::string& name, u32 num, int prio, int type, u32 ct)
|
||||||
: m_name(name)
|
: m_name(name)
|
||||||
|
@ -98,12 +99,14 @@ struct SpuGroupInfo
|
||||||
, m_ct(ct)
|
, m_ct(ct)
|
||||||
, lock(0)
|
, lock(0)
|
||||||
, m_count(num)
|
, m_count(num)
|
||||||
|
, m_state(0)
|
||||||
|
, m_exit_status(0)
|
||||||
|
, m_group_exit(false)
|
||||||
{
|
{
|
||||||
m_state = SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED; //Before all the nums done, it is not initialized.
|
m_state = SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED; //Before all the nums done, it is not initialized.
|
||||||
list.resize(256);
|
list.resize(256);
|
||||||
for (auto& v : list) v = 0;
|
for (auto& v : list) v = 0;
|
||||||
m_state = SPU_THREAD_GROUP_STATUS_INITIALIZED; //Then Ready to Start. Cause Reference use New i can only place this here.
|
m_state = SPU_THREAD_GROUP_STATUS_INITIALIZED; //Then Ready to Start. Cause Reference use New i can only place this here.
|
||||||
m_exit_status = 0;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue