void FMTest1P() { TEST_PRINT("Testing priority change"); if (NKern::NumberOfCpus()==1) return; NFastSemaphore exitSem(0); SFMTest1Info* pI = new SFMTest1Info; TEST_OOM(pI); memclr(pI, sizeof(SFMTest1Info)); TEST_PRINT1("Info@0x%08x", pI); pI->iBlockSize = 256; pI->iBlock = (TUint32*)malloc(pI->iBlockSize*sizeof(TUint32)); TEST_OOM(pI->iBlock); pI->iPriorityThreshold = 9; pI->iBlock[0] = 0; setup_block((TUint32*)pI->iBlock, pI->iBlockSize); pI->iStop = FALSE; TInt cpu; TInt threadCount = 0; TInt pri = 9; char name[16] = "FMTest1P.0"; for_each_cpu(cpu) { name[9] = (char)(threadCount + '0'); if (cpu==1) pI->iThreads[threadCount] = CreateThreadSignalOnExit("FMTest1PInterferer", &FMTest1PInterfererThread, 12, pI, 0, KSmallTimeslice, &exitSem, 1); else pI->iThreads[threadCount] = CreateThreadSignalOnExit(name, &FMTest1Thread, pri, pI, 0, KSmallTimeslice, &exitSem, cpu); pri = 10; threadCount++; } TUint32 b0 = 0xffffffffu; FOREVER { NKern::Sleep(1000); TUint32 b = pI->iBlock[0]; TEST_PRINT1("%d", b); if (b > 1048576) { pI->iStop = TRUE; break; } if (b == b0) { __crash(); } b0 = b; } while (threadCount--) NKern::FSWait(&exitSem); TEST_PRINT1("Total iterations %d", pI->iBlock[0]); free((TAny*)pI->iBlock); free(pI); }
void FSTest2(TAny* a) { SFSTest2Info& info = *(SFSTest2Info*)a; NFastSemaphore exitSem(0); NKern::FSSetOwner(&info.iSem, 0); info.iBlockCount = 0; info.iWaits = 0; info.iSignals = 0; info.iStart = FALSE; info.iStop = FALSE; TInt cpu; TInt threads = 0; TInt this_cpu = NKern::CurrentCpu(); for_each_cpu(cpu) { if (cpu==this_cpu) CreateThreadSignalOnExit("FSTest2Sig0", &FSTest2Signaller0, 11, a, 0, KSmallTimeslice, &exitSem, cpu); else CreateThreadSignalOnExit("FSTest2Sig", &FSTest2Signaller, 12, a, 0, KSmallTimeslice, &exitSem, cpu); ++threads; } info.iStart = TRUE; while(info.iWaits < 1048576) { NKern::FSWait(&info.iSem); ++info.iWaits; } info.iStop = TRUE; while (threads--) NKern::FSWait(&exitSem); TEST_PRINT1("Leftover signals %d", info.iSignals-info.iWaits); TInt r; do { r = WaitWithTimeout(&info.iSem, KMinTimeout); TEST_RESULT1(r==KErrNone || r==KErrTimedOut, "Invalid return code %d", r); if (r == KErrNone) ++info.iWaits; } while(r == KErrNone); TEST_PRINT2("Signalled %d, Waited %d", info.iSignals, info.iWaits); TEST_RESULT(info.iWaits==info.iSignals, "MISMATCH!"); }
void FMTest1() { TEST_PRINT("Testing mutual exclusion"); NFastSemaphore exitSem(0); SFMTest1Info* pI = new SFMTest1Info; TEST_OOM(pI); memclr(pI, sizeof(SFMTest1Info)); pI->iBlockSize = 256; pI->iBlock = (TUint32*)malloc(pI->iBlockSize*sizeof(TUint32)); TEST_OOM(pI->iBlock); pI->iPriorityThreshold = 10; pI->iBlock[0] = 0; setup_block((TUint32*)pI->iBlock, pI->iBlockSize); pI->iStop = FALSE; TInt cpu; TInt threads = 0; for_each_cpu(cpu) { CreateThreadSignalOnExit("FMTest1H", &FMTest1Thread, 11, pI, 0, KSmallTimeslice, &exitSem, cpu); CreateThreadSignalOnExit("FMTest1L0", &FMTest1Thread, 10, pI, 0, KSmallTimeslice, &exitSem, cpu); CreateThreadSignalOnExit("FMTest1L1", &FMTest1Thread, 10, pI, 0, KSmallTimeslice, &exitSem, cpu); threads += 3; } FOREVER { NKern::Sleep(1000); TEST_PRINT1("%d", pI->iBlock[0]); if (pI->iBlock[0] > 65536) { pI->iStop = TRUE; break; } } while (threads--) NKern::FSWait(&exitSem); TEST_PRINT1("Total iterations %d", pI->iBlock[0]); free((TAny*)pI->iBlock); free(pI); }
void TiedEventTest(TBool aTied, TInt aThreads, TTiedMode aMode) { TEST_PRINT3("TiedEventTest aTied=%d aThreads=%d aMode=%d", aTied, aThreads, aMode); // Set up shared parameters memclr((void*)&Flags,sizeof(Flags)); Done = EFalse; FlagsSet = 0; // Create test threads to check data NFastSemaphore exitSem(0); NFastSemaphore doneSem(0); DoneSem = &doneSem; char name[5]={0x54, 0x45, 0x54, 0x31, 0}; TInt i; NSchedulable* tieTo = NULL; NThread* t[16]; NThreadGroup* group = NULL; if (aThreads == 1) { t[0] = CreateUnresumedThreadSignalOnExit(name, TiedEventThread, 10, NULL, 0, KSmallTimeslice, &exitSem, KCpuAffinityAny); if (aTied) tieTo = t[0]; } else { group = &TG; if (aTied) tieTo = group; SNThreadGroupCreateInfo ginfo; ginfo.iCpuAffinity = KCpuAffinityAny; TInt r = NKern::GroupCreate(group, ginfo); TEST_RESULT(r==KErrNone, "Failed creating group"); for (i=0; i<aThreads; ++i) { t[i] = CreateUnresumedThreadSignalOnExit(name, TiedEventThread, 10, NULL, 0, KSmallTimeslice, &exitSem, KCpuAffinityAny, group); ++name[3]; } } #ifndef __X86__ // Tie the system timer interrupt to the thread if we're testing interrupts // This means the timer function should always be exclusive with the theads // even though it's not tied itself. if (aMode == EInterrupt && tieTo) HijackSystemTimer(tieTo); #endif // Create the IDFC NSchedulable* tieDFC = aMode == EIDFC ? tieTo : NULL; TDfc idfc(tieDFC, FiddleFlags, NULL); IDfc = &idfc; // Create and start NTimer // If we're testing timers it will be tied itself // If we're testing interrupts it will not be tied itself but will still run // exclusively because the interrupt is tied // If we're testing IDFCs it's just used to repeatedly queue the IDFC and // where the timer itself runs is irrelevant. NSchedulable* tieTimer = aMode == ETimer ? tieTo : NULL; NTimerFn timerfn = aMode == EIDFC ? IDfcQFn : TimerFn; NTimer timer(tieTimer, timerfn, NULL); Timer = &timer; timer.OneShot(10); // Resume threads for (i=0; i<aThreads; ++i) NKern::ThreadResume(t[i]); // Wait for threads to be done for (i=0; i<aThreads; ++i) NKern::FSWait(&doneSem); // Tell timer to stop requeueing itself __e32_atomic_store_rel32(&Done, ETrue); NKern::Sleep(100); #ifndef __X86__ // Restart the normal system timer if we're testing interrupts // as otherwise it will get unbound when the thing it's tied to // dies. if (aMode == EInterrupt && tieTo) HijackSystemTimer(NULL); #endif // Clean up threads/group for (i=0; i<aThreads; ++i) { NKern::ThreadRequestSignal(t[i]); NKern::FSWait(&exitSem); } if (group) NKern::GroupDestroy(group); // Check that the flag was ok TEST_PRINT1("Flag was set %d times", FlagsSet); if (aTied) TEST_RESULT(FlagsSet == 0, "Flag was set, shouldn't be"); else TEST_RESULT(FlagsSet > 0, "Flag wasn't set, test broken?"); }