예제 #1
0
void FMTest1PInterfererThread(TAny* a)
	{
	SFMTest1Info& info = *(SFMTest1Info*)a;
	NThread* pC = NKern::CurrentThread();
	TEST_PRINT1("Thread %T start", pC);
	TUint32 seed[2] = {(TUint32)pC, 0};
	NThread* t0 = info.iThreads[0];
	TInt n = 0;
	while (!__e32_atomic_load_acq32(&info.iStop))
		{
		while (!__e32_atomic_load_acq32(&info.iStop) && t0->iPriority != 11)
			__chill();
		TUint32 x = random(seed) & 2047;
		while(x)
			{
			__e32_atomic_add_ord32(&x, TUint32(-1));
			}
		if (__e32_atomic_load_acq32(&info.iStop))
			break;
		NKern::ThreadSetPriority(t0, 9);
		++n;
		}
	TEST_PRINT2("Thread %T ran %d times", pC, n);
	}
예제 #2
0
TBool NTimer::DoCancelMutating(TUint aFlags)
	{
	CHECK_PRECONDITIONS(MASK_NOT_ISR,"NTimer::Cancel (mutating NTimer)");
	TSubScheduler& ss0 = SubScheduler();
	TBool wait = FALSE;
	TInt cpu = -1;
	TBool result = TRUE;
	TDfc* d = (TDfc*)this;
	NKern::Lock();
	TDfcQue* q = iDfcQ;
	NThreadBase* t = q->iThread;
	t->AcqSLock();
	TheTimerQ.iTimerSpinLock.LockIrq();

	// 0000->0000, XX00->ZZ00, xxYY->zzYY
	TUint state = d->CancelInitialStateChange();
	if (state & 0xFF00)
		{
		// someone else cancelling at the same time - just wait for them to finish
		// they can only be waiting for the cancel IPI
		result = FALSE;
		wait = TRUE;
		goto end;
		}
	if (state == 0)	// timer was not active
		{
		result = FALSE;
		goto end;
		}
	if (state>=ETransferring && state<=EFinal)
		{
		DoCancel0(state);
		// cancel is complete
		goto reset;
		}
	if (state==1)
		{
		// on DFC final queue
		q->Remove((TPriListLink*)this);
		goto reset;
		}
	// must be on IDFC queue - need to send cancel IPI
	__NK_ASSERT_ALWAYS((state>>5)==4);
	cpu = state & 0x1f;
	if (TUint(cpu) == ss0.iCpuNum)
		{
		// it's on this CPU's IDFC queue so just dequeue it and finish
		Deque();
		cpu = -1;
reset:
		d->ResetState();	// release semantics
		}
end:
	if (aFlags & ECancelDestroy)
		iHType = EEventHandlerDummy;
	TheTimerQ.iTimerSpinLock.UnlockIrq();
	t->RelSLock();
	if (cpu>=0)
		{
		TCancelIPI ipi;
		ipi.Send(d, cpu);
		ipi.WaitCompletion();
		wait = TRUE;
		}
	if (wait)
		{
		TUint n = 0x01000000;
		while ((i8816.iHState16>>8) & ss0.iCpuMask)
			{
			__chill();
			if (!--n)
				__crash();
			}
		}
	NKern::Unlock();
	return result;
	}