int __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *badSemaMessage, bool processCallbacks) { u32 error; Semaphore *s = kernelObjects.Get<Semaphore>(id, error); if (s) { if (wantedCount > s->ns.maxCount || wantedCount <= 0) return SCE_KERNEL_ERROR_ILLEGAL_COUNT; if (s->ns.currentCount >= wantedCount) { s->ns.currentCount -= wantedCount; if (processCallbacks) hleCheckCurrentCallbacks(); } else { s->ns.numWaitThreads++; SceUID threadID = __KernelGetCurThread(); // May be in a tight loop timing out (where we don't remove from waitingThreads yet), don't want to add duplicates. if (std::find(s->waitingThreads.begin(), s->waitingThreads.end(), threadID) == s->waitingThreads.end()) s->waitingThreads.push_back(threadID); __KernelSetSemaTimeout(s, timeoutPtr); __KernelWaitCurThread(WAITTYPE_SEMA, id, wantedCount, timeoutPtr, processCallbacks, "sema waited"); } return 0; } else { ERROR_LOG(HLE, badSemaMessage, id); return error; } }
void __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *badSemaMessage, bool processCallbacks) { u32 error; Semaphore *s = kernelObjects.Get<Semaphore>(id, error); if (s) { if (wantedCount > s->ns.maxCount || wantedCount <= 0) { RETURN(SCE_KERNEL_ERROR_ILLEGAL_COUNT); return; } // We need to set the return value BEFORE processing callbacks / etc. RETURN(0); if (s->ns.currentCount >= wantedCount) s->ns.currentCount -= wantedCount; else { s->ns.numWaitThreads++; s->waitingThreads.push_back(__KernelGetCurThread()); __KernelSetSemaTimeout(s, timeoutPtr); __KernelWaitCurThread(WAITTYPE_SEMA, id, wantedCount, timeoutPtr, processCallbacks); if (processCallbacks) __KernelCheckCallbacks(); } __KernelReSchedule("semaphore waited"); } else { ERROR_LOG(HLE, badSemaMessage, id); RETURN(error); } }
static int __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, bool processCallbacks) { hleEatCycles(900); if (wantedCount <= 0) return SCE_KERNEL_ERROR_ILLEGAL_COUNT; hleEatCycles(500); u32 error; Semaphore *s = kernelObjects.Get<Semaphore>(id, error); if (s) { if (wantedCount > s->ns.maxCount) return SCE_KERNEL_ERROR_ILLEGAL_COUNT; // If there are any callbacks, we always wait, and wake after the callbacks. bool hasCallbacks = processCallbacks && __KernelCurHasReadyCallbacks(); if (s->ns.currentCount >= wantedCount && s->waitingThreads.size() == 0 && !hasCallbacks) s->ns.currentCount -= wantedCount; else { SceUID threadID = __KernelGetCurThread(); // May be in a tight loop timing out (where we don't remove from waitingThreads yet), don't want to add duplicates. if (std::find(s->waitingThreads.begin(), s->waitingThreads.end(), threadID) == s->waitingThreads.end()) s->waitingThreads.push_back(threadID); __KernelSetSemaTimeout(s, timeoutPtr); __KernelWaitCurThread(WAITTYPE_SEMA, id, wantedCount, timeoutPtr, processCallbacks, "sema waited"); } return 0; } else return error; }
int __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *badSemaMessage, bool processCallbacks) { u32 error; Semaphore *s = kernelObjects.Get<Semaphore>(id, error); if (s) { if (wantedCount > s->ns.maxCount || wantedCount <= 0) return SCE_KERNEL_ERROR_ILLEGAL_COUNT; if (s->ns.currentCount >= wantedCount) { s->ns.currentCount -= wantedCount; if (processCallbacks) hleCheckCurrentCallbacks(); } else { s->ns.numWaitThreads++; s->waitingThreads.push_back(__KernelGetCurThread()); __KernelSetSemaTimeout(s, timeoutPtr); __KernelWaitCurThread(WAITTYPE_SEMA, id, wantedCount, timeoutPtr, processCallbacks); } return 0; } else { ERROR_LOG(HLE, badSemaMessage, id); return error; } }
int __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *badSemaMessage, bool processCallbacks) { u32 error; Semaphore *s = kernelObjects.Get<Semaphore>(id, error); if (s) { if (wantedCount > s->ns.maxCount || wantedCount <= 0) return SCE_KERNEL_ERROR_ILLEGAL_COUNT; // If there are any callbacks, we always wait, and wake after the callbacks. bool hasCallbacks = processCallbacks && __KernelCurHasReadyCallbacks(); if (s->ns.currentCount >= wantedCount && s->waitingThreads.size() == 0 && !hasCallbacks) { if (hasCallbacks) { // Might actually end up having to wait, so set the timeout. __KernelSetSemaTimeout(s, timeoutPtr); __KernelWaitCallbacksCurThread(WAITTYPE_SEMA, id, wantedCount, timeoutPtr); } else s->ns.currentCount -= wantedCount; } else { SceUID threadID = __KernelGetCurThread(); // May be in a tight loop timing out (where we don't remove from waitingThreads yet), don't want to add duplicates. if (std::find(s->waitingThreads.begin(), s->waitingThreads.end(), threadID) == s->waitingThreads.end()) s->waitingThreads.push_back(threadID); __KernelSetSemaTimeout(s, timeoutPtr); __KernelWaitCurThread(WAITTYPE_SEMA, id, wantedCount, timeoutPtr, processCallbacks, "sema waited"); } return 0; } else { ERROR_LOG(HLE, badSemaMessage, id); return error; } }