Example #1
0
void LightEvent_Pulse(LightEvent* event)
{
	if (event->state == -2)
		svcArbitrateAddress(arbiter, (u32)event, ARBITRATION_SIGNAL, -1, 0);
	else if (event->state == -1)
		svcArbitrateAddress(arbiter, (u32)event, ARBITRATION_SIGNAL, 1, 0);
	else
		LightEvent_Clear(event);
}
Example #2
0
void LightEvent_Signal(LightEvent* event)
{
	if (event->state == -1)
	{
		LightEvent_SetState(event, 0);
		svcArbitrateAddress(arbiter, (u32)event, ARBITRATION_SIGNAL, 1, 0);
	} else if (event->state == -2)
	{
		LightLock_Lock(&event->lock);
		LightEvent_SetState(event, 1);
		svcArbitrateAddress(arbiter, (u32)event, ARBITRATION_SIGNAL, -1, 0);
		LightLock_Unlock(&event->lock);
	}
}
Example #3
0
void LightLock_Lock(LightLock* lock)
{
	s32 val;
_begin:
	do
	{
		val = __ldrex(lock);
		if (val < 0)
		{
			// Add ourselves to the list of threads blocked on this lock
			if (__strex(lock, val-1))
				goto _begin; // strex failed, try to lock again

		_wait:
			// Wait for a thread to wake us up
			svcArbitrateAddress(arbiter, (u32)lock, ARBITRATION_WAIT_IF_LESS_THAN, 0, 0);

			// Try to lock again
			do
			{
				val = __ldrex(lock);
				if (val < 0)
				{
					// Lock is still locked - keep waiting
					__clrex();
					goto _wait;
				}
			} while (__strex(lock, -(val-1)));
			return;
		}
	} while (__strex(lock, -val));
}
Example #4
0
void LightSemaphore_Acquire(LightSemaphore* semaphore, s32 count)
{
	s32 old_count;
	s16 num_threads_acq;

	do
	{
		for (;;)
		{
			old_count = __ldrex(&semaphore->current_count);
			if (old_count > 0)
				break;
			__clrex();

			do
				num_threads_acq = (s16)__ldrexh((u16 *)&semaphore->num_threads_acq);
			while (__strexh((u16 *)&semaphore->num_threads_acq, num_threads_acq + 1));

			svcArbitrateAddress(arbiter, (u32)semaphore, ARBITRATION_WAIT_IF_LESS_THAN, count, 0);

			do
				num_threads_acq = (s16)__ldrexh((u16 *)&semaphore->num_threads_acq);
			while (__strexh((u16 *)&semaphore->num_threads_acq, num_threads_acq - 1));
		}
	} while (__strex(&semaphore->current_count, old_count - count));
}
Example #5
0
void gspEventThreadMain(void *arg)
{
	while (gspRunEvents)
	{
		svcWaitSynchronization(gspEvent, U64_MAX);
		svcClearEvent(gspEvent);

		while (true)
		{
			int curEvt = popInterrupt();

			if (curEvt == -1)
				break;

			if (curEvt < GSPGPU_EVENT_MAX)
			{
				if (gspEventCb[curEvt])
				{
					ThreadFunc func = gspEventCb[curEvt];
					if (gspEventCbOneShot[curEvt])
						gspEventCb[curEvt] = NULL;
					func(gspEventCbData[curEvt]);
				}
				LightEvent_Signal(&gspEvents[curEvt]);
				do
					__ldrex(&gspLastEvent);
				while (__strex(&gspLastEvent, curEvt));
				svcArbitrateAddress(__sync_get_arbiter(), (u32)&gspLastEvent, ARBITRATION_SIGNAL, 1, 0);
				gspEventCounts[curEvt]++;
			}
		}
	}
}
Example #6
0
void LightEvent_Wait(LightEvent* event)
{
	for (;;)
	{
		if (event->state == -2)
		{
			svcArbitrateAddress(arbiter, (u32)event, ARBITRATION_WAIT_IF_LESS_THAN, 0, 0);
			return;
		}
		if (event->state != -1)
		{
			if (event->state == 1)
				return;
			if (event->state == 0 && LightEvent_TryReset(event))
				return;
		}
		svcArbitrateAddress(arbiter, (u32)event, ARBITRATION_WAIT_IF_LESS_THAN, 0, 0);
	}
}
Example #7
0
void LightLock_Unlock(LightLock* lock)
{
	s32 val;
	do
		val = -__ldrex(lock);
	while (__strex(lock, val));

	if (val > 1)
		// Wake up exactly one thread
		svcArbitrateAddress(arbiter, (u32)lock, ARBITRATION_SIGNAL, 1, 0);
}
Example #8
0
void LightSemaphore_Release(LightSemaphore* semaphore, s32 count)
{
	s32 old_count, new_count;
	do
	{
		old_count = __ldrex(&semaphore->current_count);
		new_count = old_count + count;
		if (new_count >= semaphore->max_count)
			new_count = semaphore->max_count;
	} while (__strex(&semaphore->current_count, new_count));

	if(old_count <= 0 || semaphore->num_threads_acq > 0)
		svcArbitrateAddress(arbiter, (u32)semaphore, ARBITRATION_SIGNAL, count, 0);
}
Example #9
0
static void poll_thread(void* arg)
{
	while ((u32) svcArbitrateAddress(arbiter, alloc_address, ARBITRATION_WAIT_IF_LESS_THAN_TIMEOUT, 0, 0) == 0xD9001814)
		svcSleepThread(10000);
	__asm__ volatile("cpsid aif \n\t");
	memcpy(flush_buffer, flush_buffer + 0x8000, 0x8000);
	memcpy(flush_buffer, flush_buffer + 0x8000, 0x8000);
	memcpy(flush_buffer, flush_buffer + 0x8000, 0x8000);
	memcpy(flush_buffer, flush_buffer + 0x8000, 0x8000);
	memcpy(flush_buffer, flush_buffer + 0x8000, 0x8000);
	while (lock_thread);
	__asm__ volatile("cpsie aif \n\t");
	svcExitThread();
}
Example #10
0
GSPGPU_Event gspWaitForAnyEvent(void)
{
	s32 x;
	do
	{
		do
		{
			x = __ldrex(&gspLastEvent);
			if (x < 0)
			{
				__clrex();
				break;
			}
		} while (__strex(&gspLastEvent, -1));
		if (x < 0)
			svcArbitrateAddress(__sync_get_arbiter(), (u32)&gspLastEvent, ARBITRATION_WAIT_IF_LESS_THAN, 0, 0);
	} while (x < 0);
	return (GSPGPU_Event)x;
}