From b58032039b26dc281dbc1f3e5de0d6b4ecc2998d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 11 Nov 2012 18:54:06 -0800 Subject: [PATCH] Cleanup sceKernel semaphore funcs. Remove some duplication of code so it's cleaner. --- Core/HLE/sceKernelSemaphore.cpp | 114 +++++++++++++------------------- 1 file changed, 45 insertions(+), 69 deletions(-) diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index 5c7246eb8c..1e2270eaa8 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -57,6 +57,26 @@ struct Semaphore : public KernelObject std::vector waitingThreads; }; +// Resume all waiting threads (for delete / cancel.) +// Returns true if it woke any threads. +bool __KernelClearSemaThreads(Semaphore *s, int reason) +{ + bool wokeThreads = false; + + std::vector::iterator iter; + for (iter = s->waitingThreads.begin(); iter!=s->waitingThreads.end(); iter++) + { + SceUID threadID = *iter; + + // TODO: Set returnValue = reason? + __KernelResumeThreadFromWait(threadID); + wokeThreads = true; + } + s->waitingThreads.empty(); + + return wokeThreads; +} + int sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr) { DEBUG_LOG(HLE,"sceKernelCancelSema(%i)", id); @@ -77,20 +97,8 @@ int sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr) s->ns.currentCount = newCount; s->ns.numWaitThreads = 0; - bool wokeThreads = false; - - std::vector::iterator iter; - for (iter = s->waitingThreads.begin(); iter!=s->waitingThreads.end(); iter++) - { - SceUID threadID = *iter; - - // TODO: Set SCE_KERNEL_ERROR_WAIT_CANCEL returnValue? - __KernelResumeThreadFromWait(threadID); - wokeThreads = true; - } - s->waitingThreads.empty(); - - if (wokeThreads) + // TODO: Should this reschedule? + if (__KernelClearSemaThreads(s, SCE_KERNEL_ERROR_WAIT_CANCEL)) __KernelReSchedule("semaphore cancelled"); return 0; @@ -132,21 +140,8 @@ int sceKernelDeleteSema(SceUID id) Semaphore *s = kernelObjects.Get(id, error); if (s) { - bool wokeThreads = false; - - std::vector::iterator iter; - for (iter = s->waitingThreads.begin(); iter!=s->waitingThreads.end(); iter++) - { - SceUID threadID = *iter; - - // TODO: Set SCE_KERNEL_ERROR_WAIT_DELETE returnValue? - __KernelResumeThreadFromWait(threadID); - wokeThreads = true; - } - s->waitingThreads.empty(); - // TODO: Should this reschedule? threads/semaphores fails if it doesn't. - if (wokeThreads) + if (__KernelClearSemaThreads(s, SCE_KERNEL_ERROR_WAIT_DELETE)) __KernelReSchedule("semaphore deleted"); return kernelObjects.Destroy(id); @@ -230,32 +225,39 @@ retry: } } -//int sceKernelWaitSema(SceUID semaid, int signal, SceUInt *timeout); -int sceKernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr) +int __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *badSemaMessage, bool processCallbacks) { u32 error; Semaphore *s = kernelObjects.Get(id, error); if (s) { - DEBUG_LOG(HLE,"sceKernelWaitSema(%i, %i, %i)", id, wantedCount, timeoutPtr); if (s->ns.currentCount >= wantedCount) //TODO fix - { s->ns.currentCount -= wantedCount; - return 0; - } else { s->ns.numWaitThreads++; s->waitingThreads.push_back(__KernelGetCurThread()); - __KernelWaitCurThread(WAITTYPE_SEMA, id, wantedCount, 0, false); - return 0; + // TODO: timeoutPtr? + __KernelWaitCurThread(WAITTYPE_SEMA, id, wantedCount, 0, processCallbacks); + if (processCallbacks) + __KernelCheckCallbacks(); } + + return 0; } else { - ERROR_LOG(HLE, "sceKernelWaitSema : Trying to wait for invalid semaphore %i", id); + ERROR_LOG(HLE, badSemaMessage, id); return error; } +} + +//int sceKernelWaitSema(SceUID semaid, int signal, SceUInt *timeout); +int sceKernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr) +{ + DEBUG_LOG(HLE,"sceKernelWaitSema(%i, %i, %i)", id, wantedCount, timeoutPtr); + + return __KernelWaitSema(id, wantedCount, timeoutPtr, "sceKernelWaitSema: Trying to wait for invalid semaphore %i", false); } //int sceKernelWaitSemaCB(SceUID semaid, int signal, SceUInt *timeout); @@ -263,56 +265,30 @@ int sceKernelWaitSemaCB(SceUID id, int wantedCount, u32 timeoutPtr) { DEBUG_LOG(HLE,"sceKernelWaitSemaCB(%i, %i, %i)", id, wantedCount, timeoutPtr); - u32 error; - Semaphore *s = kernelObjects.Get(id, error); - if (s) - { - DEBUG_LOG(HLE,"CurrentCount: %i, Signal: %i", s->ns.currentCount, wantedCount); - if (s->ns.currentCount >= wantedCount) //TODO fix - { - DEBUG_LOG(HLE,"Subtracting"); - s->ns.currentCount -= wantedCount; - } - else - { - s->ns.numWaitThreads++; - s->waitingThreads.push_back(__KernelGetCurThread()); - // TODO: timeoutPtr? - __KernelWaitCurThread(WAITTYPE_SEMA, id, wantedCount, 0, true); - __KernelCheckCallbacks(); - return 0; - } - DEBUG_LOG(HLE,"After: CurrentCount: %i, Signal: %i", s->ns.currentCount, wantedCount); - return 0; - } - else - { - ERROR_LOG(HLE,"sceKernelWaitSemaCB - Bad semaphore"); - return error; - } + return __KernelWaitSema(id, wantedCount, timeoutPtr, "sceKernelWaitSemaCB: Trying to wait for invalid semaphore %i", true); } // Should be same as WaitSema but without the wait, instead returning SCE_KERNEL_ERROR_SEMA_ZERO int sceKernelPollSema(SceUID id, int wantedCount) { + DEBUG_LOG(HLE,"sceKernelPollSema(%i, %i)", id, wantedCount); + u32 error; Semaphore *s = kernelObjects.Get(id, error); if (s) { - DEBUG_LOG(HLE,"sceKernelPollSema(%i, %i)", id, wantedCount); if (s->ns.currentCount >= wantedCount) //TODO fix - { s->ns.currentCount -= wantedCount; - return 0; - } else { return SCE_KERNEL_ERROR_SEMA_ZERO; } + + return 0; } else { - ERROR_LOG(HLE, "sceKernelPollSema : Trying to poll invalid semaphore %i", id); + ERROR_LOG(HLE, "sceKernelPollSema: Trying to poll invalid semaphore %i", id); return error; } }