mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-12 13:13:43 +00:00
Merge pull request #752 from Syphurith/patch-syscall-177
SysCalls 177 sys_spu_thread_group_terminate
This commit is contained in:
commit
004df937ed
@ -193,8 +193,8 @@ static func_caller* sc_table[kSyscallTableLength] =
|
|||||||
bind_func(sys_spu_thread_group_start), //173 (0x0AD)
|
bind_func(sys_spu_thread_group_start), //173 (0x0AD)
|
||||||
bind_func(sys_spu_thread_group_suspend), //174 (0x0AE)
|
bind_func(sys_spu_thread_group_suspend), //174 (0x0AE)
|
||||||
bind_func(sys_spu_thread_group_resume), //175 (0x0AF)
|
bind_func(sys_spu_thread_group_resume), //175 (0x0AF)
|
||||||
null_func,//bind_func(sys_spu_thread_group_yield) //176 (0x0B0)
|
bind_func(sys_spu_thread_group_yield), //176 (0x0B0)
|
||||||
null_func,//bind_func(sys_spu_thread_group_terminate) //177 (0x0B1)
|
bind_func(sys_spu_thread_group_terminate), //177 (0x0B1)
|
||||||
bind_func(sys_spu_thread_group_join), //178 (0x0B2)
|
bind_func(sys_spu_thread_group_join), //178 (0x0B2)
|
||||||
null_func,//bind_func(sys_spu_thread_group_set_priority)//179 (0x0B3)
|
null_func,//bind_func(sys_spu_thread_group_set_priority)//179 (0x0B3)
|
||||||
null_func,//bind_func(sys_spu_thread_group_get_priority)//180 (0x0B4)
|
null_func,//bind_func(sys_spu_thread_group_get_priority)//180 (0x0B4)
|
||||||
|
@ -160,10 +160,19 @@ s32 sys_spu_thread_group_destroy(u32 id)
|
|||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group_info->lock) // ???
|
//TODO: New method to check busy. and even maybe in other sys_spu_thread_group_ calls.
|
||||||
|
|
||||||
|
//TODO: SPU_THREAD_GROUP lock may not be gracefully implemented now.
|
||||||
|
// But it could still be set using simple way?
|
||||||
|
//Check the state it should be in NOT_INITIALIZED / INITIALIZED.
|
||||||
|
if ((group_info->m_state != SPU_THREAD_GROUP_STATUS_INITIALIZED)
|
||||||
|
&& (group_info->m_state != SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED))
|
||||||
{
|
{
|
||||||
return CELL_EBUSY;
|
sc_spu.Error("sys_spu_thread_group_destroy(id=%d) is not in NOT_INITIALIZED / INITIALIZED, state=%d", id, group_info->m_state);
|
||||||
|
return CELL_ESTAT; //Indeed this should not be encountered. If program itself all right.
|
||||||
}
|
}
|
||||||
|
//SET BUSY
|
||||||
|
|
||||||
|
|
||||||
for (u32 i = 0; i < group_info->list.size(); i++)
|
for (u32 i = 0; i < group_info->list.size(); i++)
|
||||||
{
|
{
|
||||||
@ -172,6 +181,9 @@ s32 sys_spu_thread_group_destroy(u32 id)
|
|||||||
Emu.GetCPU().RemoveThread(group_info->list[i]);
|
Emu.GetCPU().RemoveThread(group_info->list[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group_info->m_state = SPU_THREAD_GROUP_STATUS_UNKNOWN;
|
||||||
|
//REMOVE BUSY
|
||||||
|
|
||||||
Emu.GetIdManager().RemoveID(id);
|
Emu.GetIdManager().RemoveID(id);
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -189,6 +201,14 @@ s32 sys_spu_thread_group_start(u32 id)
|
|||||||
|
|
||||||
// TODO: check group state
|
// TODO: check group state
|
||||||
|
|
||||||
|
//Check for BUSY?
|
||||||
|
|
||||||
|
//SET BUSY
|
||||||
|
|
||||||
|
//Different from what i expected. Or else there would not be any with RUNNING.
|
||||||
|
group_info->m_state = SPU_THREAD_GROUP_STATUS_READY; //Added Group State
|
||||||
|
//Notice: I can not know the action preformed below be following the definition, but left unchanged.
|
||||||
|
|
||||||
for (u32 i = 0; i < group_info->list.size(); i++)
|
for (u32 i = 0; i < group_info->list.size(); i++)
|
||||||
{
|
{
|
||||||
CPUThread* t = Emu.GetCPU().GetThread(group_info->list[i]);
|
CPUThread* t = Emu.GetCPU().GetThread(group_info->list[i]);
|
||||||
@ -198,6 +218,9 @@ s32 sys_spu_thread_group_start(u32 id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group_info->m_state = SPU_THREAD_GROUP_STATUS_RUNNING; //SPU Thread Group now all in running.
|
||||||
|
//REMOVE BUSY
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,6 +236,17 @@ s32 sys_spu_thread_group_suspend(u32 id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check group state
|
// TODO: check group state
|
||||||
|
//Experimental implementation for the state checking
|
||||||
|
if ((group_info->m_state != SPU_THREAD_GROUP_STATUS_READY)
|
||||||
|
&& (group_info->m_state != SPU_THREAD_GROUP_STATUS_RUNNING)
|
||||||
|
&& (group_info->m_state != SPU_THREAD_GROUP_STATUS_WAITING))
|
||||||
|
{
|
||||||
|
return CELL_ESTAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check for BUSY?
|
||||||
|
|
||||||
|
//SET BUSY
|
||||||
|
|
||||||
for (u32 i = 0; i < group_info->list.size(); i++)
|
for (u32 i = 0; i < group_info->list.size(); i++)
|
||||||
{
|
{
|
||||||
@ -222,6 +256,18 @@ s32 sys_spu_thread_group_suspend(u32 id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Now the state changes.
|
||||||
|
if ((group_info->m_state == SPU_THREAD_GROUP_STATUS_READY)
|
||||||
|
|| (group_info->m_state == SPU_THREAD_GROUP_STATUS_RUNNING))
|
||||||
|
{
|
||||||
|
group_info->m_state = SPU_THREAD_GROUP_STATUS_SUSPENDED;
|
||||||
|
}
|
||||||
|
else if (group_info->m_state == SPU_THREAD_GROUP_STATUS_WAITING)
|
||||||
|
{
|
||||||
|
group_info->m_state = SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED;
|
||||||
|
}
|
||||||
|
//REMOVE BUSY
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,6 +283,24 @@ s32 sys_spu_thread_group_resume(u32 id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check group state
|
// TODO: check group state
|
||||||
|
if ((group_info->m_state != SPU_THREAD_GROUP_STATUS_SUSPENDED)
|
||||||
|
&& (group_info->m_state != SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED))
|
||||||
|
{
|
||||||
|
return CELL_ESTAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Maybe check for BUSY
|
||||||
|
|
||||||
|
//SET BUSY
|
||||||
|
|
||||||
|
if (group_info->m_state == SPU_THREAD_GROUP_STATUS_SUSPENDED)
|
||||||
|
{
|
||||||
|
group_info->m_state = SPU_THREAD_GROUP_STATUS_READY;
|
||||||
|
}
|
||||||
|
else if (group_info->m_state == SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED)
|
||||||
|
{
|
||||||
|
group_info->m_state = SPU_THREAD_GROUP_STATUS_WAITING;
|
||||||
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < group_info->list.size(); i++)
|
for (u32 i = 0; i < group_info->list.size(); i++)
|
||||||
{
|
{
|
||||||
@ -246,6 +310,94 @@ s32 sys_spu_thread_group_resume(u32 id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (group_info->m_state == SPU_THREAD_GROUP_STATUS_READY)
|
||||||
|
{
|
||||||
|
group_info->m_state = SPU_THREAD_GROUP_STATUS_RUNNING;
|
||||||
|
}
|
||||||
|
//REMOVE BUSY
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//176: Left doing nothing, indeed
|
||||||
|
s32 sys_spu_thread_group_yield(u32 id)
|
||||||
|
{
|
||||||
|
sc_spu.Error("sys_spu_thread_group_yield(id=%d)", id);
|
||||||
|
|
||||||
|
SpuGroupInfo* group_info;
|
||||||
|
if (!Emu.GetIdManager().GetIDData(id, group_info))
|
||||||
|
{
|
||||||
|
return CELL_ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
////TODO::implement sys_spu_thread_group_yield.
|
||||||
|
//Sorry i don't know where to get the caller group. So Only checking.
|
||||||
|
//Removed some stupid comments.
|
||||||
|
|
||||||
|
//Check the priority of the target spu group info.
|
||||||
|
//And check the state of target spu.
|
||||||
|
//if ((group_info->m_prio < current_thread.GetPrio())
|
||||||
|
// ||(group_info->m_state != SPU_THREAD_GROUP_STATUS_READY))
|
||||||
|
//{
|
||||||
|
// return CELL_OK;
|
||||||
|
//}
|
||||||
|
|
||||||
|
////Maybe Check for BUSY
|
||||||
|
|
||||||
|
////SET BUSY
|
||||||
|
//for (u32 i = 0; i < current_group_info->list.size(); i++)
|
||||||
|
//{
|
||||||
|
//if (CPUThread* t = Emu.GetCPU().GetThread(current_group_info->list[i]))
|
||||||
|
//{
|
||||||
|
//Not finding anything that suite the yield test. Do nothing.
|
||||||
|
//t->WaitFor(group_info);
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
|
||||||
|
//Do nothing now, so not entering the WAITING state.
|
||||||
|
//current_group_info->m_state = SPU_THREAD_GROUP_STATUS_WAITING;
|
||||||
|
|
||||||
|
////CLEAR BUSY
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//177: Left omit the EPERM check.
|
||||||
|
s32 sys_spu_thread_group_terminate(u32 id, int value)
|
||||||
|
{
|
||||||
|
sc_spu.Error("sys_spu_thread_group_terminate(id=%d, value=%d)", id, value);
|
||||||
|
|
||||||
|
SpuGroupInfo* group_info;
|
||||||
|
if (!Emu.GetIdManager().GetIDData(id, group_info))
|
||||||
|
{
|
||||||
|
return CELL_ESRCH;
|
||||||
|
}
|
||||||
|
if ((group_info->m_state != SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED)
|
||||||
|
&& (group_info->m_state != SPU_THREAD_GROUP_STATUS_INITIALIZED)
|
||||||
|
&& (group_info->m_state != SPU_THREAD_GROUP_STATUS_WAITING))
|
||||||
|
{
|
||||||
|
return CELL_ESTAT;
|
||||||
|
}
|
||||||
|
//TODO::I don't know who should i be referred to check the EPERM.
|
||||||
|
//Also i don't know how to check that is a primary or not. so disabled the EPERM check.
|
||||||
|
//Removed some stupid comments made.
|
||||||
|
|
||||||
|
//Attention. This action may not check for BUSY
|
||||||
|
|
||||||
|
//SET BUSY
|
||||||
|
for (u32 i = 0; i < group_info->list.size(); i++)
|
||||||
|
{
|
||||||
|
if (CPUThread* t = Emu.GetCPU().GetThread(group_info->list[i]))
|
||||||
|
{
|
||||||
|
t->Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
group_info->m_state = SPU_THREAD_GROUP_STATUS_INITIALIZED; // In initialized state but not running, maybe.
|
||||||
|
//Remove BUSY
|
||||||
|
|
||||||
|
group_info->m_exit_status = value;
|
||||||
|
|
||||||
|
////TODO::implement sys_spu_thread_group_terminate
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +432,7 @@ s32 sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
|
|||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group_info->lock.exchange(1)) // acquire lock
|
if (group_info->lock.exchange(1)) // acquire lock TODO:: The lock might be replaced.
|
||||||
{
|
{
|
||||||
return CELL_EBUSY;
|
return CELL_EBUSY;
|
||||||
}
|
}
|
||||||
@ -305,7 +457,7 @@ s32 sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group_info->lock = 0; // release lock
|
group_info->lock = 0; // release lock TODO: this LOCK may be replaced.
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,17 @@
|
|||||||
|
|
||||||
u32 LoadSpuImage(vfsStream& stream, u32& spu_ep);
|
u32 LoadSpuImage(vfsStream& stream, u32& spu_ep);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SYS_SPU_THREAD_GROUP_TYPE_NORMAL = 0x00,
|
||||||
|
SYS_SPU_THREAD_GROUP_TYPE_SEQUENTIAL = 0x01,
|
||||||
|
SYS_SPU_THREAD_GROUP_TYPE_SYSTEM = 0x02,
|
||||||
|
SYS_SPU_THREAD_GROUP_TYPE_MEMORY_FROM_CONTAINER = 0x04,
|
||||||
|
SYS_SPU_THREAD_GROUP_TYPE_NON_CONTEXT = 0x08,
|
||||||
|
SYS_SPU_THREAD_GROUP_TYPE_EXCLUSIVE_NON_CONTEXT = 0x18,
|
||||||
|
SYS_SPU_THREAD_GROUP_TYPE_COOPERATE_WITH_SYSTEM = 0x20
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SYS_SPU_THREAD_GROUP_JOIN_GROUP_EXIT = 0x0001,
|
SYS_SPU_THREAD_GROUP_JOIN_GROUP_EXIT = 0x0001,
|
||||||
@ -9,6 +20,18 @@ enum
|
|||||||
SYS_SPU_THREAD_GROUP_JOIN_TERMINATED = 0x0004
|
SYS_SPU_THREAD_GROUP_JOIN_TERMINATED = 0x0004
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED,
|
||||||
|
SPU_THREAD_GROUP_STATUS_INITIALIZED,
|
||||||
|
SPU_THREAD_GROUP_STATUS_READY,
|
||||||
|
SPU_THREAD_GROUP_STATUS_WAITING,
|
||||||
|
SPU_THREAD_GROUP_STATUS_SUSPENDED,
|
||||||
|
SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED,
|
||||||
|
SPU_THREAD_GROUP_STATUS_RUNNING,
|
||||||
|
SPU_THREAD_GROUP_STATUS_STOPPED,
|
||||||
|
SPU_THREAD_GROUP_STATUS_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SYS_SPU_SEGMENT_TYPE_COPY = 0x0001,
|
SYS_SPU_SEGMENT_TYPE_COPY = 0x0001,
|
||||||
@ -65,6 +88,8 @@ struct SpuGroupInfo
|
|||||||
int m_type;
|
int m_type;
|
||||||
int m_ct;
|
int m_ct;
|
||||||
u32 m_count;
|
u32 m_count;
|
||||||
|
int m_state; //SPU Thread Group State.
|
||||||
|
int m_exit_status;
|
||||||
|
|
||||||
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)
|
||||||
@ -74,8 +99,11 @@ struct SpuGroupInfo
|
|||||||
, lock(0)
|
, lock(0)
|
||||||
, m_count(num)
|
, m_count(num)
|
||||||
{
|
{
|
||||||
|
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_exit_status = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -88,6 +116,8 @@ s32 sys_spu_thread_group_destroy(u32 id);
|
|||||||
s32 sys_spu_thread_group_start(u32 id);
|
s32 sys_spu_thread_group_start(u32 id);
|
||||||
s32 sys_spu_thread_group_suspend(u32 id);
|
s32 sys_spu_thread_group_suspend(u32 id);
|
||||||
s32 sys_spu_thread_group_resume(u32 id);
|
s32 sys_spu_thread_group_resume(u32 id);
|
||||||
|
s32 sys_spu_thread_group_yield(u32 id);
|
||||||
|
s32 sys_spu_thread_group_terminate(u32 id, int value);
|
||||||
s32 sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu_thread_group_attribute> attr);
|
s32 sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu_thread_group_attribute> attr);
|
||||||
s32 sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr);
|
s32 sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr);
|
||||||
s32 sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status);
|
s32 sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user