diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index b31719cc0..04e5a8368 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -590,7 +590,7 @@ const HLEFunction ThreadManForUser[] = {0x75156e8f,sceKernelResumeThread,"sceKernelResumeThread"}, {0x3ad58b8c,&WrapU_V,"sceKernelSuspendDispatchThread"}, {0x27e22ec2,&WrapU_U,"sceKernelResumeDispatchThread"}, - {0x912354a7,sceKernelRotateThreadReadyQueue,"sceKernelRotateThreadReadyQueue"}, + {0x912354a7,&WrapI_I,"sceKernelRotateThreadReadyQueue"}, {0x9ACE131E,sceKernelSleepThread,"sceKernelSleepThread"}, {0x82826f70,sceKernelSleepThreadCB,"sceKernelSleepThreadCB"}, {0xF475845D,&WrapI_IUU,"sceKernelStartThread"}, diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 293bab900..93e8f8b79 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1600,10 +1600,31 @@ u32 sceKernelResumeDispatchThread(u32 suspended) return oldDispatchSuspended; } -void sceKernelRotateThreadReadyQueue() +int sceKernelRotateThreadReadyQueue(int priority) { DEBUG_LOG(HLE,"sceKernelRotateThreadReadyQueue : rescheduling"); - hleReSchedule("rotatethreadreadyqueue"); + + // TODO: Does it try better-priority threads? Is 0 special? + if (!threadReadyQueue[priority].empty()) + { + Thread *cur = __GetCurrentThread(); + // TODO: Who gets switched to with currentThread-priority? Next or next-next? + if (cur->nt.currentPriority == priority) + __KernelChangeReadyState(currentThread, true); + + size_t readySize = threadReadyQueue[priority].size(); + if (readySize > 1) + { + SceUID first = threadReadyQueue[priority][0]; + memmove(&threadReadyQueue[priority][0], &threadReadyQueue[priority][1], (readySize - 1) * sizeof(SceUID)); + threadReadyQueue[priority][readySize - 1] = first; + } + hleReSchedule("rotatethreadreadyqueue"); + } + // TODO: Does it reschedule in other cases? + + // TODO: Any way to get a different return? + return 0; } int sceKernelDeleteThread(int threadHandle) diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 86a158b5a..1000f9597 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -46,7 +46,7 @@ u32 sceKernelReferThreadStatus(u32 uid, u32 statusPtr); u32 sceKernelReferThreadRunStatus(u32 uid, u32 statusPtr); int sceKernelReleaseWaitThread(SceUID threadID); void sceKernelChangeCurrentThreadAttr(); -void sceKernelRotateThreadReadyQueue(); +int sceKernelRotateThreadReadyQueue(int priority); void sceKernelCheckThreadStack(); void sceKernelSuspendThread(); void sceKernelResumeThread();