Exemplo n.º 1
0
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;
	}
}
Exemplo n.º 2
0
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);
	}
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
	}
}
Exemplo n.º 5
0
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;
	}
}