Merge pull request #13703 from hrydgard/get-thread-exit-status-delay

Guess at a fix for #13698 - sceKernelThreadGetExitStatus probably takes some cycles.
This commit is contained in:
Henrik Rydgård 2020-11-23 15:10:01 +01:00 committed by GitHub
commit 6982a39801
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 6 deletions

View file

@ -2335,7 +2335,7 @@ void __KernelReturnFromModuleFunc()
SceUID leftModuleID = __KernelGetCurThreadModuleId();
SceUID leftThreadID = __KernelGetCurThread();
int exitStatus = sceKernelGetThreadExitStatus(leftThreadID);
int exitStatus = __KernelGetThreadExitStatus(leftThreadID);
// Reschedule immediately (to leave the thread) and delete it and its stack.
__KernelReSchedule("returned from module");

View file

@ -1333,30 +1333,38 @@ u32 sceKernelReferThreadRunStatus(u32 threadID, u32 statusPtr)
return 0;
}
int sceKernelGetThreadExitStatus(SceUID threadID)
{
int __KernelGetThreadExitStatus(SceUID threadID) {
u32 error;
PSPThread *t = kernelObjects.Get<PSPThread>(threadID, error);
if (t)
{
if (t->nt.status == THREADSTATUS_DORMANT) // TODO: can be dormant before starting, too, need to avoid that
{
DEBUG_LOG(SCEKERNEL,"sceKernelGetThreadExitStatus(%i)", threadID);
DEBUG_LOG(SCEKERNEL, "sceKernelGetThreadExitStatus(%d)", threadID);
return t->nt.exitStatus;
}
else
{
DEBUG_LOG(SCEKERNEL,"sceKernelGetThreadExitStatus(%i): not dormant", threadID);
DEBUG_LOG(SCEKERNEL, "sceKernelGetThreadExitStatus(%d): not dormant", threadID);
return SCE_KERNEL_ERROR_NOT_DORMANT;
}
}
else
{
ERROR_LOG(SCEKERNEL,"sceKernelGetThreadExitStatus Error %08x", error);
ERROR_LOG(SCEKERNEL, "sceKernelGetThreadExitStatus Error %08x", error);
return SCE_KERNEL_ERROR_UNKNOWN_THID;
}
}
int sceKernelGetThreadExitStatus(SceUID threadID)
{
u32 status = __KernelGetThreadExitStatus(threadID);
// Seems this is called in a tight-ish loop, maybe awaiting an interrupt - issue #13698
// Guess based on sceKernelGetThreadId.
hleEatCycles(180);
return status;
}
u32 sceKernelGetThreadmanIdType(u32 uid) {
int type;
if (kernelObjects.GetIDType(uid, &type)) {

View file

@ -48,6 +48,7 @@ int sceKernelGetThreadCurrentPriority();
// Warning: will alter v0 in current MIPS state.
int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs = false);
int __KernelStartThreadValidate(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs = false);
int __KernelGetThreadExitStatus(SceUID threadID);
int sceKernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr);
u32 sceKernelSuspendDispatchThread();
u32 sceKernelResumeDispatchThread(u32 suspended);