Пример #1
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));
}
Пример #2
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));
}
Пример #3
0
void *rt_alloc_box (void *box_mem) {
  /* Allocate a memory block and return start address. */
  void **free;
#ifndef __USE_EXCLUSIVE_ACCESS
  int  irq_dis;


#if defined (__ICCARM__)
  irq_dis = __disable_irq_iar();
#else
  irq_dis = __disable_irq ();
#endif /* __ICCARM__ */
  free = ((P_BM) box_mem)->free;
  if (free) {
    ((P_BM) box_mem)->free = *free;
  }
  if (!irq_dis) __enable_irq ();
#else
  do {
    if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0) {
      __clrex();
      break;
    }
  } while (__strex((U32)*free, &((P_BM) box_mem)->free));
#endif
  return (free);
}
Пример #4
0
static int popInterrupt()
{
	int curEvt;
	bool strexFailed;
	do {
		union {
			struct {
				u8 cur;
				u8 count;
				u8 err;
				u8 unused;
			};
			u32 as_u32;
		} header;

		// Do a load on all header fields as an atomic unit
		header.as_u32 = __ldrex((s32*)gspEventData);

		if (__builtin_expect(header.count == 0, 0)) {
			__clrex();
			return -1;
		}

		curEvt = gspEventData[0xC + header.cur];

		header.cur += 1;
		if (header.cur >= 0x34) header.cur -= 0x34;
		header.count -= 1;
		header.err = 0; // Should this really be set?

		strexFailed = __strex((s32*)gspEventData, header.as_u32);
	} while (__builtin_expect(strexFailed, 0));

	return curEvt;
}
Пример #5
0
static inline int LightEvent_TryReset(LightEvent* event)
{
	do
	{
		if (__ldrex(&event->state))
		{
			__clrex();
			return 0;
		}
	} while (__strex(&event->state, -1));
	return 1;
}
Пример #6
0
int LightLock_TryLock(LightLock* lock)
{
	s32 val;
	do
	{
		val = __ldrex(lock);
		if (val < 0)
		{
			__clrex();
			return 1; // Failure
		}
	} while (__strex(lock, -val));
	return 0; // Success
}
Пример #7
0
/*----------------------------------------------------------------------------*/
bool spinTryLock(spinlock_t *lock)
{
  if (__ldrexb(lock) == SPIN_UNLOCKED) /* Check current state */
  {
    if (!__strexb(SPIN_LOCKED, lock))
    {
      __dmb();
      return true;
    }
    else
      return false;
  }

  __clrex();
  return false; /* Lock is not free */
}
Пример #8
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;
}