Ejemplo n.º 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));
}
Ejemplo n.º 2
0
//essentially : get commandIndex and totalCommands, calculate offset of new command, copy command and update totalCommands
//use LDREX/STREX because this data may also be accessed by the GSP module and we don't want to break stuff
//(mostly, we could overwrite the buffer header with wrong data and make the GSP module reexecute old commands)
Result gspSubmitGxCommand(u32* sharedGspCmdBuf, u32 gxCommand[0x8])
{
	if(!sharedGspCmdBuf || !gxCommand)return -1;

	u32 cmdBufHeader = __ldrex((s32*)sharedGspCmdBuf);

	u8 commandIndex=cmdBufHeader&0xFF;
	u8 totalCommands=(cmdBufHeader>>8)&0xFF;

	if(totalCommands>=15)return -2;

	u8 nextCmd=(commandIndex+totalCommands)%15; //there are 15 command slots
	u32* dst=&sharedGspCmdBuf[8*(1+nextCmd)];
	memcpy(dst, gxCommand, 0x20);

	__dsb();
	totalCommands++;
	cmdBufHeader=((cmdBufHeader)&0xFFFF00FF)|(((u32)totalCommands)<<8);

	while(1)
	{
		if (!__strex((s32*)sharedGspCmdBuf, cmdBufHeader)) break;

		cmdBufHeader = __ldrex((s32*)sharedGspCmdBuf);
		totalCommands=((cmdBufHeader&0xFF00)>>8)+1;
		cmdBufHeader=((cmdBufHeader)&0xFFFF00FF)|((totalCommands<<8)&0xFF00);
	}

	if(totalCommands==1)return GSPGPU_TriggerCmdReqQueue();
	return 0;
}
Ejemplo n.º 3
0
int rt_free_box (void *box_mem, void *box) {
  /* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */
#ifndef __USE_EXCLUSIVE_ACCESS
  int irq_dis;
#endif

  if (box < box_mem || box >= ((P_BM) box_mem)->end) {
    return (1);
  }

#ifndef __USE_EXCLUSIVE_ACCESS
#if defined (__ICCARM__)
  irq_dis = __disable_irq_iar();
#else
  irq_dis = __disable_irq ();
#endif /* __ICCARM__ */
  *((void **)box) = ((P_BM) box_mem)->free;
  ((P_BM) box_mem)->free = box;
  if (!irq_dis) __enable_irq ();
#else
  do {
    *((void **)box) = (void *)__ldrex(&((P_BM) box_mem)->free);
  } while (__strex ((U32)box, &((P_BM) box_mem)->free));
#endif
  return (0);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
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));
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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]++;
			}
		}
	}
}
Ejemplo n.º 8
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);
}
Ejemplo n.º 9
0
static inline int LightEvent_TryReset(LightEvent* event)
{
	do
	{
		if (__ldrex(&event->state))
		{
			__clrex();
			return 0;
		}
	} while (__strex(&event->state, -1));
	return 1;
}
Ejemplo n.º 10
0
void __fastcall sub_1B6F2C(void *a1)
{
  unsigned int *v1; // r3@1
  unsigned int v2; // r2@2

  __dmb();
  v1 = (unsigned int *)((char *)a1 + 8);
  do
    v2 = __ldrex(v1);
  while ( __strex(v2 - 1, v1) );
  __dmb();
  if ( (signed int)v2 <= 0 )
    operator delete(a1);
}
Ejemplo n.º 11
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
}
Ejemplo n.º 12
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);
}
Ejemplo n.º 13
0
Result KernelSetStateHook(u32 type, u32 varg1, u32 varg2, u32 varg3)
{
    Result res = 0;

    switch(type)
    {
        case 0x10000:
        {
            do
            {
                __ldrex((s32 *)&rosalinaState);
            }
            while(__strex((s32 *)&rosalinaState, (s32)(rosalinaState ^ varg1)));

            if(rosalinaState & 2)
                hasStartedRosalinaNetworkFuncsOnce = true;

            if(rosalinaState & 1)
                rosalinaLockAllThreads();
            else if(varg1 & 1)
                rosalinaUnlockAllThreads();

            break;
        }
        case 0x10001:
        {
            KRecursiveLock__Lock(criticalSectionLock);
            KRecursiveLock__Lock(&processLangemuLock);

            u32 i;
            for(i = 0; i < 0x40 && processLangemuAttributes[i].titleId != 0ULL; i++);
            if(i < 0x40)
            {
                processLangemuAttributes[i].titleId = ((u64)varg3 << 32) | (u32)varg2;
                processLangemuAttributes[i].state = (u8)(varg1 >> 24);
                processLangemuAttributes[i].country = (u8)(varg1 >> 16);
                processLangemuAttributes[i].language = (u8)(varg1 >> 8);
                processLangemuAttributes[i].region = (u8)((varg1 >> 4) & 0xf);
                processLangemuAttributes[i].mask = (u8)(varg1 & 0xf);
            }
            else
                res = 0xD8609013;

            KRecursiveLock__Unlock(&processLangemuLock);
            KRecursiveLock__Unlock(criticalSectionLock);
            break;
        }
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
int __fastcall sub_1B85C0(int a1, int a2)
{
  int v2; // r3@1
  int v3; // r4@1
  int v4; // r0@1
  int result; // r0@3
  void *v6; // r3@4
  unsigned int *v7; // r2@5
  unsigned int v8; // r1@6
  char v9; // [sp+4h] [bp-Ch]@4

  v2 = *(_DWORD *)a2;
  v3 = a1;
  v4 = *(_DWORD *)a2 - 12;
  if ( *(_DWORD *)(*(_DWORD *)a2 - 4) < 0 )
  {
    v6 = sub_1B8200(v4, (int)&v9, 0);
    result = v3;
    *(_DWORD *)v3 = v6;
  }
  else
  {
    if ( (_UNKNOWN *)v4 != &unk_200B34 )
    {
      v7 = (unsigned int *)(v2 - 4);
      __dmb();
      do
        v8 = __ldrex(v7);
      while ( __strex(v8 + 1, v7) );
      __dmb();
    }
    result = v3;
    *(_DWORD *)v3 = v2;
  }
  return result;
}
Ejemplo n.º 16
0
int __fastcall sub_110830(int a1, int a2, int a3, int a4)
{
  int v4; // r5@1
  int v5; // r4@1
  int v6; // r6@1
  void *v7; // r7@6
  void *v8; // r0@6
  char *v9; // r8@7
  char v10; // r3@8
  int *v11; // r4@8
  int v12; // r0@11
  int v13; // r0@11
  int v14; // r0@11
  int v15; // r0@11
  int v16; // r0@11
  int v17; // r0@11
  int v18; // r0@11
  int v19; // r0@11
  void *v20; // r0@11
  unsigned int *v22; // r3@15
  signed int v23; // r2@16
  unsigned int *v24; // r3@20
  signed int v25; // r2@21
  const char *v26; // [sp+4h] [bp-94h]@4
  char v27; // [sp+Ch] [bp-8Ch]@11
  int v28; // [sp+10h] [bp-88h]@5
  char v29; // [sp+14h] [bp-84h]@7
  int v30; // [sp+24h] [bp-74h]@5
  char v31; // [sp+28h] [bp-70h]@8
  char v32; // [sp+29h] [bp-6Fh]@8
  char v33; // [sp+2Ah] [bp-6Eh]@8
  char v34; // [sp+2Bh] [bp-6Dh]@8
  char v35; // [sp+2Ch] [bp-6Ch]@8
  char v36; // [sp+2Dh] [bp-6Bh]@8
  char v37; // [sp+2Eh] [bp-6Ah]@8
  char v38; // [sp+2Fh] [bp-69h]@8
  char v39; // [sp+30h] [bp-68h]@8
  char v40; // [sp+31h] [bp-67h]@8
  char v41; // [sp+32h] [bp-66h]@8
  char v42; // [sp+33h] [bp-65h]@8
  char v43; // [sp+34h] [bp-64h]@8
  char v44; // [sp+35h] [bp-63h]@8
  char v45; // [sp+36h] [bp-62h]@8
  char v46; // [sp+37h] [bp-61h]@8
  char v47; // [sp+38h] [bp-60h]@8
  char v48; // [sp+39h] [bp-5Fh]@8
  char v49; // [sp+3Ah] [bp-5Eh]@8
  char v50; // [sp+3Bh] [bp-5Dh]@8
  char v51; // [sp+3Ch] [bp-5Ch]@8
  char v52; // [sp+3Dh] [bp-5Bh]@8
  char v53; // [sp+3Eh] [bp-5Ah]@8
  char v54; // [sp+3Fh] [bp-59h]@8
  char v55; // [sp+40h] [bp-58h]@8
  char v56; // [sp+41h] [bp-57h]@8
  char v57; // [sp+42h] [bp-56h]@8
  char v58; // [sp+43h] [bp-55h]@8
  char v59; // [sp+44h] [bp-54h]@8
  char v60; // [sp+45h] [bp-53h]@8
  char v61; // [sp+46h] [bp-52h]@8
  char v62; // [sp+47h] [bp-51h]@8
  char v63; // [sp+48h] [bp-50h]@8
  char v64; // [sp+49h] [bp-4Fh]@8
  char v65; // [sp+4Ah] [bp-4Eh]@8
  char v66; // [sp+4Bh] [bp-4Dh]@8
  char v67; // [sp+4Ch] [bp-4Ch]@8
  char v68; // [sp+4Dh] [bp-4Bh]@8
  char v69; // [sp+4Eh] [bp-4Ah]@8
  char v70; // [sp+4Fh] [bp-49h]@8
  char v71; // [sp+50h] [bp-48h]@8
  char v72; // [sp+51h] [bp-47h]@8
  char v73; // [sp+52h] [bp-46h]@8
  char v74; // [sp+53h] [bp-45h]@8
  char v75; // [sp+54h] [bp-44h]@8
  char v76; // [sp+55h] [bp-43h]@8
  char v77; // [sp+56h] [bp-42h]@8
  char v78; // [sp+57h] [bp-41h]@8
  char v79; // [sp+58h] [bp-40h]@8
  char v80; // [sp+59h] [bp-3Fh]@8
  char v81; // [sp+5Ah] [bp-3Eh]@8
  char v82; // [sp+5Bh] [bp-3Dh]@8
  char v83; // [sp+5Ch] [bp-3Ch]@8
  char v84; // [sp+5Dh] [bp-3Bh]@8
  char v85; // [sp+5Eh] [bp-3Ah]@8
  char v86; // [sp+5Fh] [bp-39h]@8
  char v87; // [sp+60h] [bp-38h]@8
  char v88; // [sp+61h] [bp-37h]@8
  char v89; // [sp+62h] [bp-36h]@8
  char v90; // [sp+63h] [bp-35h]@8
  char v91; // [sp+64h] [bp-34h]@8
  char v92; // [sp+66h] [bp-32h]@8
  char v93; // [sp+67h] [bp-31h]@8
  char v94; // [sp+68h] [bp-30h]@8
  char v95; // [sp+69h] [bp-2Fh]@8
  char v96; // [sp+6Ah] [bp-2Eh]@8
  char v97; // [sp+6Bh] [bp-2Dh]@8
  char v98; // [sp+6Ch] [bp-2Ch]@11

  v4 = a3;
  v5 = a4;
  v6 = sub_11D268();
  if ( !v6 )
  {
    if ( v4 )
    {
      if ( v4 == 1 )
        v26 = "serializing";
      else
        v26 = 0;
    }
    else
    {
      v26 = "parsing";
    }
    sub_1B8850(&v28, &unk_1D2476, &v30);
    if ( v5 )
    {
      sub_11BBB4(&v30, " '%s'", v5);
      sub_1B7AAC(&v28, &v30);
      v7 = &unk_200B34;
      v8 = (void *)(v30 - 12);
      if ( (_UNKNOWN *)(v30 - 12) == &unk_200B34 )
      {
        v9 = &v29;
      }
      else
      {
        v24 = (unsigned int *)(v30 - 4);
        __dmb();
        do
          v25 = __ldrex(v24);
        while ( __strex(v25 - 1, v24) );
        __dmb();
        v9 = &v29;
        if ( v25 <= 0 )
          operator delete(v8);
      }
    }
    else
    {
      v9 = &v29;
      v7 = &unk_200B34;
    }
    memset(&v30, 0, 0x49u);
    v30 = 16974380;
    v51 = 44;
    v58 = 44;
    v31 = 1;
    v10 = 44;
    v34 = 28;
    v32 = 30;
    v33 = 30;
    v35 = 29;
    v36 = 27;
    v37 = 65;
    v11 = &v30;
    v40 = 74;
    v46 = 74;
    v41 = 93;
    v44 = 93;
    v42 = 101;
    v43 = 75;
    v45 = 79;
    v47 = 70;
    v48 = 111;
    v49 = 49;
    v50 = 48;
    v52 = 48;
    v53 = 42;
    v54 = 36;
    v55 = 50;
    v56 = 46;
    v57 = 102;
    v38 = 94;
    v59 = 34;
    v39 = 94;
    v60 = 32;
    v85 = 3;
    v69 = 48;
    v72 = 42;
    v74 = 46;
    v90 = 30;
    v61 = 40;
    v77 = 40;
    v62 = 61;
    v66 = 61;
    v63 = 96;
    v64 = 55;
    v65 = 62;
    v76 = 62;
    v67 = 52;
    v75 = 52;
    v91 = 52;
    v68 = 56;
    v78 = 56;
    v70 = 121;
    v71 = 39;
    v73 = 54;
    v79 = 112;
    v80 = 23;
    v81 = 8;
    v89 = 8;
    v82 = 16;
    v83 = 6;
    v84 = 59;
    v86 = 9;
    v87 = 21;
    v88 = 5;
    v92 = 4;
    v93 = 26;
    v94 = 10;
    v95 = 94;
    v97 = 17;
    v96 = 18;
    while ( 1 )
    {
      *((_BYTE *)v11 + 1) ^= v10 + (_BYTE)v11 - (unsigned int)&v30;
      v11 = (int *)((char *)v11 + 1);
      if ( (char *)v11 == &v97 )
        break;
      v10 = v30;
    }
    v98 = 0;
    sub_11AC24(v9, 2, (char *)&v30 + 1, 532);
    v12 = sub_11ABD0(v9, "String field");
    v13 = sub_11ABC0(v12, &v28);
    v14 = sub_11ABD0(v13, " contains invalid ");
    v15 = sub_11ABD0(v14, "UTF-8 data when ");
    v16 = sub_11ABD0(v15, v26);
    v17 = sub_11ABD0(v16, " a protocol ");
    v18 = sub_11ABD0(v17, "buffer. Use the 'bytes' type if you intend to send raw ");
    v19 = sub_11ABD0(v18, "bytes. ");
    sub_11B094(&v27, v19);
    sub_11AC40(v9);
    v20 = (void *)(v28 - 12);
    if ( (void *)(v28 - 12) != v7 )
    {
      v22 = (unsigned int *)(v28 - 4);
      __dmb();
      do
        v23 = __ldrex(v22);
      while ( __strex(v23 - 1, v22) );
      __dmb();
      if ( v23 <= 0 )
        operator delete(v20);
    }
  }
  return v6;
}
Ejemplo n.º 17
0
void __fastcall sub_1B7E44(const void **a1, size_t a2, int a3, int a4)
{
  size_t v4; // r6@1
  char *v5; // r4@1
  int v6; // r10@1
  const void **v7; // r9@1
  int v8; // r8@1
  int v9; // r5@1
  int v10; // r7@1
  unsigned int v11; // r5@1
  size_t v12; // r7@1
  int v13; // r0@3
  int v14; // r4@3
  void *v15; // r3@3
  void *v16; // r0@4
  const void *v17; // r1@4
  int v18; // r2@7
  int v19; // r6@7
  int v20; // r10@7
  char *v21; // r0@9
  bool v22; // zf@14
  int v23; // r10@17
  int v24; // r6@17
  char *v25; // r0@17
  char *v26; // r1@17
  void *v27; // ST04_4@22
  unsigned int *v28; // r1@23
  signed int v29; // r2@24
  void *v30; // ST04_4@26

  v4 = a2;
  v5 = (char *)*a1;
  v6 = a4;
  v7 = a1;
  v8 = a3;
  v9 = *((_DWORD *)*a1 - 3);
  v10 = v9 - a2;
  v11 = v9 + a4 - a3;
  v12 = v10 - a3;
  if ( v11 > *((_DWORD *)*a1 - 2) || *((_DWORD *)v5 - 1) > 0 )
  {
    v13 = sub_1B7D04(v11);
    v14 = v13;
    v15 = (void *)(v13 + 12);
    if ( v4 )
    {
      v16 = (void *)(v13 + 12);
      v17 = *v7;
      if ( v4 != 1 )
      {
        v15 = memcpy(v16, v17, v4);
        if ( v12 )
        {
LABEL_7:
          v18 = v4 + 12;
          v19 = v4 + v8;
          v20 = v6 + v18;
          if ( v12 == 1 )
          {
            *(_BYTE *)(v14 + v20) = *((_BYTE *)*v7 + v19);
          }
          else
          {
            v27 = v15;
            memcpy((void *)(v14 + v20), (char *)*v7 + v19, v12);
            v15 = v27;
          }
        }
LABEL_9:
        v21 = (char *)*v7 - 12;
        if ( (_UNKNOWN *)v21 != &unk_200B34 )
        {
          v28 = (unsigned int *)((char *)*v7 - 4);
          __dmb();
          do
            v29 = __ldrex(v28);
          while ( __strex(v29 - 1, v28) );
          __dmb();
          if ( v29 <= 0 )
          {
            v30 = v15;
            operator delete(v21);
            v15 = v30;
          }
        }
        v5 = (char *)v15;
        *v7 = v15;
        goto LABEL_11;
      }
      v15 = (void *)(v14 + 12);
      *(_BYTE *)(v14 + 12) = *(_BYTE *)v17;
    }
    if ( v12 )
      goto LABEL_7;
    goto LABEL_9;
  }
  v22 = a3 == a4;
  if ( a3 != a4 )
    v22 = v12 == 0;
  if ( !v22 )
  {
    v23 = a4 + a2;
    v24 = a2 + a3;
    v25 = &v5[a4] + a2;
    v26 = &v5[a2] + a3;
    if ( v12 == 1 )
    {
      v5[v23] = v5[v24];
      v5 = (char *)*v7;
    }
    else
    {
      memmove(v25, v26, v12);
      v5 = (char *)*v7;
    }
  }
LABEL_11:
  if ( (_UNKNOWN *)(v5 - 12) != &unk_200B34 )
  {
    *((_DWORD *)v5 - 3) = v11;
    *((_DWORD *)v5 - 1) = 0;
    v5[v11] = 0;
  }
}
Ejemplo n.º 18
0
void LightLock_Init(LightLock* lock)
{
	do
		__ldrex(lock);
	while (__strex(lock, 1));
}
Ejemplo n.º 19
0
static inline void LightEvent_SetState(LightEvent* event, int state)
{
	do
		__ldrex(&event->state);
	while (__strex(&event->state, state));
}