From 411c711daceeea0d84f1675299700f4573f54c0e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 9 Feb 2013 02:17:19 -0800 Subject: [PATCH] Initial sceKernelRotateThreadReadyQueue(). Might not be right but it's closer. Makes games that call this func much faster. --- Core/HLE/sceKernel.cpp | 2 +- Core/HLE/sceKernelThread.cpp | 25 +++++++++++++++++++++++-- Core/HLE/sceKernelThread.h | 2 +- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index b31719cc08..04e5a8368e 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 293bab900e..93e8f8b794 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 86a158b5a4..1000f9597a 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();