Improve sceKernelDelayThread() timing.

A delay of 0 never reschedules, actually, unless there's a better priority
thread.  A greater delay depends on if a >= or similar check matches, but
generally is at least 200us.

It seems like this actually completes in at least another 10-20us.
This commit is contained in:
Unknown W. Brackets 2014-06-22 19:44:43 -07:00
parent 8851fc1685
commit e8803c4e9b
2 changed files with 29 additions and 23 deletions

View File

@ -45,7 +45,7 @@ inline void WaitExecTimeout(SceUID threadID) {
}
}
// Move a thead from the waiting thread list to the paused thread list.
// Move a thread from the waiting thread list to the paused thread list.
// This version is for vectors which contain structs, which must have SceUID threadID and u64 pausedTimeout.
// Should not be called directly.
template <typename WaitInfoType, typename PauseType>

View File

@ -2594,33 +2594,39 @@ int sceKernelChangeThreadPriority(SceUID threadID, int priority)
}
}
s64 __KernelDelayThreadUs(u64 usec)
{
// Seems to very based on clockrate / other things, but 0 delays less than 200us for sure.
if (usec == 0)
return 100;
else if (usec < 200)
return 200;
return usec;
s64 __KernelDelayThreadUs(u64 usec) {
if (usec < 200) {
return 210;
}
// It never wakes up right away. It usually takes at least 15 extra us, but let's be nicer.
return usec + 10;
}
int sceKernelDelayThreadCB(u32 usec)
{
DEBUG_LOG(SCEKERNEL,"sceKernelDelayThreadCB(%i usec)",usec);
SceUID curThread = __KernelGetCurThread();
__KernelScheduleWakeup(curThread, __KernelDelayThreadUs(usec));
__KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, true, "thread delayed");
int sceKernelDelayThreadCB(u32 usec) {
hleEatCycles(2000);
if (usec > 0) {
DEBUG_LOG(SCEKERNEL, "sceKernelDelayThreadCB(%i usec)", usec);
SceUID curThread = __KernelGetCurThread();
__KernelScheduleWakeup(curThread, __KernelDelayThreadUs(usec));
__KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, true, "thread delayed");
} else {
DEBUG_LOG(SCEKERNEL, "sceKernelDelayThreadCB(%i usec): no delay", usec);
hleReSchedule("thread delayed");
}
return 0;
}
int sceKernelDelayThread(u32 usec)
{
DEBUG_LOG(SCEKERNEL,"sceKernelDelayThread(%i usec)",usec);
SceUID curThread = __KernelGetCurThread();
__KernelScheduleWakeup(curThread, __KernelDelayThreadUs(usec));
__KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, false, "thread delayed");
int sceKernelDelayThread(u32 usec) {
hleEatCycles(2000);
if (usec > 0) {
DEBUG_LOG(SCEKERNEL, "sceKernelDelayThread(%i usec)", usec);
SceUID curThread = __KernelGetCurThread();
__KernelScheduleWakeup(curThread, __KernelDelayThreadUs(usec));
__KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, false, "thread delayed");
} else {
DEBUG_LOG(SCEKERNEL, "sceKernelDelayThread(%i usec): no delay", usec);
hleReSchedule("thread delayed");
}
return 0;
}