diff --git a/Core/HLE/KernelWaitHelpers.h b/Core/HLE/KernelWaitHelpers.h index db7257110f..37bd54389d 100644 --- a/Core/HLE/KernelWaitHelpers.h +++ b/Core/HLE/KernelWaitHelpers.h @@ -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 diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 2e1293e586..2886fe2a19 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -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; }