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); }
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; }