sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // f32test\demandpaging\loader\t_pageldrtst.cpp sl@0: // Demand Paging Loader Stress Tests sl@0: // Demand Paging Loader stress tests attempt to cause as much paging as possible sl@0: // whilst putting the system various types of load. sl@0: // t_pageldrtst.exe is the root of the tests, it in turn will start copies of sl@0: // itself stored in various types of media (t_pageldrtst_rom.exe for example). sl@0: // It also loads DLLs from various media, each DLL containing simple functions sl@0: // that are aligned on page boundaries, so each function call is likely to sl@0: // cause a page fault. sl@0: // Usage: sl@0: // t_pageldrtst and t_pageldrtst_rom sl@0: // Common command lines: sl@0: // t_pageldrtst - run the auto test suite sl@0: // t_pageldrtst lowmem - run the low memory tests sl@0: // t_pageldrtst chunks - run the chunk tests sl@0: // t_pageldrtst chunks+ - run the chunk tests (same as used in autotest) sl@0: // t_pageldrtst echunks - run the really stressful chunk tests sl@0: // t_pageldrtst auto debug - run the autotest but with debug output to the serial port sl@0: // t_pageldrtst d_exc - run the d_exc tests sl@0: // Arguments: sl@0: // single - run the tests in a single thread sl@0: // multiple <numThreads> - run the tests in multiple threads where <numThreads> sl@0: // auto - dummy param to trick the tests into running the auto test suite with extra params sl@0: // fullauto - param to make the tests perform the full automatic stress test sl@0: // interleave - force thread interleaving sl@0: // prio - each thread reschedules in between each function call, causes lots of context changes sl@0: // media - perform media access during the tests, very stressful sl@0: // mmc - only use the mmc media for media access to test file caching sl@0: // min - min cache size in pages sl@0: // max - max cache size in pages sl@0: // chunks - simple chunk stress tests sl@0: // chunks+ - the chunk auto tests sl@0: // echunks - extremem chunks tests sl@0: // nochunkdata - don't check the integrity of the data in the chunks sl@0: // lowmem - low memory tests sl@0: // dll - only load dll's sl@0: // exe - only start exe's (t_pagestress) sl@0: // self - only start copies of self (t_pageldrtst from various media) sl@0: // complete - dll, exe and self. sl@0: // rom - only load from ROM sl@0: // base - only load the base DLL and exe's (from code) sl@0: // mixed - rom and base. sl@0: // all_media - load dlls and exes from all media sl@0: // debug - switch on debugging information sl@0: // silent - no output to the screen or serial port sl@0: // noclean - don't delete copied files on exit sl@0: // d_exc - run the d_exc tests sl@0: // global - load dlls once globally sl@0: // thread - load dlls once per thread sl@0: // func - load dlls in the test function (default and most stressful) sl@0: // forward - patern in which to execute function calls sl@0: // backward - patern in which to execute function calls sl@0: // random - patern in which to execute function calls sl@0: // all - patern in which to execute function calls (forward, backward and random) sl@0: // inst - for debugging a parameter passed to a spawned exe to give it an id. sl@0: // iters <count> - the number of times to loop (a '-' means run forever) sl@0: // reaper - test the reaper. sl@0: // btrace - test the btrace code. sl@0: // defrag - test the ram defrag code. sl@0: // stressfree - set the page cache to stress free size and run tests. sl@0: // t_pageldrtst causes a large ammount of paging by repeatedly calling sl@0: // functions from multiple DLLs which include 64 functions which have sl@0: // been aligned on page boundaries from multiple threads, whilst causing sl@0: // background paging by spawning copies of itself and t_pagestress. sl@0: // The test also endeavours to stress the loader by loading and unloading sl@0: // DLLs from multiple threads from various types of media at the same sl@0: // time as stressing the media, testing chunks, the reaper and changing sl@0: // thread priorities. sl@0: // 002 Load thrashing, test rapid loading and unloading of DLLs from sl@0: // multiple threads (DEF100158) sl@0: // 003 Multiple threads loading DLLs in random pattern sl@0: // 004 Multiple threads loading EXE, SELF and DLLs in random pattern with sl@0: // all media, loaded in thread with prio change sl@0: // 005 Multiple threads loading EXE, SELF and DLLs in random pattern with sl@0: // all media, loaded globally with prio change sl@0: // 006 Multiple threads loading EXE, SELF and DLLs in random pattern with sl@0: // all media, loaded in func with process interleaving sl@0: // 007 Multiple threads loading EXE, SELF and DLLs in random pattern with sl@0: // all media, loaded in func with process interleaving, prio change sl@0: // and media access sl@0: // 008 Low Memory setup test sl@0: // 009 Low Memory, Multiple threads loading EXE, SELF and DLLs in random sl@0: // pattern, loaded in func. sl@0: // 010 Low Memory setup test sl@0: // 011 Low Memory, Multiple threads loading EXE, SELF and DLLs in random sl@0: // pattern, loaded in func with process interleaving, sl@0: // prio change and media access sl@0: // 012 Close test driver sl@0: // 013 Chunk tests, Multiple threads loading EXE, SELF and DLLs in random sl@0: // pattern with ROM / ROFS media, loaded in func with prio change sl@0: // 014 Reaper tests with Multiple threads loading EXE, SELF and DLLs in random sl@0: // pattern with all media sl@0: // 015 Reaper tests with Multiple threads loading EXE, SELF and DLLs in random sl@0: // pattern with all media, prio change and process interleaving sl@0: // 016 d_exc check test sl@0: // sl@0: // sl@0: sl@0: //! @SYMTestCaseID KBASE-T_PAGELDRTST-0326 sl@0: //! @SYMTestType UT sl@0: //! @SYMPREQ PREQ1110 sl@0: //! @SYMTestCaseDesc Demand Paging Loader Stress Tests sl@0: //! @SYMTestActions 001 Demand Paging loader stress tests... sl@0: //! @SYMTestExpectedResults All tests should pass. sl@0: //! @SYMTestPriority High sl@0: //! @SYMTestStatus Implemented sl@0: sl@0: #include <e32test.h> sl@0: #include <e32rom.h> sl@0: #include <e32svr.h> sl@0: #include <u32hal.h> sl@0: #include <f32file.h> sl@0: #include <f32dbg.h> sl@0: #include <e32msgqueue.h> sl@0: #include <e32math.h> sl@0: #include <e32btrace.h> sl@0: #include <d32btrace.h> sl@0: #include <d32locd.h> sl@0: #include <hal.h> sl@0: sl@0: #include "t_hash.h" sl@0: #include "paging_info.h" sl@0: sl@0: #ifndef TEST_AUTOTEST sl@0: #define TEST_RUN_REAPERTEST sl@0: #define TEST_RUN_LOWMEMTEST sl@0: #define TEST_RUN_DEFRAGTEST sl@0: #define TEST_RUN_D_EXCTEST sl@0: #define TEST_RUN_CHUNKTEST sl@0: #define TEST_RUN_AUTOTEST sl@0: RTest test(_L("T_PAGELDRTST")); sl@0: #else sl@0: #ifdef TEST_RUN_REAPERTEST sl@0: RTest test(_L("T_PAGELDRTST_REAPER")); sl@0: #endif sl@0: #ifdef TEST_RUN_LOWMEMTEST sl@0: RTest test(_L("T_PAGELDRTST_LOWMEM")); sl@0: #endif sl@0: #ifdef TEST_RUN_DEFRAGTEST sl@0: RTest test(_L("T_PAGELDRTST_DEFRAG")); sl@0: #endif sl@0: #ifdef TEST_RUN_D_EXCTEST sl@0: RTest test(_L("T_PAGELDRTST_D_EXC")); sl@0: #endif sl@0: #ifdef TEST_RUN_CHUNKTEST sl@0: RTest test(_L("T_PAGELDRTST_CHUNK")); sl@0: #endif sl@0: #ifdef TEST_RUN_AUTOTEST sl@0: RTest test(_L("T_PAGELDRTST_AUTO")); sl@0: #endif sl@0: #endif //TEST_AUTOTEST sl@0: sl@0: const TInt KMessageBufSize = 80; sl@0: typedef TBuf<KMessageBufSize> TMessageBuf; sl@0: sl@0: //#define TEST_SHORT_TEST sl@0: //#define TEST_THRASHING_TEST sl@0: //#define TEST_ADD_FAT_MEDIA sl@0: #define TEST_DONT_RESET_STATS sl@0: #define TEST_MINIMAL_STATS sl@0: //#define TEST_KERN_HEAP sl@0: #define TEST_ADD_FRAGD_MEDIA sl@0: #ifdef TEST_ADD_FRAGD_MEDIA sl@0: #endif sl@0: sl@0: #if defined(_DEBUG) || defined(_DEBUG_RELEASE) sl@0: //#define WANT_FS_CACHE_STATS sl@0: #endif sl@0: sl@0: #ifdef __X86__ sl@0: #define TEST_ON_UNPAGED sl@0: #define TEST_NO_DEXC_IN_AUTO sl@0: #endif sl@0: sl@0: sl@0: #include "t_pagestress.h" sl@0: #include "t_pageldrtstdll.h" sl@0: sl@0: #include "t_ramstress.h" sl@0: sl@0: TBool TestDebug = EFalse; sl@0: TBool TestSilent = EFalse; sl@0: TBool TestExit = EFalse; sl@0: #define TEST_EXE 0x01 sl@0: #define TEST_DLL 0x02 sl@0: #define TEST_SELF 0x04 sl@0: #define TEST_EXE_SELF (TEST_EXE | TEST_SELF) sl@0: #define TEST_EXE_SELF_DLL (TEST_EXE | TEST_SELF | TEST_DLL) sl@0: TInt TestLoading = TEST_EXE_SELF_DLL; sl@0: sl@0: #define TEST_MEDIA_BASE (1 << KTestMediaBase) sl@0: #define TEST_MEDIA_ROM (1 << KTestMediaRom) sl@0: #define TEST_MEDIA_ROFS (1 << KTestMediaRofs) sl@0: #define TEST_MEDIA_EXT (1 << KTestMediaExt) sl@0: #define TEST_MEDIA_FAT (1 << KTestMediaFat) sl@0: #define TEST_MEDIA_MMC (1 << KTestMediaMmc) sl@0: #define TEST_MEDIA_ROM_BASE (TEST_MEDIA_ROM | TEST_MEDIA_BASE) sl@0: #define TEST_MEDIA_ALL (TEST_MEDIA_ROM | TEST_MEDIA_BASE | TEST_MEDIA_ROFS | TEST_MEDIA_EXT | TEST_MEDIA_MMC) sl@0: sl@0: typedef enum sl@0: { sl@0: KTestMediaBase = 0, sl@0: KTestMediaRom, sl@0: KTestMediaExt, sl@0: KTestMediaRofs, sl@0: #ifdef TEST_ADD_FAT_MEDIA sl@0: KTestMediaFat, // this is the last one that is always present. sl@0: #endif sl@0: KTestMediaMmc, sl@0: #ifdef TEST_ADD_FRAGD_MEDIA sl@0: KTestMediaNandFrag, sl@0: KTestMediaMmcFrag, sl@0: #endif sl@0: KTestMediaCOUNT, sl@0: }ETestMediaType; sl@0: #ifdef TEST_ADD_FAT_MEDIA sl@0: #define TEST_MEDIA_COUNT_HACK (KTestMediaFat + 1) sl@0: #else sl@0: #define TEST_MEDIA_COUNT_HACK (KTestMediaRofs + 1) sl@0: #endif sl@0: sl@0: typedef enum sl@0: { sl@0: KTestMediaAccessNone = 0, sl@0: KTestMediaAccessBasic, sl@0: KTestMediaAccessMultipleThreads, sl@0: KTestMediaAccessMultiplePattern, sl@0: KTestMediaAccessMixed, sl@0: KTestMediaAccessCOUNT, sl@0: }ETestMediaAccess; sl@0: sl@0: TInt TestWhichMedia = TEST_MEDIA_ROM_BASE; sl@0: TInt DriveNumber=-1; // Parameter - Which drive? -1 = autodetect. sl@0: TBool TestSingle = EFalse; sl@0: TBool TestMultiple = EFalse; sl@0: TInt TestMaxLoops = 20; sl@0: #define TEST_2MEDIA_THREADS 20 sl@0: #define TEST_ALLMEDIA_THREADS 20 sl@0: TInt TestMultipleThreadCount = TEST_2MEDIA_THREADS; sl@0: TInt TestInstanceId = 0; sl@0: TBool TestWeAreTheTestBase = EFalse; sl@0: TBool TestBootedFromMmc = EFalse; sl@0: TBool TestOnlyFromMmc = EFalse; sl@0: TBool TestD_Exc = EFalse; sl@0: TBool TestNoClean = EFalse; sl@0: TBool TestFullAutoTest = EFalse; sl@0: #define TEST_DLL_GLOBAL 0x01 sl@0: #define TEST_DLL_THREAD 0x02 sl@0: #define TEST_DLL_FUNC 0x04 sl@0: TInt TestLoadDllHow = TEST_DLL_FUNC; sl@0: TBool TestIsAutomated = EFalse; sl@0: sl@0: #define TEST_INTERLEAVE_PRIO EPriorityMore//EPriorityRealTime //23 // KNandThreadPriority - 1 sl@0: TBool TestInterleave = EFalse; sl@0: TFileName TestNameBuffer; sl@0: TBool TestPrioChange = EFalse; sl@0: sl@0: volatile TBool TestStopMedia = EFalse; sl@0: ETestMediaAccess TestMediaAccess = KTestMediaAccessNone; sl@0: #define TEST_NUM_FILES 5 sl@0: sl@0: RSemaphore TestMultiSem; sl@0: RMsgQueue<TMessageBuf> TestMsgQueue; sl@0: sl@0: #define TEST_LM_NUM_FREE 0 sl@0: #define TEST_LM_BLOCKSIZE 1 sl@0: #define TEST_LM_BLOCKS_FREE 4 sl@0: TBool TestLowMem = EFalse; sl@0: TBool TestingLowMem = EFalse; sl@0: RPageStressTestLdd PagestressLdd; sl@0: RRamStressTestLdd RamstressLdd; sl@0: sl@0: TBool TestBtrace = EFalse; sl@0: TBool TestDefrag = EFalse; sl@0: TBool TestChunks = EFalse; sl@0: TBool TestChunksPlus = EFalse; sl@0: TBool TestExtremeChunks = EFalse; sl@0: TBool TestChunkData = ETrue; sl@0: TBool TestingChunks = EFalse; sl@0: volatile TBool TestDefragTestEnd = EFalse; sl@0: TBool TestingDefrag = EFalse; sl@0: volatile TBool TestThreadsExit = EFalse; sl@0: TInt TestPageSize = 4096; sl@0: RChunk TestChunk; sl@0: TInt TestCommitEnd = 0; sl@0: TUint8* TestChunkBase = NULL; sl@0: #define TEST_NUM_PAGES 64 sl@0: #define TEST_NUM_CHUNK_PAGES (TEST_NUM_PAGES * 2) sl@0: TBool TestChunkPageState[TEST_NUM_CHUNK_PAGES]; sl@0: sl@0: TBool TestReaper = EFalse; sl@0: TBool TestingReaper = EFalse; sl@0: TBool TestingReaperCleaningFiles = EFalse; sl@0: #define TEST_REAPER_ITERS 20 sl@0: #define TEST_DOT_PERIOD 30 sl@0: TBool TestStressFree = EFalse; sl@0: TInt TestMinCacheSize = 64 * 4096; sl@0: TInt TestMaxCacheSize = 128 * 4096; sl@0: TBool TestIsDemandPaged = ETrue; sl@0: #define TEST_MAX_ZONE_THREADS 8 sl@0: TUint TestZoneCount = 0; sl@0: TInt TickPeriod = 15625; sl@0: sl@0: #define TEST_NONE 0x0 sl@0: #define TEST_THRASH 0x1 sl@0: #define TEST_FORWARD 0x2 sl@0: #define TEST_BACKWARD 0x4 sl@0: #define TEST_RANDOM 0x8 sl@0: #define TEST_ALL (TEST_RANDOM | TEST_BACKWARD | TEST_FORWARD) sl@0: TUint32 TestWhichTests = TEST_ALL; sl@0: _LIT(KRomPath, "z:\\sys\\bin\\"); sl@0: _LIT(KMmcDefaultPath, "d:\\sys\\bin\\"); sl@0: sl@0: #define EXISTS(__val) ((__val == KErrNone) ? &KFileExists : &KFileMissing) sl@0: _LIT(KSysHash,"?:\\Sys\\Hash\\"); sl@0: _LIT(KTestBlank, ""); sl@0: _LIT(KFileExists, "Exists"); sl@0: _LIT(KFileMissing, "Missing"); sl@0: _LIT(KMultipleTest, "Multiple"); sl@0: _LIT(KSingleTest, "Single "); sl@0: _LIT(KTestExe, "Exe "); sl@0: _LIT(KTestDll, "Dll "); sl@0: _LIT(KTestSelf, "Self "); sl@0: _LIT(KTestBase, "Base "); sl@0: _LIT(KTestRom, "ROM "); sl@0: _LIT(KTestAll, "All "); sl@0: _LIT(KTestGlobal, "Global"); sl@0: _LIT(KTestThread, "Thread"); sl@0: _LIT(KTestFunc, "Func"); sl@0: _LIT(KTestInter, "Interleave "); sl@0: _LIT(KTestPrio, "Prio "); sl@0: _LIT(KTestMedia, "Media "); sl@0: _LIT(KTestLowMem, "LowMem "); sl@0: _LIT(KTestChunking, "Chunks "); sl@0: _LIT(KTestEChunking, "EChunks "); sl@0: _LIT(KTestChunkingPlus, "Chunks+ "); sl@0: _LIT(KTestReaper, "Reaper "); sl@0: _LIT(KTestThrash, "Thrash "); sl@0: _LIT(KTestForward, "Forward "); sl@0: _LIT(KTestBackward, "Backward "); sl@0: _LIT(KTestRandom, "Random "); sl@0: sl@0: typedef struct sl@0: { sl@0: TBool testFullAutoOnly; sl@0: TInt testLoading; sl@0: TInt testWhichMedia; sl@0: TBool testMultiple; sl@0: TInt testMaxLoops; sl@0: TInt testMultipleThreadCount; sl@0: TBool testLoadDllHow; sl@0: TBool testInterleave; sl@0: TBool testPrioChange; sl@0: ETestMediaAccess testMediaAccess; sl@0: TUint32 testWhichTests; sl@0: TBool testLowMem; sl@0: TInt testFreeRam; sl@0: }TTheTests; sl@0: sl@0: typedef struct sl@0: { sl@0: TInt ok; sl@0: TInt fail; sl@0: }TChunkTestPair; sl@0: sl@0: typedef struct sl@0: { sl@0: TChunkTestPair lock; sl@0: TChunkTestPair unlock; sl@0: TChunkTestPair decommit; sl@0: TChunkTestPair commit; sl@0: TChunkTestPair check; sl@0: } sl@0: TChunkTestStats; sl@0: sl@0: TChunkTestStats TestChunkStats[TEST_NUM_CHUNK_PAGES]; sl@0: sl@0: sl@0: TPtrC TestPsExeNames[KTestMediaCOUNT] = { _L("t_pagestress.exe"), sl@0: _L("t_pagestress_rom.exe"), sl@0: _L("t_pagestress_ext.exe"), sl@0: _L("t_pagestress_rofs.exe"), sl@0: #ifdef TEST_ADD_FAT_MEDIA sl@0: _L("t_pagestress_fat.exe"), sl@0: #endif sl@0: _L("t_pagestress_mmc.exe"), sl@0: #ifdef TEST_ADD_FRAGD_MEDIA sl@0: _L("t_pagestress_nfr.exe"), sl@0: _L("t_pagestress_mfr.exe"), sl@0: #endif sl@0: }; sl@0: sl@0: TPtrC TestPlExeNames[KTestMediaCOUNT] = { _L("t_pageldrtst.exe"), sl@0: _L("t_pageldrtst_rom.exe"), sl@0: _L("t_pageldrtst_ext.exe"), sl@0: _L("t_pageldrtst_rofs.exe"), sl@0: #ifdef TEST_ADD_FAT_MEDIA sl@0: _L("t_pageldrtst_fat.exe"), sl@0: #endif sl@0: _L("t_pageldrtst_mmc.exe"), sl@0: #ifdef TEST_ADD_FRAGD_MEDIA sl@0: _L("t_pageldrtst_nfr.exe"), sl@0: _L("t_pageldrtst_mfr.exe"), sl@0: #endif sl@0: }; sl@0: sl@0: _LIT(KDllBaseName, "t_pageldrtst"); sl@0: sl@0: TPtrC TestPlExtNames[KTestMediaCOUNT] = { _L(".dll"), sl@0: _L("_rom.dll"), sl@0: _L("_ext.dll"), sl@0: _L("_rofs.dll"), sl@0: #ifdef TEST_ADD_FAT_MEDIA sl@0: _L("_fat.dll"), sl@0: #endif sl@0: _L("_mmc.dll"), sl@0: #ifdef TEST_ADD_FRAGD_MEDIA sl@0: _L("_nfr.dll"), sl@0: _L("_mfr.dll"), sl@0: #endif sl@0: }; sl@0: sl@0: sl@0: TBool TestDllExesExist[KTestMediaCOUNT] = { EFalse, sl@0: EFalse, sl@0: EFalse, sl@0: EFalse, sl@0: #ifdef TEST_ADD_FAT_MEDIA sl@0: EFalse, sl@0: #endif sl@0: EFalse, sl@0: #ifdef TEST_ADD_FRAGD_MEDIA sl@0: EFalse, sl@0: EFalse, sl@0: #endif sl@0: }; sl@0: #define DBGS_PRINT(__args)\ sl@0: if (!TestSilent) test.Printf __args; sl@0: sl@0: #define DBGD_PRINT(__args)\ sl@0: if (TestDebug) test.Printf __args; sl@0: sl@0: void SendDebugMessage(RMsgQueue<TMessageBuf> *aMsgQueue = NULL, sl@0: TMessageBuf *aBuffer = NULL, sl@0: RSemaphore *aTheSem = NULL) sl@0: { sl@0: for (;;) sl@0: { sl@0: aTheSem->Wait(); sl@0: TInt r = aMsgQueue->Send(*aBuffer); sl@0: aTheSem->Signal(); sl@0: if (r != KErrOverflow) sl@0: return; sl@0: User::After(0); sl@0: } sl@0: } sl@0: sl@0: #define DEBUG_PRINT(__args)\ sl@0: if (!TestSilent) \ sl@0: {\ sl@0: if (aMsgQueue && aBuffer && aTheSem)\ sl@0: {\ sl@0: aBuffer->Zero();\ sl@0: aBuffer->Format __args ;\ sl@0: SendDebugMessage(aMsgQueue, aBuffer, aTheSem);\ sl@0: }\ sl@0: else\ sl@0: {\ sl@0: test.Printf __args ;\ sl@0: }\ sl@0: } sl@0: sl@0: #define RUNTEST(__test, __error)\ sl@0: if (!TestSilent)\ sl@0: test(__test == __error);\ sl@0: else\ sl@0: __test; sl@0: sl@0: #define RUNTEST1(__test)\ sl@0: if (!TestSilent)\ sl@0: test(__test); sl@0: sl@0: sl@0: #define DEBUG_PRINT1(__args)\ sl@0: if (TestDebug)\ sl@0: {\ sl@0: DEBUG_PRINT(__args)\ sl@0: } sl@0: sl@0: #define DOTEST(__operation, __condition)\ sl@0: if (aLowMem) \ sl@0: {\ sl@0: __operation;\ sl@0: while (!__condition)\ sl@0: {\ sl@0: DBGD_PRINT((_L("Releasing some memory on line %d\n"), __LINE__));\ sl@0: if (pTheSem)\ sl@0: pTheSem->Wait();\ sl@0: PagestressLdd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE);\ sl@0: if (pTheSem)\ sl@0: pTheSem->Signal();\ sl@0: __operation;\ sl@0: }\ sl@0: RUNTEST1(__condition);\ sl@0: }\ sl@0: else\ sl@0: {\ sl@0: __operation;\ sl@0: RUNTEST1(__condition);\ sl@0: } sl@0: sl@0: #define DOTEST1(__var, __func, __ok, __fail)\ sl@0: if (aLowMem) \ sl@0: {\ sl@0: __var = __func;\ sl@0: while (__var == __fail)\ sl@0: {\ sl@0: DBGD_PRINT((_L("Releasing some memory on line %d\n"), __LINE__));\ sl@0: if (pTheSem)\ sl@0: pTheSem->Wait();\ sl@0: PagestressLdd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE);\ sl@0: if (pTheSem)\ sl@0: pTheSem->Signal();\ sl@0: __var = __func;\ sl@0: }\ sl@0: if (__var != __ok)\ sl@0: DBGS_PRINT((_L("Failing on line %d with error %d\n"), __LINE__, __var));\ sl@0: RUNTEST1(__var == __ok);\ sl@0: }\ sl@0: else\ sl@0: {\ sl@0: __var = __func;\ sl@0: RUNTEST1(__var == __ok);\ sl@0: } sl@0: sl@0: #define DOLOADALLOC(__numDlls, __pTheLibs, __theSem)\ sl@0: if (TestingLowMem)\ sl@0: {\ sl@0: __pTheLibs = (PageLdrRLibrary *)User::AllocZ(sizeof(PageLdrRLibrary) * __numDlls);\ sl@0: while (__pTheLibs == NULL)\ sl@0: {\ sl@0: DEBUG_PRINT1((_L("Releasing some memory for alloc on line %d\n"), __LINE__));\ sl@0: if (__theSem)\ sl@0: __theSem->Wait();\ sl@0: PagestressLdd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE);\ sl@0: if (__theSem)\ sl@0: __theSem->Signal();\ sl@0: __pTheLibs = (PageLdrRLibrary *)User::AllocZ(sizeof(PageLdrRLibrary) * __numDlls);\ sl@0: }\ sl@0: }\ sl@0: else\ sl@0: {\ sl@0: __pTheLibs = (PageLdrRLibrary *)User::AllocZ(sizeof(PageLdrRLibrary) * __numDlls);\ sl@0: if (__pTheLibs == NULL)\ sl@0: return KErrGeneral;\ sl@0: } sl@0: sl@0: #define TEST_NEXT(__args) \ sl@0: if (!TestSilent)\ sl@0: test.Next __args; sl@0: sl@0: void DoStats(); sl@0: void CheckFilePresence(TBool aDoFileCopy); sl@0: void CleanupFiles(TBool silent); sl@0: typedef TInt (*TCallFunction)(TUint32 funcIndex, TInt param1, TInt param2); sl@0: sl@0: class PageLdrRLibrary : public RLibrary sl@0: { sl@0: public: sl@0: TInt TestLoadLibrary(const TDesC& aFileName, TInt aThreadIndex, RMsgQueue<TMessageBuf> *aMsgQueue, TMessageBuf *aBuffer, RSemaphore *aTheSem); sl@0: TInt CloseLibrary(); sl@0: sl@0: public: sl@0: TBool iInUse; sl@0: TUint32 iFuncCount; sl@0: TLibraryFunction iInitFunc; sl@0: TLibraryFunction iFunctionCountFunc; sl@0: TCallFunction iCallFunctionFunc; sl@0: TLibraryFunction iSetCloseFunc; sl@0: }; sl@0: sl@0: TInt PageLdrRLibrary::CloseLibrary() sl@0: { sl@0: if (iInUse) sl@0: { sl@0: if (iSetCloseFunc) sl@0: (iSetCloseFunc)(); sl@0: Close(); sl@0: iFuncCount = 0; sl@0: iInitFunc = NULL; sl@0: iFunctionCountFunc = NULL; sl@0: iCallFunctionFunc = NULL; sl@0: iSetCloseFunc = NULL; sl@0: iInUse = EFalse; sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: PageLdrRLibrary theGlobalLibs[PAGELDRTST_MAX_DLLS * KTestMediaCOUNT]; sl@0: sl@0: //////////////////////////////////////////////////////////// sl@0: // Template functions encapsulating ControlIo magic sl@0: // sl@0: GLDEF_D template <class C> sl@0: GLDEF_C TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c) sl@0: { sl@0: TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C)); sl@0: sl@0: TInt r = fs.ControlIo(drv, fkn, ptrC); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: // sl@0: // FreeRam sl@0: // sl@0: // Get available free ram. sl@0: // sl@0: sl@0: TInt FreeRam() sl@0: { sl@0: // wait for any async cleanup in the supervisor to finish first... sl@0: UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0); sl@0: sl@0: TMemoryInfoV1Buf meminfo; sl@0: TInt r=UserHal::MemoryInfo(meminfo); sl@0: test (r==KErrNone); sl@0: return meminfo().iFreeRamInBytes; sl@0: } sl@0: sl@0: // sl@0: // FindFsNANDDrive sl@0: // sl@0: // Find the NAND drive sl@0: // sl@0: sl@0: static TInt FindFsNANDDrive(RFs& aFs) sl@0: { sl@0: TDriveList driveList; sl@0: TDriveInfo driveInfo; sl@0: TInt r=aFs.DriveList(driveList); sl@0: if (r == KErrNone) sl@0: { sl@0: for (TInt drvNum= (DriveNumber<0)?0:DriveNumber; drvNum<KMaxDrives; ++drvNum) sl@0: { sl@0: if(!driveList[drvNum]) sl@0: continue; //-- skip unexisting drive sl@0: sl@0: if (aFs.Drive(driveInfo, drvNum) == KErrNone) sl@0: { sl@0: if(driveInfo.iMediaAtt&KMediaAttPageable) sl@0: { sl@0: TBool readOnly = driveInfo.iMediaAtt & KMediaAttWriteProtected; // skip ROFS partitions sl@0: if(!readOnly && (driveInfo.iType != EMediaHardDisk)) sl@0: { sl@0: if ((drvNum==DriveNumber) || (DriveNumber<0)) // only test if running on this drive sl@0: { sl@0: return (drvNum); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: } sl@0: } sl@0: return (-1); sl@0: } sl@0: sl@0: // sl@0: // FindMMCDriveNumber sl@0: // sl@0: // Find the first read write drive. sl@0: // sl@0: sl@0: TInt FindMMCDriveNumber(RFs& aFs) sl@0: { sl@0: TDriveInfo driveInfo; sl@0: for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum) sl@0: { sl@0: TInt r = aFs.Drive(driveInfo, drvNum); sl@0: if (r >= 0) sl@0: { sl@0: if (driveInfo.iType == EMediaHardDisk) sl@0: return (drvNum); sl@0: } sl@0: } sl@0: return -1; sl@0: } sl@0: sl@0: sl@0: // sl@0: // PageLdrRLibrary::TestLoadLibrary sl@0: // sl@0: // Load a library and initialise information about that library sl@0: // sl@0: sl@0: TInt PageLdrRLibrary::TestLoadLibrary(const TDesC& aFileName, sl@0: TInt aThreadIndex, sl@0: RMsgQueue<TMessageBuf> *aMsgQueue = NULL, sl@0: TMessageBuf *aBuffer = NULL, sl@0: RSemaphore *aTheSem = NULL) sl@0: { sl@0: TInt retVal = KErrNone; sl@0: if (TestingLowMem) sl@0: { sl@0: TBool whinged = EFalse; sl@0: TInt initialFreeRam = 0; sl@0: TInt freeRam = 0; sl@0: sl@0: while (1) sl@0: { sl@0: initialFreeRam = FreeRam(); sl@0: retVal = Load(aFileName); sl@0: freeRam = FreeRam(); sl@0: if (retVal == KErrNoMemory) sl@0: { sl@0: if (!whinged && (freeRam > (4 * TestPageSize))) sl@0: { sl@0: whinged = ETrue; sl@0: DEBUG_PRINT1((_L("Load() %d pages %S\n"), (freeRam / TestPageSize), &aFileName)); sl@0: if (TestIsDemandPaged) sl@0: { sl@0: SVMCacheInfo tempPages; sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0); sl@0: sl@0: DEBUG_PRINT1((_L("DPC : min %d max %d curr %d\n"), sl@0: tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize)); sl@0: DEBUG_PRINT1((_L(" : maxFree %d freeRam %d\n"), sl@0: tempPages.iMaxFreeSize, FreeRam())); sl@0: } sl@0: } sl@0: DEBUG_PRINT1((_L("Load() releasing some memory for %S (%d)\n"), &aFileName, retVal)); sl@0: if (aTheSem) sl@0: aTheSem->Wait(); sl@0: PagestressLdd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE); sl@0: if (aTheSem) sl@0: aTheSem->Signal(); sl@0: } sl@0: else sl@0: { sl@0: if (whinged) sl@0: { sl@0: DEBUG_PRINT((_L("Load() Ok %d pages (%d) %S\n"), ((initialFreeRam - freeRam) / TestPageSize), (freeRam / TestPageSize), &aFileName)); sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT1((_L("Loading %S (%d)\n"), &aFileName, aThreadIndex)); sl@0: retVal = Load(aFileName); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DEBUG_PRINT1((_L("Load failed %S (%d)\n"), &aFileName, aThreadIndex)); sl@0: if (TestingReaper ) sl@0: { sl@0: TInt tempIndex = 0; sl@0: TBool whinged = EFalse; sl@0: while ( ( (retVal == KErrNotFound) sl@0: || (retVal == KErrPermissionDenied) sl@0: || (retVal == KErrCorrupt) sl@0: || (retVal == KErrInUse)) sl@0: && ( TestingReaperCleaningFiles sl@0: || (tempIndex < TEST_REAPER_ITERS))) sl@0: { sl@0: User::After(2000000); sl@0: if (!whinged) sl@0: { sl@0: DEBUG_PRINT((_L("Load() retrying load for %S (%d)\n"), &aFileName, retVal)); sl@0: whinged = ETrue; sl@0: } sl@0: retVal = Load(aFileName); sl@0: if (!TestingReaperCleaningFiles) sl@0: { sl@0: tempIndex ++; sl@0: } sl@0: } sl@0: if (retVal != KErrNone) sl@0: { sl@0: DEBUG_PRINT((_L("Load() failing for %S (%d) idx %d\n"), &aFileName, retVal, tempIndex)); sl@0: } sl@0: } sl@0: else if (TestingDefrag) sl@0: { sl@0: TInt tempIndex = 0; sl@0: TBool whinged = EFalse; sl@0: while ((retVal == KErrGeneral) && (tempIndex < 10)) sl@0: { sl@0: User::After(20000); sl@0: if (!whinged) sl@0: { sl@0: DEBUG_PRINT((_L("Load() retrying load for %S (%d)\n"), &aFileName, retVal)); sl@0: whinged = ETrue; sl@0: } sl@0: retVal = Load(aFileName); sl@0: tempIndex ++; sl@0: } sl@0: if (retVal != KErrNone) sl@0: { sl@0: DEBUG_PRINT((_L("Load() failing for %S (%d) idx %d\n"), &aFileName, retVal, tempIndex)); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: DEBUG_PRINT1((_L("Loaded %S (%d)\n"), &aFileName, aThreadIndex)); sl@0: if (retVal == KErrNone) sl@0: { sl@0: iInUse = ETrue; sl@0: iInitFunc = Lookup(PAGELDRTST_FUNC_Init); sl@0: iFunctionCountFunc = Lookup(PAGELDRTST_FUNC_FunctionCount); sl@0: iCallFunctionFunc = (TCallFunction)Lookup(PAGELDRTST_FUNC_CallFunction); sl@0: iSetCloseFunc = Lookup(PAGELDRTST_FUNC_SetClose); sl@0: if ( (iInitFunc != NULL) sl@0: && (iFunctionCountFunc != NULL) sl@0: && (iCallFunctionFunc != NULL) sl@0: && (iSetCloseFunc != NULL)) sl@0: { sl@0: retVal = (iInitFunc)(); sl@0: if (retVal == KErrNone) sl@0: { sl@0: iFuncCount = (iFunctionCountFunc)(); sl@0: if (iFuncCount != 0) sl@0: { sl@0: DEBUG_PRINT1((_L("Loaded ok %S (%d)\n"), &aFileName, aThreadIndex)); sl@0: return KErrNone; sl@0: } sl@0: retVal = KErrGeneral; sl@0: DEBUG_PRINT((_L("!!! bad count %S (%d)\n"), &aFileName, aThreadIndex)); sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT((_L("!!! init failed %S (%d)\n"), &aFileName, aThreadIndex)); sl@0: retVal = KErrGeneral; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT((_L("!!! missing %S (%d)\n"), &aFileName, aThreadIndex)); sl@0: retVal = KErrGeneral; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT((_L("Load() failed %S %d\n"), &aFileName, retVal)); sl@0: #ifdef WANT_FS_CACHE_STATS sl@0: RFs fs; sl@0: if (KErrNone != fs.Connect()) sl@0: { sl@0: DEBUG_PRINT(_L("TestLoadLibrary : Can't connect to the FS\n")); sl@0: } sl@0: else sl@0: { sl@0: TFileCacheStats stats1; sl@0: TInt drvNum = FindMMCDriveNumber(fs); sl@0: controlIo(fs,drvNum, KControlIoFileCacheStats, stats1); sl@0: sl@0: DEBUG_PRINT((_L("FSC: drv %d %c free %d used %d locked %d\n"), sl@0: drvNum, 'a' + drvNum, sl@0: stats1.iFreeCount, sl@0: stats1.iUsedCount, sl@0: stats1.iLockedSegmentCount)); sl@0: DEBUG_PRINT((_L(" : alloc %d lock %d closed %d\n"), sl@0: stats1.iAllocatedSegmentCount, sl@0: stats1.iFileCount, sl@0: stats1.iFilesOnClosedQueue)); sl@0: fs.Close(); sl@0: } sl@0: #endif //WANT_FS_CACHE_STATS sl@0: sl@0: if (TestIsDemandPaged) sl@0: { sl@0: SVMCacheInfo tempPages; sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0); sl@0: sl@0: DEBUG_PRINT((_L("DPC : min %d max %d curr %d\n"), sl@0: tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize)); sl@0: DEBUG_PRINT((_L(" : maxFree %d freeRam %d\n"), sl@0: tempPages.iMaxFreeSize, FreeRam())); sl@0: } sl@0: } sl@0: return retVal; sl@0: } sl@0: sl@0: // sl@0: // GetNumDlls sl@0: // sl@0: // Work out how many Dlls we will play with sl@0: // sl@0: TInt GetNumDlls() sl@0: { sl@0: TInt maxDllIndex; sl@0: sl@0: switch (TestWhichMedia) sl@0: { sl@0: default: sl@0: case TEST_MEDIA_BASE: sl@0: case TEST_MEDIA_ROM: sl@0: maxDllIndex = PAGELDRTST_MAX_DLLS; sl@0: break; sl@0: sl@0: case TEST_MEDIA_ROM_BASE: sl@0: maxDllIndex = PAGELDRTST_MAX_DLLS * 2; sl@0: break; sl@0: sl@0: case TEST_MEDIA_ALL: sl@0: maxDllIndex = PAGELDRTST_MAX_DLLS * KTestMediaCOUNT; sl@0: break; sl@0: } sl@0: return maxDllIndex; sl@0: } sl@0: sl@0: // sl@0: // LoadTheLibs sl@0: // sl@0: // Open DLLs for use in the tests. sl@0: // sl@0: sl@0: TInt LoadTheLibs(PageLdrRLibrary *aTheLibs, sl@0: TInt aLibCount, sl@0: TInt aThreadIndex, sl@0: RMsgQueue<TMessageBuf> *aMsgQueue = NULL, sl@0: TMessageBuf *aBuffer = NULL, sl@0: RSemaphore *aTheSem = NULL) sl@0: { sl@0: TBuf<128> nameBuffer; sl@0: TInt dllIndex = 0; sl@0: TInt realDllIndex = 0; sl@0: TInt dllOffset = -1; sl@0: TInt testWhich; sl@0: RThread thisThread; sl@0: sl@0: memset(aTheLibs, 0, sizeof(*aTheLibs) * aLibCount); sl@0: for (dllIndex = 0; dllIndex < aLibCount; dllIndex ++) sl@0: { sl@0: realDllIndex = (dllIndex + aThreadIndex) % PAGELDRTST_MAX_DLLS; sl@0: // realDllIndex = (dllIndex) % PAGELDRTST_MAX_DLLS; sl@0: if (realDllIndex == 0) sl@0: dllOffset ++; sl@0: sl@0: if ((TestWhichMedia & TEST_MEDIA_ALL) == TEST_MEDIA_ALL) sl@0: testWhich = (dllIndex + dllOffset) % KTestMediaCOUNT; sl@0: else if ((TestWhichMedia & TEST_MEDIA_ALL) == TEST_MEDIA_ROM_BASE) sl@0: testWhich = ((dllIndex + dllOffset) & 1) ? KTestMediaBase : KTestMediaRom; sl@0: else if (TestWhichMedia & TEST_MEDIA_BASE ) sl@0: testWhich = KTestMediaBase; sl@0: else sl@0: testWhich = KTestMediaRom; sl@0: sl@0: if (!TestDllExesExist[testWhich]) sl@0: testWhich = KTestMediaBase; sl@0: sl@0: nameBuffer.Format(_L("%S%d%S"), &KDllBaseName, realDllIndex, &TestPlExtNames[testWhich]); sl@0: sl@0: DEBUG_PRINT1((_L("LoadTheLibs[%02d] - loading %S\n"), aThreadIndex, &nameBuffer)); sl@0: TInt theErr = aTheLibs[dllIndex].TestLoadLibrary(nameBuffer, aThreadIndex, aMsgQueue, aBuffer, aTheSem); sl@0: if (theErr != KErrNone) sl@0: { sl@0: DEBUG_PRINT((_L("LoadTheLibs[%02d] - fail %S %d\n"), aThreadIndex, &nameBuffer, theErr)); sl@0: return KErrGeneral; sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT1((_L("LoadTheLibs[%02d] - loaded %S OK\n"), aThreadIndex, &nameBuffer)); sl@0: } sl@0: if (TestThreadsExit) sl@0: { sl@0: DEBUG_PRINT((_L("LoadTheLibs[%02d] - cancelled\n"), aThreadIndex)); sl@0: return KErrCancel; sl@0: } sl@0: if (TestPrioChange) sl@0: { sl@0: TThreadPriority originalThreadPriority = thisThread.Priority(); sl@0: DEBUG_PRINT1((_L("LoadTheLibs[%02d] before priority change\n"), aThreadIndex)); sl@0: thisThread.SetPriority(EPriorityLess); sl@0: User::AfterHighRes(0); sl@0: thisThread.SetPriority(originalThreadPriority); sl@0: DEBUG_PRINT1((_L("LoadTheLibs[%02d] after priority change\n"), aThreadIndex)); sl@0: } sl@0: } sl@0: DEBUG_PRINT((_L("LoadTheLibs[%02d] done\n"), aThreadIndex)); sl@0: return KErrNone; sl@0: } sl@0: sl@0: // sl@0: // CloseTheLibs sl@0: // sl@0: // Close the DLLs that we have previously opened sl@0: // sl@0: sl@0: void CloseTheLibs (PageLdrRLibrary *aTheLibs, sl@0: TInt aLibCount) sl@0: { sl@0: TInt dllIndex = 0; sl@0: sl@0: for (dllIndex = 0; dllIndex < aLibCount; dllIndex ++) sl@0: { sl@0: aTheLibs[dllIndex].CloseLibrary(); sl@0: } sl@0: memset(aTheLibs, 0, sizeof(*aTheLibs) * aLibCount); sl@0: } sl@0: sl@0: // sl@0: // RunThreadForward sl@0: // sl@0: // Walk through the function pointer array (forwards) calling each function sl@0: // sl@0: sl@0: TInt RunThreadForward(TInt aThreadIndex, sl@0: PageLdrRLibrary *aTheLibs, sl@0: TInt aMaxDllIndex, sl@0: RMsgQueue<TMessageBuf> *aMsgQueue = NULL, sl@0: TMessageBuf *aBuffer = NULL, sl@0: RSemaphore *aTheSem = NULL) sl@0: { sl@0: TInt seed = 1; sl@0: TUint32 index = 0; sl@0: RThread thisThread; sl@0: PageLdrRLibrary *pTheLibs = NULL; sl@0: TInt dllIndex = 0; sl@0: sl@0: if (TestLoadDllHow == TEST_DLL_FUNC) sl@0: { sl@0: DOLOADALLOC(aMaxDllIndex, pTheLibs, aTheSem); sl@0: if (pTheLibs) sl@0: { sl@0: TInt retVal = LoadTheLibs(pTheLibs, aMaxDllIndex, aThreadIndex, aMsgQueue, aBuffer, aTheSem); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DEBUG_PRINT((_L("Forward[%d] - load fail\n"), aThreadIndex)); sl@0: CloseTheLibs (pTheLibs, aMaxDllIndex); sl@0: User::Free(pTheLibs); sl@0: return retVal; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT((_L("Forward[%d] - alloc fail\n"), aThreadIndex)); sl@0: return KErrGeneral; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: pTheLibs = aTheLibs; sl@0: } sl@0: sl@0: for (dllIndex = 0; dllIndex < aMaxDllIndex; dllIndex ++) sl@0: { sl@0: index = 0; sl@0: while (index < pTheLibs[dllIndex].iFuncCount) sl@0: { sl@0: if (TestPrioChange) sl@0: { sl@0: TThreadPriority originalThreadPriority = thisThread.Priority(); sl@0: thisThread.SetPriority(EPriorityLess); sl@0: User::AfterHighRes(0); sl@0: thisThread.SetPriority(originalThreadPriority); sl@0: } sl@0: if (pTheLibs[dllIndex].iCallFunctionFunc) sl@0: seed = pTheLibs[dllIndex].iCallFunctionFunc(index, seed, index); sl@0: else sl@0: DEBUG_PRINT((_L("Forward[%d] : dll %d was NULL\n"), aThreadIndex, dllIndex)); sl@0: index ++; sl@0: if (TestThreadsExit) sl@0: break; sl@0: } sl@0: if (TestThreadsExit) sl@0: break; sl@0: } sl@0: if (TestLoadDllHow == TEST_DLL_FUNC) sl@0: { sl@0: CloseTheLibs(pTheLibs, aMaxDllIndex); sl@0: User::Free(pTheLibs); sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: // sl@0: // RunThreadBackward sl@0: // sl@0: // Walk through the function pointer array (backwards) calling each function sl@0: // sl@0: sl@0: TInt RunThreadBackward(TInt aThreadIndex, sl@0: PageLdrRLibrary *aTheLibs, sl@0: TInt aMaxDllIndex, sl@0: RMsgQueue<TMessageBuf> *aMsgQueue = NULL, sl@0: TMessageBuf *aBuffer = NULL, sl@0: RSemaphore *aTheSem = NULL) sl@0: { sl@0: TInt seed = 1; sl@0: TUint32 index = 0; sl@0: RThread thisThread; sl@0: PageLdrRLibrary *pTheLibs = NULL; sl@0: TInt dllIndex = 0; sl@0: sl@0: if (TestLoadDllHow == TEST_DLL_FUNC) sl@0: { sl@0: DOLOADALLOC(aMaxDllIndex, pTheLibs, aTheSem); sl@0: if (pTheLibs) sl@0: { sl@0: TInt retVal = LoadTheLibs(pTheLibs, aMaxDllIndex, aThreadIndex, aMsgQueue, aBuffer, aTheSem); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DEBUG_PRINT((_L("Backward[%d] - load fail\n"), aThreadIndex)); sl@0: CloseTheLibs (pTheLibs, aMaxDllIndex); sl@0: User::Free(pTheLibs); sl@0: return retVal; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT((_L("Backward[%d] - alloc fail\n"), aThreadIndex)); sl@0: return KErrGeneral; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: pTheLibs = aTheLibs; sl@0: } sl@0: sl@0: for (dllIndex = aMaxDllIndex - 1; dllIndex >= 0; dllIndex --) sl@0: { sl@0: index = pTheLibs[dllIndex].iFuncCount; sl@0: while (index > 0) sl@0: { sl@0: if (TestPrioChange) sl@0: { sl@0: TThreadPriority originalThreadPriority = thisThread.Priority(); sl@0: thisThread.SetPriority(EPriorityLess); sl@0: User::AfterHighRes(0); sl@0: thisThread.SetPriority(originalThreadPriority); sl@0: } sl@0: if (pTheLibs[dllIndex].iCallFunctionFunc) sl@0: seed = pTheLibs[dllIndex].iCallFunctionFunc(index, seed, index); sl@0: else sl@0: DEBUG_PRINT((_L("Backward[%d] : dll %d was NULL\n"), aThreadIndex, dllIndex)); sl@0: index --; sl@0: if (TestThreadsExit) sl@0: break; sl@0: } sl@0: if (TestThreadsExit) sl@0: break; sl@0: } sl@0: if (TestLoadDllHow == TEST_DLL_FUNC) sl@0: { sl@0: CloseTheLibs(pTheLibs, aMaxDllIndex); sl@0: User::Free(pTheLibs); sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: // sl@0: // RunThreadRandom sl@0: // sl@0: // Walk through the function pointer array in a random order a number of times calling each function sl@0: // sl@0: sl@0: TInt RunThreadRandom(TInt aThreadIndex, sl@0: PageLdrRLibrary *aTheLibs, sl@0: TInt aMaxDllIndex, sl@0: RMsgQueue<TMessageBuf> *aMsgQueue = NULL, sl@0: TMessageBuf *aBuffer = NULL, sl@0: RSemaphore *aTheSem = NULL) sl@0: { sl@0: TInt seed = 1; sl@0: TUint randNum; sl@0: RThread thisThread; sl@0: PageLdrRLibrary *pTheLibs = NULL; sl@0: TUint dllIndex = 0; sl@0: sl@0: if (TestLoadDllHow == TEST_DLL_FUNC) sl@0: { sl@0: DOLOADALLOC(aMaxDllIndex, pTheLibs, aTheSem); sl@0: if (pTheLibs) sl@0: { sl@0: TInt retVal = LoadTheLibs(pTheLibs, aMaxDllIndex, aThreadIndex, aMsgQueue, aBuffer, aTheSem); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DEBUG_PRINT((_L("Random[%d] - load fail\n"), aThreadIndex)); sl@0: CloseTheLibs (pTheLibs, aMaxDllIndex); sl@0: User::Free(pTheLibs); sl@0: return retVal; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT((_L("Random[%d] - alloc fail\n"), aThreadIndex)); sl@0: return KErrGeneral; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: pTheLibs = aTheLibs; sl@0: } sl@0: sl@0: sl@0: TUint funcCount = (TUint)pTheLibs[0].iFuncCount; sl@0: TInt iterCount = aMaxDllIndex * funcCount; sl@0: sl@0: // reduce the time for auto tests by reducing the number of cycles. sl@0: if (TestIsAutomated) sl@0: iterCount /= 4; sl@0: sl@0: while (iterCount > 0) sl@0: { sl@0: if (TestPrioChange) sl@0: { sl@0: TThreadPriority originalThreadPriority = thisThread.Priority(); sl@0: thisThread.SetPriority(EPriorityLess); sl@0: User::AfterHighRes(0); sl@0: thisThread.SetPriority(originalThreadPriority); sl@0: } sl@0: sl@0: randNum = (TUint)Math::Random(); sl@0: dllIndex = randNum % (TUint)aMaxDllIndex; sl@0: sl@0: randNum %= funcCount; sl@0: sl@0: if ( (randNum < funcCount) sl@0: && ((TInt)dllIndex < aMaxDllIndex)) sl@0: { sl@0: if (pTheLibs[dllIndex].iCallFunctionFunc) sl@0: { sl@0: seed = pTheLibs[dllIndex].iCallFunctionFunc(randNum, seed, randNum); sl@0: } sl@0: else sl@0: DEBUG_PRINT((_L("Random[%d] : dll %d was NULL\n"), aThreadIndex, dllIndex)); sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT((_L("Random[%d] : %d ERROR dllIndex %u rand %u\n"), aThreadIndex, iterCount, dllIndex, randNum)); sl@0: } sl@0: sl@0: --iterCount; sl@0: if (TestThreadsExit) sl@0: break; sl@0: } sl@0: sl@0: if (TestLoadDllHow == TEST_DLL_FUNC) sl@0: { sl@0: CloseTheLibs(pTheLibs, aMaxDllIndex); sl@0: User::Free(pTheLibs); sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: // sl@0: // ThrashThreadLoad sl@0: // sl@0: // Load and unload the DLLs rapidly to show up a timing window in the kernel. sl@0: // sl@0: sl@0: TInt ThrashThreadLoad (TInt aThreadIndex, sl@0: PageLdrRLibrary *aTheLibs, sl@0: TInt aMaxDllIndex, sl@0: RMsgQueue<TMessageBuf> *aMsgQueue = NULL, sl@0: TMessageBuf *aBuffer = NULL, sl@0: RSemaphore *aTheSem = NULL) sl@0: { sl@0: if (TestLoadDllHow == TEST_DLL_FUNC) sl@0: { sl@0: PageLdrRLibrary *pTheLibs = NULL; sl@0: DOLOADALLOC(aMaxDllIndex, pTheLibs, aTheSem); sl@0: if (pTheLibs) sl@0: { sl@0: TInt retVal = LoadTheLibs(pTheLibs, aMaxDllIndex, aThreadIndex, aMsgQueue, aBuffer, aTheSem); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DEBUG_PRINT((_L("Thrash[%d] - load fail\n"), aThreadIndex)); sl@0: CloseTheLibs (pTheLibs, aMaxDllIndex); sl@0: User::Free(pTheLibs); sl@0: return retVal; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT((_L("Thrash[%d] - alloc fail\n"), aThreadIndex)); sl@0: return KErrGeneral; sl@0: } sl@0: sl@0: CloseTheLibs(pTheLibs, aMaxDllIndex); sl@0: User::Free(pTheLibs); sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: // sl@0: // PerformTestThread sl@0: // sl@0: // This is the function that actually does the work. sl@0: // It is complicated a little because test.Printf can only be called from the first thread that calls it sl@0: // so if we are using multiple threads we need to use a message queue to pass the debug info from the sl@0: // child threads back to the parent for the parent to then call printf. sl@0: // sl@0: // sl@0: sl@0: LOCAL_C TInt PerformTestThread(TInt aThreadIndex, sl@0: RMsgQueue<TMessageBuf> *aMsgQueue = NULL, sl@0: TMessageBuf *aBuffer = NULL, sl@0: RSemaphore *aTheSem = NULL) sl@0: { sl@0: TUint start = User::TickCount(); sl@0: sl@0: TFullName n(RThread().Name()); sl@0: sl@0: DEBUG_PRINT((_L("%S : thread %d Executing %S\n"), &TestNameBuffer, aThreadIndex, &n)); sl@0: sl@0: // now select how we do the test... sl@0: TInt iterIndex; sl@0: sl@0: PageLdrRLibrary *pTheLibs = theGlobalLibs; sl@0: TInt maxDllIndex = GetNumDlls(); sl@0: sl@0: switch (TestLoadDllHow) sl@0: { sl@0: case TEST_DLL_THREAD: sl@0: pTheLibs = NULL; sl@0: DOLOADALLOC(maxDllIndex, pTheLibs, aTheSem); sl@0: if (pTheLibs) sl@0: { sl@0: TInt retVal = LoadTheLibs(pTheLibs, maxDllIndex, aThreadIndex, aMsgQueue, aBuffer, aTheSem); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DEBUG_PRINT((_L("Perform[%d] - load fail\n"), aThreadIndex)); sl@0: CloseTheLibs (pTheLibs, maxDllIndex); sl@0: User::Free(pTheLibs); sl@0: return retVal; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT((_L("Perform[%d] - alloc fail\n"), aThreadIndex)); sl@0: return KErrGeneral; sl@0: } sl@0: break; sl@0: sl@0: case TEST_DLL_GLOBAL: sl@0: pTheLibs = theGlobalLibs; sl@0: break; sl@0: sl@0: case TEST_DLL_FUNC: sl@0: default: sl@0: // do nowt sl@0: break; sl@0: } sl@0: sl@0: TInt retVal = KErrNone; sl@0: if (TEST_ALL == (TestWhichTests & TEST_ALL)) sl@0: { sl@0: #define LOCAL_ORDER_INDEX1 6 sl@0: #define LOCAL_ORDER_INDEX2 3 sl@0: TInt order[LOCAL_ORDER_INDEX1][LOCAL_ORDER_INDEX2] = { {TEST_FORWARD, TEST_BACKWARD,TEST_RANDOM}, sl@0: {TEST_FORWARD, TEST_RANDOM, TEST_BACKWARD}, sl@0: {TEST_BACKWARD,TEST_FORWARD, TEST_RANDOM}, sl@0: {TEST_BACKWARD,TEST_RANDOM, TEST_FORWARD}, sl@0: {TEST_RANDOM, TEST_FORWARD, TEST_BACKWARD}, sl@0: {TEST_RANDOM, TEST_BACKWARD,TEST_FORWARD}}; sl@0: TInt whichOrder = 0; sl@0: sl@0: for (iterIndex = 0; ; ) sl@0: { sl@0: TInt selOrder = ((aThreadIndex + 1) * (iterIndex + 1)) % LOCAL_ORDER_INDEX1; sl@0: for (whichOrder = 0; whichOrder < LOCAL_ORDER_INDEX2; whichOrder ++) sl@0: { sl@0: switch (order[selOrder][whichOrder]) sl@0: { sl@0: case TEST_FORWARD: sl@0: DEBUG_PRINT((_L("%S : %d Iter %d.%d Forward\n"), sl@0: &TestNameBuffer, aThreadIndex, iterIndex, whichOrder)); sl@0: retVal = RunThreadForward(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem); sl@0: break; sl@0: sl@0: case TEST_BACKWARD: sl@0: DEBUG_PRINT((_L("%S : %d Iter %d.%d Backward\n"), sl@0: &TestNameBuffer, aThreadIndex, iterIndex, whichOrder)); sl@0: retVal = RunThreadBackward(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem); sl@0: break; sl@0: sl@0: case TEST_RANDOM: sl@0: DEBUG_PRINT((_L("%S : %d Iter %d.%d Random\n"), sl@0: &TestNameBuffer, aThreadIndex, iterIndex, whichOrder)); sl@0: retVal = RunThreadRandom(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem); sl@0: break; sl@0: sl@0: default: // this is really an error. sl@0: break; sl@0: } sl@0: DEBUG_PRINT((_L("%S : %d Iter %d.%d finished %d\n"), sl@0: &TestNameBuffer, aThreadIndex, iterIndex, whichOrder, retVal)); sl@0: if ((retVal == KErrCancel) && iterIndex > 0) sl@0: retVal = KErrNone; sl@0: if ((retVal != KErrNone) || TestThreadsExit) sl@0: break; sl@0: } sl@0: if ((retVal != KErrNone) || TestThreadsExit) sl@0: break; sl@0: if (++iterIndex >= TestMaxLoops) sl@0: break; sl@0: User::AfterHighRes(TEST_DOT_PERIOD/3*1000000); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if (TestWhichTests & TEST_FORWARD) sl@0: { sl@0: for (iterIndex = 0; ; ) sl@0: { sl@0: DEBUG_PRINT((_L("%S : %d Iter %d Forward\n"), &TestNameBuffer, aThreadIndex, iterIndex)); sl@0: retVal = RunThreadForward(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem); sl@0: DEBUG_PRINT((_L("%S : %d Iter %d finished %d\n"), &TestNameBuffer, aThreadIndex, iterIndex, retVal)); sl@0: if ((retVal == KErrCancel) && iterIndex > 0) sl@0: retVal = KErrNone; sl@0: if ((retVal != KErrNone) || TestThreadsExit) sl@0: break; sl@0: if (++iterIndex >= TestMaxLoops) sl@0: break; sl@0: User::AfterHighRes(TEST_DOT_PERIOD/3*1000000); sl@0: } sl@0: } sl@0: sl@0: if (TestWhichTests & TEST_BACKWARD) sl@0: { sl@0: for (iterIndex = 0; ; ) sl@0: { sl@0: DEBUG_PRINT((_L("%S : %d Iter %d Backward\n"), &TestNameBuffer, aThreadIndex, iterIndex)); sl@0: retVal = RunThreadBackward(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem); sl@0: DEBUG_PRINT((_L("%S : %d Iter %d finished %d\n"), &TestNameBuffer, aThreadIndex, iterIndex, retVal)); sl@0: if ((retVal == KErrCancel) && iterIndex > 0) sl@0: retVal = KErrNone; sl@0: if ((retVal != KErrNone) || TestThreadsExit) sl@0: break; sl@0: if (++iterIndex >= TestMaxLoops) sl@0: break; sl@0: User::AfterHighRes(TEST_DOT_PERIOD/3*1000000); sl@0: } sl@0: } sl@0: sl@0: if (TestWhichTests & TEST_RANDOM) sl@0: { sl@0: for (iterIndex = 0; ; ) sl@0: { sl@0: DEBUG_PRINT((_L("%S : %d Iter %d Random\n"), &TestNameBuffer, aThreadIndex, iterIndex)); sl@0: retVal = RunThreadRandom(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem); sl@0: DEBUG_PRINT((_L("%S : %d Iter %d finished %d\n"), &TestNameBuffer, aThreadIndex, iterIndex, retVal)); sl@0: if ((retVal == KErrCancel) && iterIndex > 0) sl@0: retVal = KErrNone; sl@0: if ((retVal != KErrNone) || TestThreadsExit) sl@0: break; sl@0: if (++iterIndex >= TestMaxLoops) sl@0: break; sl@0: User::AfterHighRes(TEST_DOT_PERIOD/3*1000000); sl@0: } sl@0: } sl@0: sl@0: if (TestWhichTests & TEST_THRASH) sl@0: { sl@0: for (iterIndex = 0; ; ) sl@0: { sl@0: DEBUG_PRINT((_L("%S : %d Iter %d Thrash Load\n"), &TestNameBuffer, aThreadIndex, iterIndex)); sl@0: retVal = ThrashThreadLoad(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem); sl@0: DEBUG_PRINT((_L("%S : %d Iter %d finished %d\n"), &TestNameBuffer, aThreadIndex, iterIndex, retVal)); sl@0: if ((retVal == KErrCancel) && iterIndex > 0) sl@0: retVal = KErrNone; sl@0: if ((retVal != KErrNone) || TestThreadsExit) sl@0: break; sl@0: if (++iterIndex >= TestMaxLoops) sl@0: break; sl@0: User::AfterHighRes(TEST_DOT_PERIOD/3*1000000); sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (TestLoadDllHow == TEST_DLL_THREAD) sl@0: { sl@0: CloseTheLibs(pTheLibs, maxDllIndex); sl@0: User::Free(pTheLibs); sl@0: } sl@0: sl@0: DEBUG_PRINT((_L("%S : thread %d Exit (tick %u)\n"), &TestNameBuffer, aThreadIndex, User::TickCount() - start)); sl@0: return retVal; sl@0: } sl@0: sl@0: sl@0: // sl@0: // MultipleTestThread sl@0: // sl@0: // Thread function, one created for each thread in a multiple thread test. sl@0: // sl@0: sl@0: LOCAL_C TInt MultipleTestThread(TAny* aUseTb) sl@0: { sl@0: TInt ret; sl@0: TMessageBuf localBuffer; sl@0: sl@0: if (TestInterleave) sl@0: { sl@0: RThread thisThread; sl@0: thisThread.SetPriority((TThreadPriority) TEST_INTERLEAVE_PRIO); sl@0: } sl@0: sl@0: ret = PerformTestThread((TInt) aUseTb, &TestMsgQueue, &localBuffer, &TestMultiSem); sl@0: if (!TestingChunks) sl@0: { sl@0: if (ret != KErrNone) sl@0: User::Panic(_L("LOAD"), KErrGeneral); sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: // sl@0: // StartExe sl@0: // sl@0: // Start an executable. sl@0: // sl@0: sl@0: TInt StartExe(RProcess& aTheProcesses, TRequestStatus* aPrStatus, TInt aIndex, TBool aLoadSelf, TBool aLowMem, RSemaphore *pTheSem = NULL) sl@0: { sl@0: TBuf<256> buffer; sl@0: TInt testWhich = KTestMediaRom; sl@0: //y_LIT(KTestDebug, "debug"); sl@0: _LIT(KTestSilent, "silent"); sl@0: sl@0: if ((TestWhichMedia & TEST_MEDIA_ALL) == TEST_MEDIA_ALL) sl@0: testWhich = aIndex % KTestMediaCOUNT; sl@0: else if ((TestWhichMedia & TEST_MEDIA_ALL) == TEST_MEDIA_ROM_BASE) sl@0: testWhich = (aIndex & 1) ? KTestMediaBase : KTestMediaRom; sl@0: else if (TestWhichMedia & TEST_MEDIA_BASE ) sl@0: testWhich = KTestMediaBase; sl@0: else sl@0: testWhich = KTestMediaRom; sl@0: sl@0: if (!TestDllExesExist[testWhich]) sl@0: testWhich = KTestMediaBase; sl@0: sl@0: buffer.Zero(); sl@0: TInt ret; sl@0: if (aLoadSelf) sl@0: { sl@0: buffer.Format(_L("single random dll %S iters %d inst %d"), sl@0: /* TestDebug ? &KTestDebug : */ &KTestSilent, TestMaxLoops, aIndex); sl@0: if (TestExtremeChunks) sl@0: buffer.Append(_L(" echunks")); sl@0: else if (TestChunksPlus) sl@0: buffer.Append(_L(" chunks prio")); sl@0: if (TestChunkData == EFalse) sl@0: buffer.Append(_L(" nochunkdata")); sl@0: DBGS_PRINT((_L("%S : Starting Process %d %S %S\n"), sl@0: &TestNameBuffer, aIndex, &TestPlExeNames[testWhich], &buffer)); sl@0: DOTEST1(ret,aTheProcesses.Create(TestPlExeNames[testWhich],buffer),KErrNone, KErrNoMemory); sl@0: } sl@0: else sl@0: { sl@0: buffer.Format(_L("single random %S iters %d inst %d"), sl@0: /* TestDebug ? &KTestDebug : */ &KTestSilent, TestMaxLoops, aIndex); sl@0: DBGS_PRINT((_L("%S : Starting Process %d %S %S\n"), sl@0: &TestNameBuffer, aIndex, &TestPsExeNames[testWhich], &buffer)); sl@0: DOTEST1(ret,aTheProcesses.Create(TestPsExeNames[testWhich],buffer),KErrNone, KErrNoMemory); sl@0: } sl@0: if (ret == KErrNone) sl@0: { sl@0: if(aPrStatus) sl@0: { sl@0: aTheProcesses.Logon(*aPrStatus); sl@0: RUNTEST1(*aPrStatus == KRequestPending); sl@0: } sl@0: aTheProcesses.Resume(); sl@0: } sl@0: return ret; sl@0: } sl@0: sl@0: // sl@0: // PerformRomAndFileSystemAccessThread sl@0: // sl@0: // Access the rom and dump it out to one of the writeable partitions... sl@0: // really just to make the media server a little busy during the test. sl@0: // sl@0: TInt PerformRomAndFileSystemAccessThread(TInt aThreadId, sl@0: RMsgQueue<TMessageBuf> *aMsgQueue, sl@0: TMessageBuf *aBuffer, sl@0: RSemaphore *aTheSem, sl@0: TBool aLowMem) sl@0: { sl@0: RThread thisThread; sl@0: TUint maxBytes = KMaxTUint; sl@0: TInt startTime = User::TickCount(); sl@0: RSemaphore *pTheSem = aTheSem; sl@0: RFs fs; sl@0: RFile file; sl@0: sl@0: if (KErrNone != fs.Connect()) sl@0: { sl@0: DEBUG_PRINT(_L("PerformRomAndFileSystemAccessThread : Can't connect to the FS\n")); sl@0: return KErrGeneral; sl@0: } sl@0: sl@0: // get info about the ROM... sl@0: TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress(); sl@0: TUint8* start; sl@0: TUint8* end; sl@0: if(romHeader->iPageableRomStart) sl@0: { sl@0: start = (TUint8*)romHeader + romHeader->iPageableRomStart; sl@0: end = start + romHeader->iPageableRomSize; sl@0: } sl@0: else sl@0: { sl@0: start = (TUint8*)romHeader; sl@0: end = start + romHeader->iUncompressedSize; sl@0: } sl@0: if (end <= start) sl@0: return KErrGeneral; sl@0: sl@0: // read all ROM pages in a random order...and write out to file in ROFs sl@0: TInt pageSize = 0; sl@0: UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&pageSize,0); sl@0: sl@0: TUint size = end - start - pageSize; sl@0: if(size > maxBytes) sl@0: size = maxBytes; sl@0: sl@0: TUint32 random = 1 + aThreadId; sl@0: TPtrC8 sourceData; sl@0: TUint8* theAddr; sl@0: HBufC8* checkData; sl@0: sl@0: DOTEST((checkData = HBufC8::New(pageSize + 10)), sl@0: (checkData != NULL)); sl@0: sl@0: if (!checkData) sl@0: { sl@0: DEBUG_PRINT((_L("RomAndFSThread %S : failed to alloc read buffer\n"), &TestNameBuffer)); sl@0: } sl@0: sl@0: TInt drvNum = (TestBootedFromMmc || TestOnlyFromMmc) ? FindMMCDriveNumber(fs) : FindFsNANDDrive(fs); sl@0: TBuf<32> filename; sl@0: sl@0: filename.Format(_L("?:\\Pageldrtst%d.tmp"), aThreadId); sl@0: if (drvNum >= 0) sl@0: { sl@0: DEBUG_PRINT((_L("%S : Filename %S\n"), &TestNameBuffer, &filename)); sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT((_L("RomAndFSThread : error getting drive num\n"))); sl@0: drvNum = 3; //make it 'd' by default. sl@0: } sl@0: filename[0] = 'a' + drvNum; sl@0: sl@0: #ifdef WANT_FS_CACHE_STATS sl@0: TInt allocatedSegmentCount = 0; sl@0: TInt filesOnClosedQueue = 0; sl@0: #endif sl@0: TInt ret; sl@0: while(1) sl@0: { sl@0: for(TInt i = size / (pageSize); i>0; --i) sl@0: { sl@0: DEBUG_PRINT1((_L("%S : Opening the file\n"), &TestNameBuffer)); sl@0: DOTEST((ret = file.Replace(fs, filename, EFileWrite)), sl@0: (KErrNone == ret)); sl@0: sl@0: random = random * 69069 + 1; sl@0: theAddr = (TUint8 *)(start + ((TInt64(random) * TInt64(size - pageSize)) >> 32)); sl@0: sourceData.Set(theAddr,pageSize); sl@0: DEBUG_PRINT1((_L("%S : Writing the file\n"), &TestNameBuffer)); sl@0: ret = file.Write(sourceData); sl@0: if (ret != KErrNone) sl@0: { sl@0: DEBUG_PRINT((_L("%S : Write returned error %d\n"), &TestNameBuffer, ret)); sl@0: } sl@0: DEBUG_PRINT1((_L("%S : Closing the file\n"), &TestNameBuffer)); sl@0: file.Close(); sl@0: sl@0: if (checkData) sl@0: { sl@0: TPtr8 theBuf = checkData->Des(); sl@0: sl@0: #ifdef WANT_FS_CACHE_STATS sl@0: // Page cache sl@0: TFileCacheStats stats1; sl@0: TFileCacheStats stats2; sl@0: ret = controlIo(fs,drvNum, KControlIoFileCacheStats, stats1); sl@0: if ((ret != KErrNone) && (ret != KErrNotSupported)) sl@0: { sl@0: DEBUG_PRINT((_L("%S : KControlIoFileCacheStats 1 failed %d\n"), &TestNameBuffer, ret)); sl@0: } sl@0: sl@0: if (aThreadId & 1) sl@0: { sl@0: // flush closed files queue sl@0: ret = fs.ControlIo(drvNum, KControlIoFlushClosedFiles); sl@0: if (ret != KErrNone) sl@0: { sl@0: DEBUG_PRINT((_L("%S : KControlIoFlushClosedFiles failed %d\n"), &TestNameBuffer, ret)); sl@0: } sl@0: } sl@0: else sl@0: #endif //WANT_FS_CACHE_STATS sl@0: { sl@0: // rename file to make sure it has cleared the cache. sl@0: TBuf<32> newname; sl@0: newname.Format(_L("d:\\Pageldrtst%d.temp"), aThreadId); sl@0: if (drvNum >= 0) sl@0: { sl@0: newname[0] = 'a' + drvNum; sl@0: } sl@0: fs.Rename(filename, newname); sl@0: filename = newname; sl@0: } sl@0: #ifdef WANT_FS_CACHE_STATS sl@0: ret = controlIo(fs,drvNum, KControlIoFileCacheStats, stats2); sl@0: if (ret != KErrNone && ret != KErrNotSupported) sl@0: { sl@0: DEBUG_PRINT((_L("%S : KControlIoFileCacheStats2 failed %d\n"), &TestNameBuffer, ret)); sl@0: } sl@0: sl@0: allocatedSegmentCount = (allocatedSegmentCount > stats1.iAllocatedSegmentCount) ? allocatedSegmentCount : stats1.iAllocatedSegmentCount; sl@0: filesOnClosedQueue = (filesOnClosedQueue > stats1.iFilesOnClosedQueue) ? filesOnClosedQueue : stats1.iFilesOnClosedQueue; sl@0: #endif //WANT_FS_CACHE_STATS sl@0: sl@0: DOTEST((ret = file.Open(fs, filename, EFileRead)), sl@0: (KErrNone == ret)); sl@0: // now read back the page that we wrote and compare with the source. sl@0: ret = file.Read(0, theBuf, pageSize); sl@0: if (ret == KErrNone) sl@0: { sl@0: ret = sourceData.Compare(theBuf); sl@0: if (ret != 0) sl@0: { sl@0: DEBUG_PRINT((_L("%S : read compare error %d\n"), &TestNameBuffer, ret)); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT((_L("%S : failed read compare, error %d\n"), &TestNameBuffer, ret)); sl@0: } sl@0: file.Close(); sl@0: } sl@0: DEBUG_PRINT1((_L("%S : Deleting the file\n"), &TestNameBuffer)); sl@0: ret = fs.Delete(filename); sl@0: if (KErrNone != ret) sl@0: { sl@0: DEBUG_PRINT((_L("%S [%d] Delete %S Failed %d!\n"), &TestNameBuffer, aThreadId, &filename, ret)); sl@0: } sl@0: sl@0: if (TestPrioChange) sl@0: { sl@0: TThreadPriority originalThreadPriority = thisThread.Priority(); sl@0: DEBUG_PRINT1((_L("%S [%d] media thread before priority change, stop = %d\n"), &TestNameBuffer, aThreadId, TestStopMedia)); sl@0: thisThread.SetPriority(EPriorityLess); sl@0: User::AfterHighRes(0); sl@0: thisThread.SetPriority(originalThreadPriority); sl@0: DEBUG_PRINT1((_L("%S [%d] media thread after priority change, stop = %d\n"), &TestNameBuffer, aThreadId, TestStopMedia)); sl@0: } sl@0: if (TestStopMedia) sl@0: break; sl@0: } sl@0: if (TestStopMedia) sl@0: break; sl@0: } sl@0: sl@0: #ifdef WANT_FS_CACHE_STATS sl@0: DEBUG_PRINT((_L("%S : [%d] allocPageCount %d filesClosedQueue %d \n"),&TestNameBuffer, aThreadId,allocatedSegmentCount,filesOnClosedQueue)); sl@0: #endif //WANT_FS_CACHE_STATS sl@0: sl@0: if (checkData) sl@0: { sl@0: delete checkData; sl@0: } sl@0: fs.Close(); sl@0: DEBUG_PRINT1((_L("Done in %d ticks\n"), User::TickCount() - startTime)); sl@0: return KErrNone; sl@0: } sl@0: sl@0: // sl@0: // PerformFileSystemAccessThread sl@0: // sl@0: // Access the rom and dump it out to one of the writeable partitions... sl@0: // really just to make the media server a little busy during the test. sl@0: // sl@0: TInt PerformFileSystemAccessThread(TInt aThreadId, sl@0: RMsgQueue<TMessageBuf> *aMsgQueue, sl@0: TMessageBuf *aBuffer, sl@0: RSemaphore *aTheSem, sl@0: TBool aLowMem) sl@0: { sl@0: RThread thisThread; sl@0: TInt startTime = User::TickCount(); sl@0: RSemaphore *pTheSem = aTheSem; sl@0: RFs fs; sl@0: RFile file; sl@0: if (KErrNone != fs.Connect()) sl@0: { sl@0: DEBUG_PRINT(_L("PerformFileSystemAccessThread : Can't connect to the FS\n")); sl@0: return KErrGeneral; sl@0: } sl@0: sl@0: // read all ROM pages in a random order...and write out to file in ROFs sl@0: TInt pageSize = 0; sl@0: UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&pageSize,0); sl@0: sl@0: HBufC8* checkData; sl@0: HBufC8* sourceData; sl@0: TUint32 random = 1 + aThreadId; sl@0: TInt dataSize = pageSize + (pageSize / 2); sl@0: sl@0: DOTEST((sourceData = HBufC8::New(dataSize)), sl@0: (sourceData != NULL)); sl@0: if (!sourceData) sl@0: { sl@0: DEBUG_PRINT((_L("RomAndFSThread %S : failed to alloc read buffer\n"), &TestNameBuffer)); sl@0: fs.Close(); sl@0: return KErrGeneral; sl@0: } sl@0: sl@0: DOTEST((checkData = HBufC8::New(dataSize)), sl@0: (checkData != NULL)); sl@0: if (!checkData) sl@0: { sl@0: DEBUG_PRINT((_L("RomAndFSThread %S : failed to alloc read buffer\n"), &TestNameBuffer)); sl@0: } sl@0: sl@0: TInt drvNum = (TestBootedFromMmc || TestOnlyFromMmc) ? FindMMCDriveNumber(fs) : FindFsNANDDrive(fs); sl@0: TBuf<32> filename; sl@0: sl@0: if (drvNum < 0) sl@0: { sl@0: drvNum = 3; //make it 'd' by default. sl@0: DEBUG_PRINT((_L("FSAccessThread : error getting drive num\n"))); sl@0: } sl@0: sl@0: #ifdef WANT_FS_CACHE_STATS sl@0: TInt allocatedSegmentCount = 0; sl@0: TInt filesOnClosedQueue = 0; sl@0: #endif sl@0: TInt fileIndex; sl@0: TInt ret; sl@0: sl@0: TPtr8 pBuf = sourceData->Des(); sl@0: sl@0: while (1) sl@0: { sl@0: TUint32 randomStart = random; sl@0: // write the file sl@0: for (fileIndex = 0; fileIndex < TEST_NUM_FILES; fileIndex ++) sl@0: { sl@0: filename.Format(_L("%c:\\pldrtst%d_%d.tmp"), 'a' + drvNum, aThreadId, fileIndex); sl@0: sl@0: DEBUG_PRINT1((_L("%S : Opening the file\n"), &TestNameBuffer)); sl@0: sl@0: DOTEST ((ret = file.Replace(fs, filename, EFileWrite)), sl@0: (KErrNone == ret)); sl@0: sl@0: pBuf.Zero(); sl@0: if (fileIndex & 1) sl@0: { sl@0: TInt fillSize = dataSize / sizeof(TUint32); sl@0: while (fillSize > 0) sl@0: { sl@0: random = random * 69069 + 1; sl@0: pBuf.Append((const TUint8 *) &random, sizeof(random)); sl@0: fillSize --; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: pBuf.Fill('x',dataSize); sl@0: } sl@0: sl@0: sl@0: DEBUG_PRINT1((_L("%S : Writing the file\n"), &TestNameBuffer)); sl@0: ret = file.Write(sourceData->Des()); sl@0: if (ret != KErrNone) sl@0: { sl@0: DEBUG_PRINT((_L("%S : Write returned error %d\n"), &TestNameBuffer, ret)); sl@0: } sl@0: DEBUG_PRINT1((_L("%S : Closing the file\n"), &TestNameBuffer)); sl@0: file.Close(); sl@0: } sl@0: sl@0: random = randomStart; sl@0: // check the file sl@0: for (fileIndex = 0; fileIndex < TEST_NUM_FILES; fileIndex ++) sl@0: { sl@0: filename.Format(_L("%c:\\pldrtst%d_%d.tmp"), 'a' + drvNum, aThreadId, fileIndex); sl@0: sl@0: if (checkData) sl@0: { sl@0: TPtr8 theBuf = checkData->Des(); sl@0: sl@0: #ifdef WANT_FS_CACHE_STATS sl@0: // Page cache sl@0: TFileCacheStats stats1; sl@0: TFileCacheStats stats2; sl@0: ret = controlIo(fs,drvNum, KControlIoFileCacheStats, stats1); sl@0: if ((ret != KErrNone) && (ret != KErrNotSupported)) sl@0: { sl@0: DEBUG_PRINT((_L("%S : KControlIoFileCacheStats 1 failed %d\n"), &TestNameBuffer, ret)); sl@0: } sl@0: sl@0: if (aThreadId & 1) sl@0: { sl@0: // flush closed files queue sl@0: ret = fs.ControlIo(drvNum, KControlIoFlushClosedFiles); sl@0: if (ret != KErrNone) sl@0: { sl@0: DEBUG_PRINT((_L("%S : KControlIoFlushClosedFiles failed %d\n"), &TestNameBuffer, ret)); sl@0: } sl@0: } sl@0: else sl@0: #endif //WANT_FS_CACHE_STATS sl@0: { sl@0: // rename file to make sure it has cleared the cache. sl@0: TBuf<32> newname; sl@0: newname.Format(_L("%c:\\pldrtst%d_%d.temp"), 'a' + drvNum, aThreadId, fileIndex); sl@0: fs.Rename(filename, newname); sl@0: filename = newname; sl@0: } sl@0: #ifdef WANT_FS_CACHE_STATS sl@0: ret = controlIo(fs,drvNum, KControlIoFileCacheStats, stats2); sl@0: if (ret != KErrNone && ret != KErrNotSupported) sl@0: { sl@0: DEBUG_PRINT((_L("%S : KControlIoFileCacheStats2 failed %d\n"), &TestNameBuffer, ret)); sl@0: } sl@0: allocatedSegmentCount = (allocatedSegmentCount > stats1.iAllocatedSegmentCount) ? allocatedSegmentCount : stats1.iAllocatedSegmentCount; sl@0: filesOnClosedQueue = (filesOnClosedQueue > stats1.iFilesOnClosedQueue) ? filesOnClosedQueue : stats1.iFilesOnClosedQueue; sl@0: #endif //WANT_FS_CACHE_STATS sl@0: sl@0: DOTEST((ret = file.Open(fs, filename, EFileRead)), sl@0: (KErrNone == ret)); sl@0: // now read back the page that we wrote and compare with the source. sl@0: ret = file.Read(0, theBuf, dataSize); sl@0: if (ret == KErrNone) sl@0: { sl@0: pBuf.Zero(); sl@0: if (fileIndex & 1) sl@0: { sl@0: TInt fillSize = dataSize / sizeof(TUint32); sl@0: while (fillSize > 0) sl@0: { sl@0: random = random * 69069 + 1; sl@0: pBuf.Append((const TUint8 *) &random, sizeof(random)); sl@0: fillSize --; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: pBuf.Fill('x',dataSize); sl@0: } sl@0: sl@0: ret = sourceData->Des().Compare(theBuf); sl@0: if (ret != 0) sl@0: { sl@0: DEBUG_PRINT((_L("%S :compare error %S %d\n"), &TestNameBuffer, &filename, ret)); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: DEBUG_PRINT((_L("%S : failed read compare, error %d\n"), &TestNameBuffer, ret)); sl@0: } sl@0: file.Close(); sl@0: } sl@0: DEBUG_PRINT1((_L("%S : Deleting the file\n"), &TestNameBuffer)); sl@0: ret = fs.Delete(filename); sl@0: if (KErrNone != ret) sl@0: { sl@0: DEBUG_PRINT((_L("%S [%d] Delete %S Failed %d!\n"), &TestNameBuffer, aThreadId, &filename, ret)); sl@0: } sl@0: if (TestPrioChange) sl@0: { sl@0: TThreadPriority originalThreadPriority = thisThread.Priority(); sl@0: thisThread.SetPriority(EPriorityLess); sl@0: User::AfterHighRes(0); sl@0: thisThread.SetPriority(originalThreadPriority); sl@0: } sl@0: if (TestStopMedia) sl@0: break; sl@0: } sl@0: if (TestStopMedia) sl@0: break; sl@0: } sl@0: #ifdef WANT_FS_CACHE_STATS sl@0: DEBUG_PRINT((_L("%S : [%d] allocPageCount %d filesClosedQueue %d \n"),&TestNameBuffer, aThreadId,allocatedSegmentCount,filesOnClosedQueue)); sl@0: #endif //WANT_FS_CACHE_STATS sl@0: sl@0: if (checkData) sl@0: { sl@0: delete checkData; sl@0: } sl@0: delete sourceData; sl@0: fs.Close(); sl@0: DEBUG_PRINT1((_L("Done in %d ticks\n"), User::TickCount() - startTime)); sl@0: return KErrNone; sl@0: } sl@0: sl@0: // sl@0: // PerformRomAndFileSystemAccess sl@0: // sl@0: // Thread function, kicks off the file system access. sl@0: // sl@0: sl@0: LOCAL_C TInt PerformRomAndFileSystemAccess(TAny* aParam) sl@0: { sl@0: TMessageBuf localBuffer; sl@0: TInt threadId = (TInt) aParam; sl@0: TInt retVal = KErrGeneral; sl@0: sl@0: if (TestInterleave) sl@0: { sl@0: RThread thisThread; sl@0: thisThread.SetPriority((TThreadPriority) TEST_INTERLEAVE_PRIO); sl@0: } sl@0: sl@0: switch (TestMediaAccess) sl@0: { sl@0: default: sl@0: break; sl@0: sl@0: case KTestMediaAccessBasic: sl@0: case KTestMediaAccessMultipleThreads: sl@0: retVal = PerformRomAndFileSystemAccessThread(threadId, &TestMsgQueue, &localBuffer, &TestMultiSem, TestingLowMem); sl@0: break; sl@0: sl@0: case KTestMediaAccessMultiplePattern: sl@0: retVal = PerformFileSystemAccessThread(threadId, &TestMsgQueue, &localBuffer, &TestMultiSem, TestingLowMem); sl@0: break; sl@0: sl@0: case KTestMediaAccessMixed: sl@0: if (threadId < ((TestMultipleThreadCount + 1) / 2)) sl@0: retVal = PerformRomAndFileSystemAccessThread(threadId, &TestMsgQueue, &localBuffer, &TestMultiSem, TestingLowMem); sl@0: else sl@0: retVal = PerformFileSystemAccessThread(threadId, &TestMsgQueue, &localBuffer, &TestMultiSem, TestingLowMem); sl@0: break; sl@0: } sl@0: return retVal; sl@0: } sl@0: sl@0: sl@0: // sl@0: // DisplayTestBanner sl@0: // sl@0: // Output a header showing the test parameters. sl@0: // sl@0: sl@0: void DisplayTestBanner(TBool aMultiple) sl@0: { sl@0: DBGS_PRINT((_L("%S : what = %S%S%S(0x%x), media = %S%S%S(0x%x)\n"), sl@0: aMultiple ? &KMultipleTest : &KSingleTest, sl@0: TestLoading & TEST_EXE ? &KTestExe : &KTestBlank, sl@0: TestLoading & TEST_DLL ? &KTestDll : &KTestBlank, sl@0: TestLoading & TEST_SELF ? &KTestSelf : &KTestBlank, sl@0: TestLoading, sl@0: TestWhichMedia & TEST_MEDIA_BASE ? &KTestBase : &KTestBlank, sl@0: TestWhichMedia & TEST_MEDIA_ROM ? &KTestRom : &KTestBlank, sl@0: (TestWhichMedia & TEST_MEDIA_ALL) == TEST_MEDIA_ALL ? &KTestAll : &KTestBlank, sl@0: TestWhichMedia)); sl@0: DBGS_PRINT((_L(" : maxLoops = %d, threads = %d, loadHow = %S (0x%x)\n"), sl@0: TestMaxLoops, sl@0: TestMultipleThreadCount, sl@0: TestLoadDllHow == TEST_DLL_GLOBAL ? &KTestGlobal : TestLoadDllHow == TEST_DLL_THREAD ? &KTestThread : &KTestFunc, TestLoadDllHow)); sl@0: DBGS_PRINT((_L(" : options = %S%S%S%S%S%S, which = %S%S%S%S (0x%x)\n"), sl@0: TestInterleave ? &KTestInter : &KTestBlank, sl@0: TestPrioChange ? &KTestPrio: &KTestBlank, sl@0: (TestMediaAccess == KTestMediaAccessNone) ? &KTestBlank : &KTestMedia, sl@0: TestingLowMem ? &KTestLowMem : &KTestBlank, sl@0: TestExtremeChunks ? &KTestEChunking : TestChunksPlus ? &KTestChunkingPlus : TestingChunks ? &KTestChunking : &KTestBlank, sl@0: TestingReaper ? &KTestReaper : &KTestBlank, sl@0: TestWhichTests & TEST_THRASH ? &KTestThrash : &KTestBlank, sl@0: TestWhichTests & TEST_FORWARD ? &KTestForward : &KTestBlank, sl@0: TestWhichTests & TEST_BACKWARD ? &KTestBackward : &KTestBlank, sl@0: TestWhichTests & TEST_RANDOM ? &KTestRandom : &KTestBlank, sl@0: TestWhichTests)); sl@0: } sl@0: sl@0: // sl@0: // DoSingleTest sl@0: // sl@0: // Perform the single thread test, spawning a number of threads. sl@0: // sl@0: sl@0: LOCAL_C TInt DoSingleTest(TBool aLowMem = EFalse) sl@0: { sl@0: TUint start = User::TickCount(); sl@0: RSemaphore *pTheSem = NULL; sl@0: TInt ret = KErrNone; sl@0: DisplayTestBanner(EFalse); sl@0: sl@0: if (aLowMem) sl@0: { sl@0: DOTEST1(ret,TestMultiSem.CreateLocal(1),KErrNone, KErrNoMemory); sl@0: pTheSem = &TestMultiSem; sl@0: } sl@0: if (TestLoading & TEST_EXE) sl@0: { sl@0: RProcess theProcess; sl@0: TRequestStatus status; sl@0: sl@0: if (StartExe(theProcess, &status, 0, EFalse, aLowMem, pTheSem) == KErrNone) sl@0: { sl@0: User::WaitForRequest(status); sl@0: if (theProcess.ExitType() == EExitPanic) sl@0: { sl@0: DBGS_PRINT((_L("%S : Process Panic'd...\n"), &TestNameBuffer)); sl@0: } sl@0: theProcess.Close(); sl@0: } sl@0: } sl@0: sl@0: if (TestLoading & TEST_SELF) sl@0: { sl@0: RProcess theProcess; sl@0: TRequestStatus status; sl@0: sl@0: if (StartExe(theProcess, &status, 0, ETrue, aLowMem,pTheSem) == KErrNone) sl@0: { sl@0: User::WaitForRequest(status); sl@0: if (theProcess.ExitType() == EExitPanic) sl@0: { sl@0: DBGS_PRINT((_L("%S : Process Panic'd...\n"), &TestNameBuffer)); sl@0: } sl@0: theProcess.Close(); sl@0: } sl@0: } sl@0: sl@0: if (TestLoading & TEST_DLL) sl@0: { sl@0: TInt maxDlls = GetNumDlls(); sl@0: if (TestLoadDllHow == TEST_DLL_GLOBAL) sl@0: { sl@0: TInt retVal = LoadTheLibs(theGlobalLibs, maxDlls, TestInstanceId, NULL, NULL, pTheSem); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("DoSingleTest - unable to load libs\n") )); sl@0: CloseTheLibs (theGlobalLibs, PAGELDRTST_MAX_DLLS); sl@0: if (aLowMem) sl@0: { sl@0: TestMultiSem.Close(); sl@0: } sl@0: return KErrGeneral; sl@0: } sl@0: } sl@0: sl@0: ret = PerformTestThread((TInt) TestInstanceId, NULL, NULL, pTheSem); sl@0: sl@0: if (TestLoadDllHow == TEST_DLL_GLOBAL) sl@0: { sl@0: CloseTheLibs(theGlobalLibs, maxDlls); sl@0: } sl@0: } sl@0: if (aLowMem) sl@0: { sl@0: TestMultiSem.Close(); sl@0: } sl@0: sl@0: if (!TestSilent) sl@0: { sl@0: TInt end = User::TickCount(); sl@0: TInt time = TUint((TUint64)(end-start)*(TUint64)TickPeriod/(TUint64)1000000); sl@0: DBGS_PRINT((_L("\n%S : Single Test : (%u seconds)\n"), &TestNameBuffer, time)); sl@0: } sl@0: sl@0: return ret; sl@0: } sl@0: sl@0: // sl@0: // FillPage sl@0: // sl@0: // Fill a page with test data sl@0: // sl@0: sl@0: void FillPage(TUint aOffset) sl@0: { sl@0: if (TestChunkData) sl@0: { sl@0: TUint32* ptr = (TUint32 *)((TUint8 *)TestChunkBase+aOffset); sl@0: TUint32* ptrEnd = (TUint32 *)((TUint8 *)ptr + TestPageSize); sl@0: do sl@0: { sl@0: *ptr = 0x55000000 + aOffset; sl@0: ptr ++; sl@0: aOffset += 4; sl@0: } sl@0: while(ptr<ptrEnd); sl@0: } sl@0: } sl@0: sl@0: // sl@0: // CheckPage sl@0: // sl@0: // Check a page matches test data.... sl@0: // sl@0: sl@0: TBool CheckPage(TUint index, TUint aOffset) sl@0: { sl@0: TBool ret = ETrue; sl@0: if (TestChunkData) sl@0: { sl@0: TUint32* ptr = (TUint32 *)((TUint8 *)TestChunkBase+aOffset); sl@0: TUint32* ptrEnd = (TUint32 *)((TUint8 *)ptr + TestPageSize); sl@0: do sl@0: { sl@0: if (*ptr != (0x55000000 + aOffset)) sl@0: break; sl@0: ptr ++; sl@0: aOffset += 4; sl@0: } sl@0: while(ptr<ptrEnd); sl@0: if (ptr==ptrEnd) sl@0: { sl@0: TestChunkStats[index].check.ok ++; sl@0: } sl@0: else sl@0: { sl@0: TestChunkStats[index].check.fail ++; sl@0: ret = EFalse; sl@0: } sl@0: } sl@0: return ret; sl@0: } sl@0: sl@0: // sl@0: // DoSomeChunking sl@0: // sl@0: // Lock and unlock various pages in a chunk... sl@0: // sl@0: TUint TestChunkingIndex = 0; sl@0: TUint TestChunkingIndexFails = 0; sl@0: sl@0: void DoSomeChunking() sl@0: { sl@0: TUint iters = TEST_NUM_CHUNK_PAGES / 4; sl@0: TBool lockit = EFalse; sl@0: TBool decomit = EFalse; sl@0: TUint index; sl@0: TInt ret; sl@0: TInt theOffset; sl@0: sl@0: while (iters) sl@0: { sl@0: TestChunkingIndex = TestChunkingIndex * 69069 + 1; sl@0: index = TUint64((TUint64)TestChunkingIndex*(TUint64)TEST_NUM_CHUNK_PAGES)>>32; sl@0: if (index >= TEST_NUM_CHUNK_PAGES) sl@0: TestChunkingIndexFails ++; sl@0: sl@0: theOffset = index * TestPageSize; sl@0: if (theOffset < TestCommitEnd) sl@0: { sl@0: if (lockit) sl@0: { sl@0: if (decomit) sl@0: { sl@0: ret = TestChunk.Decommit(theOffset,TestPageSize); sl@0: if (KErrNone == ret) sl@0: TestChunkStats[index].decommit.ok ++; sl@0: else sl@0: TestChunkStats[index].decommit.fail ++; sl@0: ret = TestChunk.Commit(theOffset,TestPageSize); sl@0: if (KErrNone == ret) sl@0: { sl@0: TestChunkStats[index].commit.ok ++; sl@0: FillPage(theOffset); sl@0: TestChunkPageState[index] = ETrue; sl@0: } sl@0: else sl@0: { sl@0: TestChunkStats[index].commit.fail ++; sl@0: TestChunkPageState[index] = EFalse; sl@0: } sl@0: ret = KErrNone; sl@0: } sl@0: else sl@0: { sl@0: ret = TestChunk.Lock(theOffset,TestPageSize); sl@0: if (KErrNone == ret) sl@0: { sl@0: TestChunkStats[index].lock.ok ++; sl@0: if (!CheckPage(index, theOffset)) sl@0: FillPage(theOffset); sl@0: TestChunkPageState[index] = ETrue; sl@0: } sl@0: else sl@0: { sl@0: TestChunkStats[index].lock.fail ++; sl@0: TestChunkPageState[index] = EFalse; sl@0: } sl@0: } sl@0: decomit = !decomit; sl@0: } sl@0: else sl@0: { sl@0: if (TestChunkPageState[index]) sl@0: { sl@0: // this one should still be locked so the data should be ok. sl@0: if (KErrNone == TestChunk.Lock(theOffset,TestPageSize)) sl@0: { sl@0: TestChunkStats[index].lock.ok ++; sl@0: CheckPage(index, theOffset); sl@0: } sl@0: else sl@0: TestChunkStats[index].lock.fail ++; sl@0: } sl@0: ret = TestChunk.Unlock(theOffset,TestPageSize); sl@0: if (KErrNone == ret) sl@0: TestChunkStats[index].unlock.ok ++; sl@0: else sl@0: TestChunkStats[index].unlock.fail ++; sl@0: TestChunkPageState[index] = EFalse; sl@0: } sl@0: if (KErrNone != ret) sl@0: { sl@0: // so now we need to commit another page in this pages place. sl@0: ret = TestChunk.Commit(theOffset,TestPageSize); sl@0: if (KErrNone != ret) sl@0: { sl@0: TestChunkStats[index].commit.fail ++; sl@0: //DBGS_PRINT((_L("%S : DoSomeChunking[%03d] index %03d failed to commit a page %d\n"), &TestNameBuffer, iters, index, ret)); sl@0: TestChunkPageState[index] = EFalse; sl@0: } sl@0: else sl@0: { sl@0: TestChunkStats[index].commit.ok ++; sl@0: FillPage(theOffset); sl@0: TestChunkPageState[index] = ETrue; sl@0: } sl@0: } sl@0: lockit = !lockit; sl@0: } sl@0: else sl@0: { sl@0: RDebug::Printf("DoSomeChunking - offset was bad %d / %d", theOffset, TestCommitEnd); sl@0: } sl@0: iters --; sl@0: } sl@0: } sl@0: sl@0: // sl@0: // DoMultipleTest sl@0: // sl@0: // Perform the multiple thread test, spawning a number of threads. sl@0: // It is complicated a little because test.Printf can only be called from the first thread that calls it sl@0: // so if we are using multiple threads we need to use a message queue to pass the debug info from the sl@0: // child threads back to the parent for the parent to then call printf. sl@0: // sl@0: sl@0: TInt DoMultipleTest(TBool aLowMem = EFalse) sl@0: { sl@0: TInt index; sl@0: TUint start = User::TickCount(); sl@0: RThread *pTheThreads = NULL; sl@0: TInt *pThreadInUse = NULL; sl@0: sl@0: RProcess *pTheProcesses = NULL; sl@0: TInt *pProcessInUse = NULL; sl@0: sl@0: RThread *pMedThreads = NULL; sl@0: TInt *pMedInUse = NULL; sl@0: sl@0: TRequestStatus mediaStatus; sl@0: RThread mediaThread; sl@0: TInt ret; sl@0: sl@0: RSemaphore *pTheSem = NULL; sl@0: sl@0: DisplayTestBanner(ETrue); sl@0: sl@0: TestThreadsExit = EFalse; sl@0: sl@0: DOTEST1(ret,TestMultiSem.CreateLocal(1),KErrNone, KErrNoMemory); sl@0: sl@0: pTheSem = &TestMultiSem; sl@0: if (TestLoading & TEST_DLL) sl@0: { sl@0: DOTEST((pTheThreads = (RThread *)User::AllocZ(sizeof(RThread) * TestMultipleThreadCount)), sl@0: (pTheThreads != NULL)) sl@0: DOTEST((pThreadInUse = (TInt *)User::AllocZ(sizeof(TInt) * TestMultipleThreadCount)), sl@0: (pThreadInUse != NULL)); sl@0: RUNTEST1(pTheThreads && pThreadInUse); sl@0: if (!(pTheThreads && pThreadInUse)) sl@0: return KErrGeneral; sl@0: } sl@0: sl@0: if (TestLoading & TEST_EXE_SELF) sl@0: { sl@0: DOTEST((pTheProcesses = (RProcess *)User::AllocZ(sizeof(RProcess) * TestMultipleThreadCount)), sl@0: (pTheProcesses != NULL)); sl@0: DOTEST((pProcessInUse = (TInt *)User::AllocZ(sizeof(TInt) * TestMultipleThreadCount)), sl@0: (pProcessInUse != NULL)); sl@0: RUNTEST1(pTheProcesses && pProcessInUse); sl@0: if (!(pTheProcesses && pProcessInUse)) sl@0: return KErrGeneral; sl@0: } sl@0: sl@0: if (!TestSilent) sl@0: { sl@0: DOTEST1(ret,TestMsgQueue.CreateLocal(TestMultipleThreadCount * 10, EOwnerProcess),KErrNone, KErrNoMemory); sl@0: if (ret != KErrNone) sl@0: return KErrGeneral; sl@0: } sl@0: sl@0: if (TestMediaAccess != KTestMediaAccessNone) sl@0: { sl@0: if (TestMediaAccess != KTestMediaAccessBasic) sl@0: { sl@0: TestStopMedia = EFalse; sl@0: DOTEST((pMedThreads = (RThread *)User::AllocZ(sizeof(RThread) * TestMultipleThreadCount)), sl@0: (pMedThreads != NULL)) sl@0: DOTEST((pMedInUse = (TInt *)User::AllocZ(sizeof(TInt) * TestMultipleThreadCount)), sl@0: (pMedInUse != NULL)); sl@0: RUNTEST1(pMedThreads && pMedInUse); sl@0: if (!(pMedThreads && pMedInUse)) sl@0: return KErrGeneral; sl@0: sl@0: for (index = 0; index < TestMultipleThreadCount; index++) sl@0: { sl@0: DBGS_PRINT((_L("%S : Starting Media Thread %d\n"), &TestNameBuffer, index)); sl@0: DOTEST1(ret,pMedThreads[index].Create(KTestBlank,PerformRomAndFileSystemAccess,KDefaultStackSize,NULL,(TAny*) index),KErrNone, KErrNoMemory); sl@0: if (ret == KErrNone) sl@0: { sl@0: pMedThreads[index].Resume(); sl@0: pMedInUse[index] = 1; sl@0: } sl@0: User::AfterHighRes(0); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: TestStopMedia = EFalse; sl@0: DOTEST1(ret,mediaThread.Create(KTestBlank,PerformRomAndFileSystemAccess,KDefaultStackSize,NULL,(TAny *) 0),KErrNone, KErrNoMemory); sl@0: if (ret == KErrNone) sl@0: { sl@0: mediaThread.Logon(mediaStatus); sl@0: RUNTEST1(mediaStatus == KRequestPending); sl@0: mediaThread.Resume(); sl@0: } sl@0: } sl@0: } sl@0: sl@0: TInt maxDlls = GetNumDlls(); sl@0: if (TestLoadDllHow == TEST_DLL_GLOBAL) sl@0: { sl@0: TInt retVal = LoadTheLibs(theGlobalLibs, maxDlls, 0, NULL, NULL, NULL); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("DoMultipleTest - unable to load libs\n"))); sl@0: CloseTheLibs (theGlobalLibs, maxDlls); sl@0: if (!TestSilent) sl@0: { sl@0: TestMsgQueue.Close(); sl@0: } sl@0: TestMultiSem.Close(); sl@0: return KErrGeneral; sl@0: } sl@0: } sl@0: sl@0: // make sure we have a priority higher than that of the threads we spawn... sl@0: RThread thisThread; sl@0: TThreadPriority savedThreadPriority = thisThread.Priority(); sl@0: const TThreadPriority KMainThreadPriority = EPriorityMuchMore; sl@0: __ASSERT_COMPILE(KMainThreadPriority>TEST_INTERLEAVE_PRIO); sl@0: thisThread.SetPriority(KMainThreadPriority); sl@0: sl@0: sl@0: for (index = 0; index < TestMultipleThreadCount; index++) sl@0: { sl@0: if (TestLoading & TEST_EXE_SELF) sl@0: { sl@0: if (KErrNone == StartExe(pTheProcesses[index], 0, index + ((TestLoading & TEST_DLL) ? TestMultipleThreadCount : 0), ((TestLoading & TEST_EXE_SELF) == TEST_EXE_SELF) ? (index & 2) : (TestLoading & TEST_SELF), aLowMem, pTheSem)) sl@0: { sl@0: User::AfterHighRes(0); sl@0: pProcessInUse[index] = 1; sl@0: } sl@0: } sl@0: sl@0: sl@0: if (TestLoading & TEST_DLL) sl@0: { sl@0: DBGS_PRINT((_L("%S : Starting Thread %d\n"), &TestNameBuffer, index)); sl@0: DOTEST1(ret,pTheThreads[index].Create(KTestBlank,MultipleTestThread,KDefaultStackSize,NULL,(TAny*) index),KErrNone, KErrNoMemory); sl@0: if (ret == KErrNone) sl@0: { sl@0: pTheThreads[index].Resume(); sl@0: User::AfterHighRes(0); sl@0: pThreadInUse[index] = 1; sl@0: } sl@0: } sl@0: } sl@0: sl@0: // wait for any child threads to exit and process any debug messages they pass back to the parent. sl@0: TBool anyUsed = ETrue; sl@0: TMessageBuf localBuffer; sl@0: sl@0: TInt processOk = 0; sl@0: TInt threadOk = 0; sl@0: TInt processPanic = 0; sl@0: TInt threadPanic = 0; sl@0: TUint end = start; sl@0: TUint now; sl@0: TUint time; sl@0: TUint killNext = 0; sl@0: TUint numDots = 0; sl@0: TUint maxDots = (10*60)/TEST_DOT_PERIOD; // No individual test should take longer than 10 minutes! sl@0: // Most have been tuned to take between 2 and 8 minutes. sl@0: // The autotests should not take more than 120 minutes total. sl@0: sl@0: while(anyUsed) sl@0: { sl@0: TInt threadCount = 0; sl@0: TInt processCount = 0; sl@0: anyUsed = EFalse; sl@0: sl@0: // check the message queue and call printf if we get a message. sl@0: if (!TestSilent) sl@0: { sl@0: while (KErrNone == TestMsgQueue.Receive(localBuffer)) sl@0: { sl@0: DBGS_PRINT((localBuffer)); sl@0: } sl@0: } sl@0: sl@0: // walk through the thread list to check which are still alive. sl@0: for (index = 0; index < TestMultipleThreadCount; index++) sl@0: { sl@0: if (TestLoading & TEST_DLL) sl@0: { sl@0: if (pThreadInUse[index]) sl@0: { sl@0: if (pTheThreads[index].ExitType() != EExitPending) sl@0: { sl@0: if (pTheThreads[index].ExitType() == EExitPanic) sl@0: { sl@0: DBGS_PRINT((_L("%S : Thread %d Panic'd after %u ticks \n"), sl@0: &TestNameBuffer, index, User::TickCount() - start)); sl@0: threadPanic ++; sl@0: } sl@0: else sl@0: { sl@0: DBGS_PRINT((_L("%S : Thread %d Exited after %u ticks \n"), sl@0: &TestNameBuffer, index, User::TickCount() - start)); sl@0: threadOk ++; sl@0: } sl@0: pTheThreads[index].Close(); sl@0: pThreadInUse[index] = EFalse; sl@0: } sl@0: else sl@0: { sl@0: threadCount += 1; sl@0: anyUsed = ETrue; sl@0: if (TestThreadsExit) sl@0: { sl@0: now = User::TickCount(); sl@0: time = TUint((TUint64)(now-end)*(TUint64)TickPeriod/(TUint64)1000000); sl@0: if (time > TEST_DOT_PERIOD) sl@0: { sl@0: DBGS_PRINT((_L("%S : Thread %d still running\n"), &TestNameBuffer, index)); sl@0: } sl@0: time = TUint((TUint64)(now-killNext)*(TUint64)TickPeriod/(TUint64)1000000); sl@0: const TUint killTimeStep = (TEST_DOT_PERIOD+9)/10; // 1/10th of a dot sl@0: if(time>TEST_DOT_PERIOD+killTimeStep) sl@0: { sl@0: killNext += killTimeStep*1000000/TickPeriod; sl@0: DBGS_PRINT((_L("%S : killing Thread %d\n"), &TestNameBuffer, index)); sl@0: pTheThreads[index].Kill(KErrNone); sl@0: pTheThreads[index].Close(); sl@0: pThreadInUse[index] = EFalse; sl@0: } sl@0: } sl@0: } sl@0: } sl@0: } sl@0: if (TestLoading & TEST_EXE_SELF) sl@0: { sl@0: if (pProcessInUse[index]) sl@0: { sl@0: if (pTheProcesses[index].ExitType() != EExitPending) sl@0: { sl@0: if (pTheProcesses[index].ExitType() == EExitPanic) sl@0: { sl@0: DBGS_PRINT((_L("%S : Process %d Panic'd after %u ticks \n"), sl@0: &TestNameBuffer, sl@0: index + ((TestLoading & TEST_DLL) ? TestMultipleThreadCount : 0), sl@0: User::TickCount() - start)); sl@0: processPanic ++; sl@0: } sl@0: else sl@0: { sl@0: DBGS_PRINT((_L("%S : Process %d Exited after %u ticks \n"), sl@0: &TestNameBuffer, sl@0: index + ((TestLoading & TEST_DLL) ? TestMultipleThreadCount : 0), sl@0: User::TickCount() - start)); sl@0: processOk ++; sl@0: } sl@0: sl@0: pTheProcesses[index].Close(); sl@0: pProcessInUse[index] = EFalse; sl@0: } sl@0: else sl@0: { sl@0: processCount += 1; sl@0: anyUsed = ETrue; sl@0: if (TestThreadsExit) sl@0: { sl@0: now = User::TickCount(); sl@0: time = TUint((TUint64)(now-end)*(TUint64)TickPeriod/(TUint64)1000000); sl@0: if (time > TEST_DOT_PERIOD) sl@0: { sl@0: DBGS_PRINT((_L("%S : Process %d still running; killing it.\n"), sl@0: &TestNameBuffer, index)); sl@0: pTheProcesses[index].Kill(EExitKill); sl@0: pTheProcesses[index].Close(); sl@0: pProcessInUse[index] = EFalse; sl@0: } sl@0: sl@0: } sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: now = User::TickCount(); sl@0: time = TUint((TUint64)(now-end)*(TUint64)TickPeriod/(TUint64)1000000); sl@0: sl@0: DBGD_PRINT((_L("%S : %d seconds (%d ticks) %d threads, %d processes still alive\n"), sl@0: &TestNameBuffer, time, now, threadCount, processCount)); sl@0: sl@0: if (time > TEST_DOT_PERIOD) sl@0: { sl@0: DBGS_PRINT((_L("."))); sl@0: numDots ++; sl@0: end += TEST_DOT_PERIOD*1000000/TickPeriod; sl@0: if (TestingReaper) sl@0: { sl@0: TestingReaperCleaningFiles = ETrue; sl@0: CleanupFiles(EFalse); sl@0: CheckFilePresence(ETrue); sl@0: TestingReaperCleaningFiles = EFalse; sl@0: } sl@0: if ((numDots >= maxDots) && (!TestThreadsExit)) sl@0: { sl@0: DBGS_PRINT((_L("Taking longer than %d dots...exiting test case."), maxDots)); sl@0: TestThreadsExit = ETrue; sl@0: killNext = end; sl@0: } sl@0: } sl@0: sl@0: if (TestingChunks) sl@0: { sl@0: DoSomeChunking(); sl@0: } sl@0: sl@0: #ifdef TEST_THRASHING_TEST sl@0: User::AfterHighRes(1000); sl@0: #else sl@0: User::AfterHighRes(TickPeriod); sl@0: #endif sl@0: } sl@0: sl@0: DBGD_PRINT((_L("%S : all test threads presumably gone now\n"), &TestNameBuffer)); sl@0: sl@0: if (TestMediaAccess != KTestMediaAccessNone) sl@0: { sl@0: if (TestMediaAccess != KTestMediaAccessBasic) sl@0: { sl@0: TBool killMedia = EFalse; sl@0: TestStopMedia = ETrue; sl@0: anyUsed = ETrue; sl@0: DBGS_PRINT((_L("%S : Waiting for media threads to exit...\n"), &TestNameBuffer)); sl@0: end = User::TickCount(); sl@0: while (anyUsed) sl@0: { sl@0: anyUsed = EFalse; sl@0: sl@0: // check the message queue and call printf if we get a message. sl@0: if (!TestSilent) sl@0: { sl@0: while (KErrNone == TestMsgQueue.Receive(localBuffer)) sl@0: { sl@0: DBGS_PRINT((localBuffer)); sl@0: } sl@0: } sl@0: sl@0: for (index = 0; index < TestMultipleThreadCount; index++) sl@0: { sl@0: if (pMedInUse[index]) sl@0: { sl@0: if (pMedThreads[index].ExitType() != EExitPending) sl@0: { sl@0: if (pMedThreads[index].ExitType() == EExitPanic) sl@0: { sl@0: DBGS_PRINT((_L("%S : Media Thread %d Panic'd after %u ticks \n"), sl@0: &TestNameBuffer, index, User::TickCount() - start)); sl@0: threadPanic ++; sl@0: } sl@0: else sl@0: { sl@0: DBGS_PRINT((_L("%S : Media Thread %d Exited after %u ticks \n"), sl@0: &TestNameBuffer, index, User::TickCount() - start)); sl@0: threadOk ++; sl@0: } sl@0: pMedInUse[index] = EFalse; sl@0: } sl@0: else sl@0: { sl@0: anyUsed = ETrue; sl@0: if (killMedia) sl@0: { sl@0: DBGS_PRINT((_L("%S : Media Thread %d still going after %u ticks; killing it!\n"), sl@0: &TestNameBuffer, index, User::TickCount() - start)); sl@0: pMedThreads[index].Kill(EExitKill); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: now = User::TickCount(); sl@0: time = TUint((TUint64)(now-end)*(TUint64)TickPeriod/(TUint64)1000000); sl@0: if (time > TEST_DOT_PERIOD) sl@0: { sl@0: DBGS_PRINT((_L("."))); sl@0: end += TEST_DOT_PERIOD*1000000/TickPeriod; sl@0: killMedia = ETrue; sl@0: } sl@0: sl@0: User::AfterHighRes(50000); sl@0: sl@0: } sl@0: DBGS_PRINT((_L("%S : Media threads exited...\n"), &TestNameBuffer)); sl@0: User::Free(pMedThreads); sl@0: User::Free(pMedInUse); sl@0: } sl@0: else sl@0: { sl@0: TestStopMedia = ETrue; sl@0: DBGS_PRINT((_L("%S : Waiting for media thread to exit...\n"), &TestNameBuffer)); sl@0: end = User::TickCount(); sl@0: while (mediaThread.ExitType() == EExitPending) sl@0: { sl@0: now = User::TickCount(); sl@0: time = TUint((TUint64)(now-end)*(TUint64)TickPeriod/(TUint64)1000000); sl@0: if (time > TEST_DOT_PERIOD) sl@0: { sl@0: DBGS_PRINT((_L("%S : Media thread still going after %u seconds; killing it!\n"), sl@0: &TestNameBuffer, time)); sl@0: mediaThread.Kill(EExitKill); sl@0: } sl@0: User::AfterHighRes(50000); sl@0: } sl@0: User::WaitForRequest(mediaStatus); sl@0: mediaThread.Close(); sl@0: DBGS_PRINT((_L("%S : Media thread exited...\n"), &TestNameBuffer)); sl@0: } sl@0: } sl@0: sl@0: DBGD_PRINT((_L("%S : all media threads presumably gone now\n"), &TestNameBuffer)); sl@0: sl@0: if (!TestSilent) sl@0: { sl@0: TestMsgQueue.Close(); sl@0: } sl@0: TestMultiSem.Close(); sl@0: sl@0: DBGD_PRINT((_L("%S : about to close the libraries\n"), &TestNameBuffer)); sl@0: sl@0: if (TestLoadDllHow == TEST_DLL_GLOBAL) sl@0: { sl@0: CloseTheLibs(theGlobalLibs, maxDlls); sl@0: } sl@0: sl@0: TestThreadsExit = EFalse; sl@0: sl@0: DBGD_PRINT((_L("%S : cleaning up\n"), &TestNameBuffer)); sl@0: sl@0: // cleanup the resources and exit. sl@0: if (TestLoading & TEST_EXE_SELF) sl@0: { sl@0: User::Free(pTheProcesses); sl@0: User::Free(pProcessInUse); sl@0: } sl@0: sl@0: // cleanup the resources and exit. sl@0: if (TestLoading & TEST_DLL) sl@0: { sl@0: User::Free(pTheThreads); sl@0: User::Free(pThreadInUse); sl@0: } sl@0: sl@0: if (!TestSilent) sl@0: { sl@0: end = User::TickCount(); sl@0: time = TUint((TUint64)(end-start)*(TUint64)TickPeriod/(TUint64)1000000); sl@0: DBGS_PRINT((_L("\n%S : Multiple Test : (%u seconds)\n\tThreads panic'd = %d Ok = %d\n\tProcess panic'd = %d Ok = %d\n"), &TestNameBuffer, time, threadPanic, threadOk, processPanic, processOk)); sl@0: } sl@0: sl@0: thisThread.SetPriority(savedThreadPriority); sl@0: sl@0: return (threadPanic | processPanic) ? KErrGeneral : KErrNone; sl@0: } sl@0: sl@0: // sl@0: // DoChunkTests sl@0: // sl@0: // Allocate a chunk and assign some pages to it... sl@0: // Then do a multiple test. sl@0: // sl@0: sl@0: void DoChunkTests() sl@0: { sl@0: SVMCacheInfo tempPages; sl@0: memset(&tempPages, 0, sizeof(tempPages)); sl@0: if (TestIsDemandPaged) sl@0: { sl@0: // Shrink the page cache down to the minimum. sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0); sl@0: sl@0: DBGS_PRINT((_L("Start : min %d max %d current %d maxFree %d freeRam %d\n"), sl@0: tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize ,tempPages.iMaxFreeSize, FreeRam())); sl@0: sl@0: // set the cache small sl@0: TInt minSize = 16 * TestPageSize; sl@0: TInt maxSize = TEST_NUM_PAGES * TestPageSize; sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); sl@0: } sl@0: sl@0: if (KErrNone != TestChunk.CreateDisconnectedLocal(0,0,TEST_NUM_CHUNK_PAGES *TestPageSize)) sl@0: { sl@0: DBGS_PRINT((_L("DoChunkTests - create failed.\n"))); sl@0: return; sl@0: } sl@0: TestChunkBase = TestChunk.Base(); sl@0: if (TestChunkBase == NULL) sl@0: { sl@0: RDebug::Printf("DoChunkTests - TestChunkBase was NULL"); sl@0: TestChunk.Close(); sl@0: return; sl@0: } sl@0: TInt retVal = KErrNone; sl@0: TUint index = 0; sl@0: TestCommitEnd = 0; sl@0: memset(TestChunkPageState, 0, sizeof(TestChunkPageState)); sl@0: memset(TestChunkStats,0,sizeof(TestChunkStats)); sl@0: while(index < TEST_NUM_CHUNK_PAGES) sl@0: { sl@0: retVal = TestChunk.Commit(TestCommitEnd,TestPageSize); sl@0: if (KErrNone != retVal) sl@0: { sl@0: DBGS_PRINT((_L("%S : TestChunk.Commit returned %d for 0x%08x...\n"), &TestNameBuffer, retVal, TestCommitEnd)); sl@0: break; sl@0: } sl@0: TestChunkPageState[index] = ETrue; sl@0: FillPage(TestCommitEnd); sl@0: TestCommitEnd += TestPageSize; sl@0: index ++; sl@0: } sl@0: RUNTEST1(retVal == KErrNone); sl@0: sl@0: // now do some testing.... sl@0: TestingChunks = ETrue; sl@0: TestInterleave = EFalse; sl@0: TestPrioChange = ETrue; sl@0: TestMediaAccess = KTestMediaAccessNone; sl@0: // temp sl@0: TestWhichMedia = TEST_MEDIA_ROM_BASE; sl@0: sl@0: if (TestChunksPlus) sl@0: { sl@0: TestMaxLoops = 1; sl@0: TestMultipleThreadCount = 40; sl@0: } sl@0: else if (TestExtremeChunks) sl@0: { sl@0: TestMaxLoops = 10; sl@0: TestMultipleThreadCount = 12; sl@0: } sl@0: else sl@0: { sl@0: TestMaxLoops = 3; sl@0: TestMultipleThreadCount = 20; sl@0: } sl@0: TestWhichTests = TEST_RANDOM; sl@0: sl@0: TestLoading = TEST_EXE_SELF_DLL; sl@0: TestLoadDllHow = TEST_DLL_FUNC; sl@0: TestChunkingIndexFails = 0; sl@0: sl@0: TEST_NEXT((_L("Multiple threads random with chunks."))); sl@0: RUNTEST(DoMultipleTest(), KErrNone); sl@0: sl@0: TestingChunks = EFalse; sl@0: sl@0: // clean up. sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalFlushCache,0,0); sl@0: TestChunk.Close(); sl@0: sl@0: if (TestIsDemandPaged) sl@0: { sl@0: // put the cache back to the the original values. sl@0: TInt minSize = tempPages.iMinSize; sl@0: TInt maxSize = tempPages.iMaxSize; sl@0: sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); sl@0: sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0); sl@0: sl@0: DBGS_PRINT((_L("Finish : min %d max %d current %d maxFree %d freeRam %d\n"), sl@0: tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize ,tempPages.iMaxFreeSize, FreeRam())); sl@0: } sl@0: TChunkTestStats stats; sl@0: sl@0: memset(&stats, 0, sizeof(stats)); sl@0: DBGS_PRINT((_L("Stats : (pass/fail) \nindex\t\tlock\t\tunlock\t\tcommit\t\tdecommit\t\tcheck\n"))); sl@0: for (index = 0; index < TEST_NUM_CHUNK_PAGES; index ++) sl@0: { sl@0: DBGS_PRINT((_L("%u\t\t%d/%d\t\t%d/%d\t\t%d/%d\t\t%d/%d\t\t%d/%d\n"), sl@0: index, sl@0: TestChunkStats[index].lock.ok, TestChunkStats[index].lock.fail, sl@0: TestChunkStats[index].unlock.ok, TestChunkStats[index].unlock.fail, sl@0: TestChunkStats[index].commit.ok, TestChunkStats[index].commit.fail, sl@0: TestChunkStats[index].decommit.ok, TestChunkStats[index].decommit.fail, sl@0: TestChunkStats[index].check.ok, TestChunkStats[index].check.fail)); sl@0: sl@0: stats.lock.ok += TestChunkStats[index].lock.ok; sl@0: stats.lock.fail += TestChunkStats[index].lock.fail; sl@0: stats.unlock.ok += TestChunkStats[index].unlock.ok; sl@0: stats.unlock.fail += TestChunkStats[index].unlock.fail; sl@0: stats.decommit.ok += TestChunkStats[index].decommit.ok; sl@0: stats.decommit.fail += TestChunkStats[index].decommit.fail; sl@0: stats.commit.ok += TestChunkStats[index].commit.ok; sl@0: stats.commit.fail += TestChunkStats[index].commit.fail; sl@0: stats.check.ok += TestChunkStats[index].check.ok; sl@0: stats.check.fail += TestChunkStats[index].check.fail; sl@0: } sl@0: sl@0: DBGS_PRINT((_L("Total Stats (p/f): \n\t lock %d / %d\n\t unlock %d / %d\n\t commit %d / %d\n\t decommit %d / %d\n\t check %d / %d\n"), sl@0: stats.lock.ok, stats.lock.fail, sl@0: stats.unlock.ok, stats.unlock.fail, sl@0: stats.commit.ok, stats.commit.fail, sl@0: stats.decommit.ok, stats.decommit.fail, sl@0: stats.check.ok, stats.check.fail)); sl@0: DBGS_PRINT((_L("TestChunkingIndexFails %d\n"), TestChunkingIndexFails)); sl@0: sl@0: } sl@0: sl@0: // sl@0: // DoReaperTests sl@0: // sl@0: // Test the reaper by deleting the transient files and re-creating them. sl@0: // sl@0: sl@0: void DoReaperTests(void) sl@0: { sl@0: // make sure we have the full complement of files. sl@0: CheckFilePresence(ETrue); sl@0: sl@0: // now do some testing.... sl@0: TestInterleave = EFalse; sl@0: TestPrioChange = EFalse; sl@0: TestMediaAccess = KTestMediaAccessNone; sl@0: // temp sl@0: TestWhichMedia = TEST_MEDIA_ALL; sl@0: TestMaxLoops = 3; sl@0: TestMultipleThreadCount = 12; sl@0: TestWhichTests = TEST_RANDOM; sl@0: sl@0: TestLoading = TEST_EXE_SELF_DLL; sl@0: TestLoadDllHow = TEST_DLL_FUNC; sl@0: sl@0: TestingReaper = ETrue; sl@0: sl@0: TEST_NEXT((_L("Reaper tests."))); sl@0: RUNTEST(DoMultipleTest(), KErrNone); sl@0: TestInterleave = ETrue; sl@0: TestPrioChange = ETrue; sl@0: TEST_NEXT((_L("Reaper tests 2."))); sl@0: RUNTEST(DoMultipleTest(), KErrNone); sl@0: sl@0: TestingReaper = EFalse; sl@0: } sl@0: sl@0: // sl@0: // DoBtraceTest sl@0: // sl@0: // Test the paging BTrace function. sl@0: // sl@0: sl@0: void DoBtraceTest(void) sl@0: { sl@0: #define LE4(a) ((*((a) + 3) << 24) + (*((a) + 2) << 16) + (*((a) + 1) << 8) + *(a)) sl@0: sl@0: RBTrace bTraceHandle; sl@0: sl@0: TInt r = bTraceHandle.Open(); sl@0: test(r == KErrNone); sl@0: sl@0: r = bTraceHandle.ResizeBuffer(0x200000); sl@0: test(r == KErrNone); sl@0: bTraceHandle.SetFilter(BTrace::EPaging, ETrue); sl@0: sl@0: // Enable trace sl@0: bTraceHandle.Empty(); sl@0: bTraceHandle.SetMode(RBTrace::EEnable); sl@0: sl@0: TestLoading = TEST_EXE_SELF_DLL; sl@0: TestWhichMedia = TEST_MEDIA_ROM_BASE; sl@0: TestMaxLoops = 2; sl@0: TestMultipleThreadCount = 10; sl@0: TestLoadDllHow = TEST_DLL_FUNC; sl@0: TestInterleave = ETrue; sl@0: TestPrioChange = ETrue; sl@0: TestMediaAccess = KTestMediaAccessNone; sl@0: TestWhichTests = TEST_RANDOM; sl@0: TestingLowMem = EFalse; sl@0: sl@0: RUNTEST(DoMultipleTest(TestingLowMem), KErrNone); sl@0: sl@0: bTraceHandle.SetMode(0); sl@0: sl@0: // analyse the btrace logs and display on the serial port. sl@0: TUint8* pDataStart; sl@0: TInt dataSize; sl@0: TUint8* pTemp; sl@0: TUint8* pThis; sl@0: TUint8* pEnd; sl@0: TBuf<128> data; sl@0: while (1) sl@0: { sl@0: dataSize = bTraceHandle.GetData(pDataStart); sl@0: if (dataSize <= 0) sl@0: { sl@0: break; sl@0: } sl@0: pEnd = pDataStart + dataSize; sl@0: pTemp = pDataStart; sl@0: while (pTemp < pEnd) sl@0: { sl@0: TUint8 recSize = pTemp[BTrace::ESizeIndex]; sl@0: TUint8 recFlags = pTemp[BTrace::EFlagsIndex]; sl@0: TUint8 recCat = pTemp[BTrace::ECategoryIndex]; sl@0: TUint8 recSub = pTemp[BTrace::ESubCategoryIndex]; sl@0: TUint32 addr[4]; sl@0: pThis = pTemp; sl@0: sl@0: data.Zero(); sl@0: // step over the header. sl@0: data.Format(_L("size %d cat %d sub %d flg 0x%02x "), recSize, recCat, recSub, recFlags); sl@0: pTemp += 4; sl@0: sl@0: if (recFlags & BTrace::EHeader2Present) sl@0: { sl@0: data.AppendFormat(_L("h2 0x%08x "), LE4(pTemp)); sl@0: pTemp += 4; sl@0: } sl@0: if (recFlags & BTrace::ETimestampPresent) sl@0: { sl@0: data.AppendFormat(_L("ts 0x%08x "), LE4(pTemp)); sl@0: pTemp += 4; sl@0: } sl@0: if (recFlags & BTrace::ETimestamp2Present) sl@0: { sl@0: data.AppendFormat(_L("ts2 0x%08x "), LE4(pTemp)); sl@0: pTemp += 4; sl@0: } sl@0: if (recFlags & BTrace::EContextIdPresent) sl@0: { sl@0: data.AppendFormat(_L("cId 0x%08x "), LE4(pTemp)); sl@0: pTemp += 4; sl@0: } sl@0: TInt index; sl@0: for (index = 0; index < 4; index ++) sl@0: { sl@0: if (recSize > pTemp - pThis) sl@0: { sl@0: addr[index] = LE4(pTemp); sl@0: pTemp += 4; sl@0: } sl@0: else sl@0: addr[index] = 0; sl@0: } sl@0: sl@0: switch(recCat) sl@0: { sl@0: case BTrace::EPaging: sl@0: { sl@0: switch (recSub) sl@0: { sl@0: case BTrace::EPagingPageInBegin: sl@0: /** sl@0: - 4 bytes containing the virtual address which was accessed, causing this paging event. sl@0: - 4 bytes containing the virtual address of the instuction which caused this paging event. sl@0: (The PC value.) sl@0: **/ sl@0: test.Printf(_L("PageInBegin : %S addr 0x%08x inst 0x%08x\n"), &data, addr[0], addr[1]); sl@0: break; sl@0: sl@0: /** sl@0: - 0 bytes. (No extra data.) sl@0: */ sl@0: case BTrace::EPagingPageInUnneeded: sl@0: test.Printf(_L("PageInUnneeded : %S\n"), &data); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page 'paged in'. sl@0: - 4 bytes containing the virtual address of the page 'paged in'. sl@0: */ sl@0: case BTrace::EPagingPageInROM: sl@0: test.Printf(_L("PageInROM : %S phys 0x%08x virt 0x%08x\n"), &data, addr[0], addr[1]); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page being 'paged out'. sl@0: - 4 bytes containing the virtual address of the page being 'paged out'. sl@0: */ sl@0: case BTrace::EPagingPageOutROM: sl@0: test.Printf(_L("PageOutROM : %S phys 0x%08x virt 0x%08x\n"), &data, addr[0], addr[1]); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page being 'paged in'. sl@0: */ sl@0: case BTrace::EPagingPageInFree: sl@0: test.Printf(_L("PageInFree : %S phys 0x%08x\n"), &data, addr[0]); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page being 'paged out'. sl@0: */ sl@0: case BTrace::EPagingPageOutFree: sl@0: test.Printf(_L("PageOutFree : %S phys 0x%08x\n"), &data, addr[0]); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page being rejuvenated, (made young). sl@0: - 4 bytes containing the virtual address which was accessed, causing this paging event. sl@0: - 4 bytes containing the virtual address of the instuction which caused this paging event. sl@0: (The PC value.) sl@0: */ sl@0: case BTrace::EPagingRejuvenate: sl@0: test.Printf(_L("Rejuvenate : %S phys 0x%08x virt 0x%08x inst 0x%08x\n"), &data, addr[0], addr[1], addr[2]); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page accessed. sl@0: - 4 bytes containing the virtual address which was accessed, causing this paging event. sl@0: - 4 bytes containing the virtual address of the instuction which caused this paging event. sl@0: (The PC value.) sl@0: */ sl@0: case BTrace::EPagingPageNop: sl@0: test.Printf(_L("PageNop : %S phys 0x%08x virt 0x%08x inst 0x%08x\n"), &data, addr[0], addr[1], addr[2]); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page being locked. sl@0: - 4 bytes containing the value of the lock count after the paged was locked. sl@0: */ sl@0: case BTrace::EPagingPageLock: sl@0: test.Printf(_L("PageLock : %S phys 0x%08x lock 0x%08x\n"), &data, addr[0], addr[1]); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page being unlocked. sl@0: - 4 bytes containing the value of the lock count before the paged was unlocked. sl@0: */ sl@0: case BTrace::EPagingPageUnlock: sl@0: test.Printf(_L("PageUnlock : %S phys 0x%08x lock 0x%08x\n"), &data, addr[0], addr[1]); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page being 'paged out'. sl@0: - 4 bytes containing the virtual address of the page being 'paged out'. sl@0: */ sl@0: case BTrace::EPagingPageOutCache: sl@0: test.Printf(_L("PageOutCache : %S phys 0x%08x virt 0x%08x\n"), &data, addr[0], addr[1]); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page 'paged in'. sl@0: - 4 bytes containing the virtual address of the page 'paged in'. sl@0: */ sl@0: case BTrace::EPagingPageInCode: sl@0: test.Printf(_L("PageInCode : %S phys 0x%08x virt 0x%08x\n"), &data, addr[0], addr[1]); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page being 'paged out'. sl@0: - 4 bytes containing the virtual address of the page being 'paged out'. sl@0: */ sl@0: case BTrace::EPagingPageOutCode: sl@0: test.Printf(_L("PageOutCode : %S phys 0x%08x virt 0x%08x\n"), &data, addr[0], addr[1]); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page 'paged in'. sl@0: - 4 bytes containing the virtual address of the page 'paged in'. sl@0: */ sl@0: case BTrace::EPagingMapCode: sl@0: test.Printf(_L("MapCode : %S phys 0x%08x virt 0x%08x\n"), &data, addr[0], addr[1]); sl@0: break; sl@0: sl@0: /** sl@0: - 4 bytes containing the physical address of the page being aged, (made old). sl@0: */ sl@0: case BTrace::EPagingAged: sl@0: test.Printf(_L("Aged : %S phys 0x%08x\n"), &data, addr[0]); sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: default: sl@0: sl@0: break; sl@0: } sl@0: pTemp = BTrace::NextRecord(pThis); sl@0: } sl@0: bTraceHandle.DataUsed(); sl@0: } sl@0: bTraceHandle.Close(); sl@0: } sl@0: sl@0: // sl@0: // ParseCommandLine sl@0: // sl@0: // read the arguments passed from the command line and set global variables to sl@0: // control the tests. sl@0: // sl@0: sl@0: TBool ParseCommandLine() sl@0: { sl@0: TBuf<256> args; sl@0: User::CommandLine(args); sl@0: TLex lex(args); sl@0: TBool retVal = ETrue; sl@0: sl@0: // initially test for arguments, the parse them, if not apply some sensible defaults. sl@0: TBool foundArgs = EFalse; sl@0: sl@0: FOREVER sl@0: { sl@0: TPtrC token=lex.NextToken(); sl@0: if(token.Length()!=0) sl@0: { sl@0: if ((token == _L("help")) || (token == _L("-h")) || (token == _L("-?"))) sl@0: { sl@0: DBGS_PRINT((_L("\nUsage: [ single | multiple <numThreads>] [ dll | exe | self | complete ] [func | thread | global ] [ rom | base | mixed | mall ] [reaper] [chunks|echunks|chunks+ {nochunkdata}] [prio] [media] [lowmem] [forward | backward | random | all] [loadGlobal | loadThread | loadFunc] [interleave] [d_exc] [btrace] [defrag] [noclean] [min <pages>] [max <pages>] [stressfree] [iters <iters>]\n'-' indicated infinity.\n\n"))); sl@0: test.Getch(); sl@0: } sl@0: else if (token == _L("mmc")) sl@0: { sl@0: TestOnlyFromMmc = ETrue; sl@0: } sl@0: else if (token == _L("min")) sl@0: { sl@0: TPtrC val=lex.NextToken(); sl@0: TLex lexv(val); sl@0: TInt value; sl@0: lexv.Val(value); sl@0: TestMinCacheSize = value * 4096; sl@0: } sl@0: else if (token == _L("max")) sl@0: { sl@0: TPtrC val=lex.NextToken(); sl@0: TLex lexv(val); sl@0: TInt value; sl@0: lexv.Val(value); sl@0: TestMaxCacheSize = value * 4096; sl@0: } sl@0: else if (token == _L("interleave")) sl@0: { sl@0: TestInterleave = ETrue; sl@0: } sl@0: else if (token == _L("auto")) sl@0: { sl@0: TestFullAutoTest = EFalse; sl@0: retVal = EFalse; sl@0: } sl@0: else if (token == _L("stressfree")) sl@0: { sl@0: TestStressFree = !TestStressFree; sl@0: retVal = EFalse; sl@0: } sl@0: else if (token == _L("fullauto")) sl@0: { sl@0: TestFullAutoTest = ETrue; sl@0: retVal = EFalse; sl@0: } sl@0: else if (token == _L("prio")) sl@0: { sl@0: TestPrioChange = !TestPrioChange; sl@0: } sl@0: else if (token == _L("media")) sl@0: { sl@0: TestMediaAccess = KTestMediaAccessBasic; sl@0: } sl@0: else if (token == _L("reaper")) sl@0: { sl@0: TestReaper = ETrue; sl@0: } sl@0: else if (token == _L("btrace")) sl@0: { sl@0: TestBtrace = ETrue; sl@0: } sl@0: else if (token == _L("defrag")) sl@0: { sl@0: TestDefrag = ETrue; sl@0: } sl@0: else if (token == _L("echunks")) sl@0: { sl@0: TestChunks = ETrue; sl@0: TestExtremeChunks = ETrue; sl@0: } sl@0: else if (token == _L("chunks+")) sl@0: { sl@0: TestChunks = ETrue; sl@0: TestChunksPlus = ETrue; sl@0: } sl@0: else if (token == _L("chunks")) sl@0: { sl@0: TestChunks = ETrue; sl@0: } sl@0: else if (token == _L("nochunkdata")) sl@0: { sl@0: TestChunkData = EFalse; sl@0: } sl@0: else if (token == _L("lowmem")) sl@0: { sl@0: TestLowMem = ETrue; sl@0: } sl@0: else if (token == _L("dll")) sl@0: { sl@0: TestLoading = TEST_DLL; sl@0: } sl@0: else if (token == _L("exe")) sl@0: { sl@0: TestLoading = TEST_EXE; sl@0: } sl@0: else if (token == _L("self")) sl@0: { sl@0: TestLoading = TEST_SELF; sl@0: } sl@0: else if (token == _L("complete")) sl@0: { sl@0: TestLoading |= TEST_EXE_SELF_DLL; sl@0: } sl@0: else if (token == _L("rom")) sl@0: { sl@0: TestWhichMedia = TEST_MEDIA_ROM; sl@0: } sl@0: else if (token == _L("base")) sl@0: { sl@0: TestWhichMedia = TEST_MEDIA_BASE; sl@0: } sl@0: else if (token == _L("mixed")) sl@0: { sl@0: TestWhichMedia |= TEST_MEDIA_ROM_BASE; sl@0: } sl@0: else if (token == _L("all_media")) sl@0: { sl@0: TestWhichMedia |= TEST_MEDIA_ALL; sl@0: } sl@0: else if (token == _L("debug")) sl@0: { sl@0: if (!TestSilent) sl@0: { sl@0: TestDebug = ETrue; sl@0: TestPrioChange = ETrue; sl@0: } sl@0: } sl@0: else if (token == _L("silent")) sl@0: { sl@0: TestSilent = ETrue; sl@0: TestDebug = EFalse; sl@0: } sl@0: else if (token == _L("noclean")) sl@0: { sl@0: TestNoClean = ETrue; sl@0: } sl@0: else if (token == _L("d_exc")) sl@0: { sl@0: TestD_Exc = ETrue; sl@0: } sl@0: else if (token == _L("global")) sl@0: { sl@0: TestLoadDllHow = TEST_DLL_GLOBAL; sl@0: } sl@0: else if (token == _L("thread")) sl@0: { sl@0: TestLoadDllHow = TEST_DLL_THREAD; sl@0: } sl@0: else if (token == _L("func")) sl@0: { sl@0: TestLoadDllHow = TEST_DLL_FUNC; sl@0: } sl@0: else if (token == _L("single")) sl@0: { sl@0: TestSingle = ETrue; sl@0: } sl@0: else if (token == _L("multiple")) sl@0: { sl@0: TPtrC val=lex.NextToken(); sl@0: TLex lexv(val); sl@0: TInt value; sl@0: sl@0: if (lexv.Val(value)==KErrNone) sl@0: { sl@0: if ((value <= 0) || (value > 100)) sl@0: { sl@0: TestMultipleThreadCount = 10; sl@0: } sl@0: else sl@0: { sl@0: TestMultipleThreadCount = value; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: DBGS_PRINT((_L("Bad value for thread count '%S' was ignored.\n"), &val)); sl@0: retVal = EFalse; sl@0: break; sl@0: } sl@0: TestMultiple = ETrue; sl@0: } sl@0: else if (token == _L("forward")) sl@0: { sl@0: TestWhichTests = TEST_FORWARD; sl@0: } sl@0: else if (token == _L("backward")) sl@0: { sl@0: TestWhichTests = TEST_BACKWARD; sl@0: } sl@0: else if (token == _L("random")) sl@0: { sl@0: TestWhichTests = TEST_RANDOM; sl@0: } sl@0: else if (token == _L("all")) sl@0: { sl@0: TestWhichTests = TEST_ALL; sl@0: } sl@0: else if (token == _L("inst")) sl@0: { sl@0: TPtrC val=lex.NextToken(); sl@0: TLex lexv(val); sl@0: TInt value; sl@0: sl@0: if (lexv.Val(value)==KErrNone) sl@0: { sl@0: TestInstanceId = value; sl@0: } sl@0: } sl@0: else if (token == _L("iters")) sl@0: { sl@0: TPtrC val=lex.NextToken(); sl@0: TLex lexv(val); sl@0: TInt value; sl@0: sl@0: if (val==_L("-")) sl@0: { sl@0: TestMaxLoops = KMaxTInt; sl@0: } sl@0: else sl@0: { sl@0: if (lexv.Val(value)==KErrNone) sl@0: { sl@0: TestMaxLoops = value; sl@0: } sl@0: else sl@0: { sl@0: DBGS_PRINT((_L("Bad value for thread count '%S' was ignored.\n"), &val)); sl@0: retVal = EFalse; sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if ((foundArgs == EFalse) && (token.Length() == 1)) sl@0: { sl@0: // Single letter argument...only run on 'd' sl@0: if (token.CompareF(_L("d")) == 0) sl@0: { sl@0: sl@0: TestFullAutoTest = EFalse; sl@0: TestIsAutomated = ETrue; sl@0: break; sl@0: } sl@0: else sl@0: { sl@0: if (!TestSilent) sl@0: { sl@0: test.Title(); sl@0: test.Start(_L("Skipping non drive 'd' - Test Exiting.")); sl@0: test.End(); sl@0: } sl@0: foundArgs = ETrue; sl@0: TestExit = ETrue; sl@0: break; sl@0: } sl@0: } sl@0: DBGS_PRINT((_L("Unknown argument '%S' was ignored.\n"), &token)); sl@0: break; sl@0: } sl@0: foundArgs = ETrue; sl@0: } sl@0: else sl@0: { sl@0: break; sl@0: } sl@0: } sl@0: if (!foundArgs) sl@0: { sl@0: retVal = EFalse; sl@0: } sl@0: return retVal; sl@0: } sl@0: sl@0: // sl@0: // AreWeTheTestBase sl@0: // sl@0: // Test whether we are the root of the tests. sl@0: // sl@0: void AreWeTheTestBase() sl@0: { sl@0: if (!TestSilent) sl@0: { sl@0: TFileName filename(RProcess().FileName()); sl@0: sl@0: TParse myParse; sl@0: myParse.Set(filename, NULL, NULL); sl@0: TestNameBuffer.Zero(); sl@0: TestNameBuffer.Append(myParse.Name()); sl@0: TestNameBuffer.Append(_L(".exe")); sl@0: sl@0: TestWeAreTheTestBase = !TestNameBuffer.Compare(TestPlExeNames[KTestMediaBase]); sl@0: sl@0: RFs fs; sl@0: if (KErrNone == fs.Connect()) sl@0: { sl@0: TEntry anEntry; sl@0: TInt retVal = fs.Entry(_L("z:\\test\\mmcdemandpaginge32tests.bat"), anEntry); sl@0: if (retVal == KErrNone) sl@0: { sl@0: TestBootedFromMmc = ETrue; sl@0: } sl@0: else sl@0: { sl@0: TestBootedFromMmc = EFalse; sl@0: } sl@0: fs.Close(); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: TestNameBuffer.Zero(); sl@0: TestNameBuffer.Append(_L("t_pageldrtst.exe")); sl@0: } sl@0: } sl@0: #define MEDNONE KTestMediaAccessNone sl@0: #define MEDBASIC KTestMediaAccessBasic sl@0: #define MEDMTHRE KTestMediaAccessMultipleThreads sl@0: #define MEDMPATT KTestMediaAccessMultiplePattern sl@0: #define MEDMIX KTestMediaAccessMixed sl@0: sl@0: TTheTests TheAutoTests[] = sl@0: {// fullOnly, loading, media, multi, loops, threads, loadHow, inter, prio, media, whichTests, lowmem, free, testName sl@0: #ifdef TEST_SHORT_TEST sl@0: { EFalse, TEST_DLL, TEST_MEDIA_ALL, ETrue, 2, 24, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("DLL Load (ALL Media) Multiple thread all."), }, sl@0: #else sl@0: { EFalse, TEST_DLL, TEST_MEDIA_BASE, ETrue, 5, 24, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_THRASH, EFalse, 0, }, //_L("DLL Load (ROM) Multiple thread Thrash."), }, sl@0: { ETrue, TEST_DLL, TEST_MEDIA_ROM_BASE, EFalse, 5, 20, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_ALL, EFalse, 0, }, //_L("DLL Load (ROM/ROFS) Single thread all."), }, sl@0: { ETrue, TEST_EXE, TEST_MEDIA_ROM_BASE, EFalse, 5, 20, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_ALL, EFalse, 0, }, //_L("Exe Load (ROM/ROFS) Single thread."), }, sl@0: { ETrue, TEST_SELF, TEST_MEDIA_ROM_BASE, EFalse, 5, 20, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_ALL, EFalse, 0, }, //_L("Self Load (ROM/ROFS) Single thread."), }, sl@0: { ETrue, TEST_DLL, TEST_MEDIA_ROM_BASE, ETrue, 5, 20, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("DLL Load (ROM/ROFS) Multiple thread all."), }, sl@0: { EFalse, TEST_DLL, TEST_MEDIA_ALL, ETrue, 3, 20, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("DLL Load (ALL Media) Multiple thread all."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 16, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load (All Media) Multiple threads."), }, sl@0: { EFalse, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 16, TEST_DLL_FUNC, EFalse, ETrue, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load (All Media) Multiple threads with prio."), }, sl@0: { EFalse, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 10, TEST_DLL_FUNC, EFalse, EFalse, MEDBASIC, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load (All Media) Multiple threads with media access."), }, sl@0: { EFalse, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 12, TEST_DLL_FUNC, EFalse, ETrue, MEDBASIC, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load (All Media) Multiple threads with media access and prio."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 16, TEST_DLL_THREAD, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load thread (All Media) Multiple threads."), }, sl@0: { EFalse, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 16, TEST_DLL_THREAD, EFalse, ETrue, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load thread (All Media) Multiple threads with prio."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 12, TEST_DLL_THREAD, EFalse, ETrue, MEDBASIC, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load thread (All Media) Multiple threads with media access and prio."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 16, TEST_DLL_GLOBAL, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load global (All Media) Multiple threads."), }, sl@0: { EFalse, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 16, TEST_DLL_GLOBAL, EFalse, ETrue, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load global (All Media) Multiple threads with prio."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 12, TEST_DLL_GLOBAL, EFalse, ETrue, MEDBASIC, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load global (All Media) Multiple threads with media access and prio."), }, sl@0: { EFalse, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 16, TEST_DLL_FUNC, ETrue, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load (All Media) Multiple threads with interleave."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 16, TEST_DLL_FUNC, ETrue, ETrue, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load (All Media) Multiple threads with interleave, prio."), }, sl@0: sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 16, TEST_DLL_FUNC, ETrue, ETrue, MEDBASIC, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load (All Media) Multiple threads with interleave, media and prio."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 12, TEST_DLL_FUNC, ETrue, ETrue, MEDMTHRE, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load (All Media) Multiple threads with interleave, multi media and prio."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 12, TEST_DLL_FUNC, ETrue, ETrue, MEDMPATT, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load (All Media) Multiple threads with interleave, media and prio."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 12, TEST_DLL_FUNC, ETrue, ETrue, MEDMIX, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load (All Media) Multiple threads with interleave, media and prio."), }, sl@0: { EFalse, TEST_EXE_SELF_DLL, TEST_MEDIA_ROM_BASE, ETrue, 2, 10, TEST_DLL_FUNC, ETrue, ETrue, MEDMIX, TEST_RANDOM, EFalse, 0, }, //_L("DLL/EXE/SELF Load Multiple threads with interleave, media and prio."), }, sl@0: #endif // TEST_SHORT_TEST sl@0: }; sl@0: #define NUM_AUTO_TESTS (TInt)(sizeof(TheAutoTests) / sizeof(TTheTests)) sl@0: sl@0: // sl@0: // PerformAutoTest sl@0: // sl@0: // The autotest. sl@0: // sl@0: sl@0: void PerformAutoTest(TBool aReduceTime = EFalse) sl@0: { sl@0: TInt testIndex; sl@0: TTheTests *pTest = &TheAutoTests[0]; sl@0: sl@0: DoStats(); sl@0: sl@0: for (testIndex = 0; testIndex < NUM_AUTO_TESTS; testIndex ++, pTest++) sl@0: { sl@0: if ( ( !TestWeAreTheTestBase sl@0: && ( (pTest->testLoadDllHow != TEST_DLL_FUNC) sl@0: || !pTest->testMultiple)) sl@0: || ((TestFullAutoTest == EFalse) && (pTest->testFullAutoOnly))) sl@0: { sl@0: continue; sl@0: } sl@0: sl@0: TestLoading = pTest->testLoading; sl@0: TestWhichMedia = pTest->testWhichMedia; sl@0: TestMaxLoops = aReduceTime ? 1 : pTest->testMaxLoops; sl@0: TestMultipleThreadCount = aReduceTime ? 10 : pTest->testMultipleThreadCount; sl@0: TestLoadDllHow = pTest->testLoadDllHow; sl@0: TestInterleave = pTest->testInterleave; sl@0: TestPrioChange = pTest->testPrioChange; sl@0: TestMediaAccess = pTest->testMediaAccess; sl@0: if (aReduceTime && (TestMediaAccess != MEDBASIC) && (TestMediaAccess != MEDNONE)) sl@0: { sl@0: continue; sl@0: } sl@0: TestWhichTests = pTest->testWhichTests; sl@0: TestingLowMem = pTest->testLowMem; sl@0: if (!TestSilent) sl@0: { sl@0: test.Next(_L("Auto Test")); sl@0: } sl@0: if (pTest->testMultiple) sl@0: { sl@0: RUNTEST(DoMultipleTest(ETrue), KErrNone); sl@0: } sl@0: else sl@0: { sl@0: RUNTEST(DoSingleTest(ETrue), KErrNone); sl@0: } sl@0: sl@0: DoStats(); sl@0: sl@0: #ifdef TEST_KERN_HEAP sl@0: __KHEAP_MARK; sl@0: __KHEAP_CHECK(0); sl@0: __KHEAP_MARKEND; sl@0: #endif sl@0: } sl@0: #ifdef TEST_KERN_HEAP sl@0: __KHEAP_MARK; sl@0: __KHEAP_CHECK(0); sl@0: __KHEAP_MARKEND; sl@0: #endif sl@0: } sl@0: sl@0: TTheTests TheLowMemTests[] = sl@0: {// fullOnly, loading, media, multi, loops, threads, loadHow, inter, prio, media, whichTests, lowmem, free, testName sl@0: #ifndef TEST_SHORT_TEST sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ROM_BASE, EFalse, 1, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("Single thread with Low memory (init)."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ROM_BASE, EFalse, 5, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, ETrue, 0, }, //_L("Single thread with Low memory."), }, sl@0: { ETrue, TEST_DLL, TEST_MEDIA_ROM_BASE, EFalse, 1, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("Multiple thread with Low memory (init)."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ROM_BASE, ETrue, 2, 16, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, ETrue, 0, }, //_L("Multiple thread with Low memory ."), }, sl@0: { EFalse, TEST_DLL, TEST_MEDIA_ALL, EFalse, 5, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("Multiple thread with Low memory and All media(init)."), }, sl@0: { EFalse, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 12, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, ETrue, 0, }, //_L("Multiple thread with Low memory and All media."), }, sl@0: { ETrue, TEST_DLL, TEST_MEDIA_ROM_BASE, EFalse, 1, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("Multiple thread with Low memory, with starting free ram (init)."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ROM_BASE, ETrue, 2, 16, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, ETrue, 32, }, //_L("Multiple thread with Low memory, with starting free ram."), }, sl@0: { ETrue, TEST_DLL, TEST_MEDIA_ROM_BASE, EFalse, 1, 16, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("Multiple thread with Low memory and prio and media access(init)."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ROM_BASE, ETrue, 2, 16, TEST_DLL_FUNC, EFalse, ETrue, MEDBASIC, TEST_RANDOM, ETrue, 0, }, //_L("Multiple thread with Low memory and prio and media access."), }, sl@0: { ETrue, TEST_DLL, TEST_MEDIA_ROM_BASE, EFalse, 1, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("Multiple thread with Low memory interleave, prio and media access(init)."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ROM_BASE, ETrue, 2, 16, TEST_DLL_FUNC, ETrue, ETrue, MEDBASIC, TEST_RANDOM, ETrue, 0, }, //_L("Multiple thread with Low memory interleave, prio and media access."), }, sl@0: { ETrue, TEST_DLL, TEST_MEDIA_ROM_BASE, EFalse, 1, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("Multiple thread with Low memory interleave, media access and All media (init)."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 16, TEST_DLL_FUNC, ETrue, EFalse, MEDBASIC, TEST_RANDOM, ETrue, 0, }, //_L("Multiple thread with Low memory interleave, media access and All media + loading."), }, sl@0: { EFalse, TEST_DLL, TEST_MEDIA_ROM_BASE, EFalse, 10, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("Single thread with Low memory (init)."), }, sl@0: { EFalse, TEST_DLL, TEST_MEDIA_ROM_BASE, EFalse, 5, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, ETrue, 0, }, //_L("Single thread with Low memory."), }, sl@0: #endif //TEST_SHORT_TEST sl@0: { EFalse, TEST_DLL, TEST_MEDIA_ROM_BASE, EFalse, 10, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("Multiple thread with Low memory interleave, prio, media access and All media (init)."), }, sl@0: { EFalse, TEST_EXE_SELF_DLL, TEST_MEDIA_ROM_BASE, ETrue, 2, 16, TEST_DLL_FUNC, ETrue, ETrue, MEDBASIC, TEST_RANDOM, ETrue, 0, }, //_L("Multiple thread with Low memory interleave, prio, media access and All media + loading."), }, sl@0: { EFalse, TEST_DLL, TEST_MEDIA_ROM_BASE, EFalse, 5, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("Multiple thread with Low memory interleave, prio, media access and All media (init)."), }, sl@0: { EFalse, TEST_EXE_SELF_DLL, TEST_MEDIA_ROM_BASE, ETrue, 2, 10, TEST_DLL_FUNC, ETrue, ETrue, MEDMTHRE, TEST_RANDOM, ETrue, 0, }, //_L("Multiple thread with Low memory interleave, prio, multi media access and All media + loading."), }, sl@0: { ETrue, TEST_DLL, TEST_MEDIA_ROM_BASE, EFalse, 1, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("Multiple thread with Low memory interleave, prio, media access and All media (init)."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 16, TEST_DLL_FUNC, ETrue, ETrue, MEDBASIC, TEST_RANDOM, ETrue, 0, }, //_L("Multiple thread with Low memory interleave, prio, media access and All media + loading."), }, sl@0: { ETrue, TEST_DLL, TEST_MEDIA_ROM_BASE, EFalse, 1, 1, TEST_DLL_FUNC, EFalse, EFalse, MEDNONE, TEST_RANDOM, EFalse, 0, }, //_L("Multiple thread with Low memory interleave, prio, media access and All media (init)."), }, sl@0: { ETrue, TEST_EXE_SELF_DLL, TEST_MEDIA_ALL, ETrue, 2, 16, TEST_DLL_FUNC, ETrue, ETrue, MEDMTHRE, TEST_RANDOM, ETrue, 0, }, //_L("Multiple thread with Low memory interleave, prio, multi media access and All media + loading."), }, sl@0: sl@0: }; sl@0: #define NUM_LOWMEM_TESTS (TInt)(sizeof(TheLowMemTests) / sizeof(TTheTests)) sl@0: sl@0: // sl@0: // DoLowMemTest sl@0: // sl@0: // Low Memory Test sl@0: // sl@0: void DoLowMemTest(TBool aEnableAllMedia = EFalse) sl@0: { sl@0: TInt r = User::LoadLogicalDevice(KPageStressTestLddName); sl@0: RUNTEST1(r==KErrNone || r==KErrAlreadyExists); sl@0: RUNTEST(PagestressLdd.Open(),KErrNone); sl@0: RUNTEST(PagestressLdd.DoSetDebugFlag((TInt)TestDebug),KErrNone); sl@0: sl@0: SVMCacheInfo tempPages; sl@0: memset(&tempPages, 0, sizeof(tempPages)); sl@0: if (TestIsDemandPaged) sl@0: { sl@0: // get the old cache info sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0); sl@0: TInt minSize = 8 * 4096; sl@0: TInt maxSize = 256 * 4096; sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); sl@0: } sl@0: sl@0: TInt testIndex; sl@0: TTheTests *pTest = &TheLowMemTests[0]; sl@0: for (testIndex = 0; testIndex < NUM_LOWMEM_TESTS; testIndex ++, pTest++) sl@0: { sl@0: if ( (!aEnableAllMedia && (pTest->testWhichMedia == TEST_MEDIA_ALL)) sl@0: || ((TestFullAutoTest == EFalse) && (pTest->testFullAutoOnly))) sl@0: { sl@0: continue; sl@0: } sl@0: sl@0: TestLoading = pTest->testLoading; sl@0: TestWhichMedia = pTest->testWhichMedia; sl@0: TestMaxLoops = pTest->testMaxLoops; sl@0: TestMultipleThreadCount = pTest->testMultipleThreadCount; sl@0: TestLoadDllHow = pTest->testLoadDllHow; sl@0: TestInterleave = pTest->testInterleave; sl@0: TestPrioChange = pTest->testPrioChange; sl@0: TestMediaAccess = pTest->testMediaAccess; sl@0: TestWhichTests = pTest->testWhichTests; sl@0: TestingLowMem = pTest->testLowMem; sl@0: if (!TestSilent) sl@0: { sl@0: test.Next(_L("Low Memory")); sl@0: } sl@0: if (pTest->testLowMem) sl@0: { sl@0: PagestressLdd.DoConsumeRamSetup(pTest->testFreeRam, TEST_LM_BLOCKSIZE); sl@0: } sl@0: sl@0: if (pTest->testMultiple) sl@0: { sl@0: RUNTEST(DoMultipleTest(pTest->testLowMem), KErrNone); sl@0: } sl@0: else sl@0: { sl@0: RUNTEST(DoSingleTest(pTest->testLowMem), KErrNone); sl@0: } sl@0: sl@0: if (pTest->testLowMem) sl@0: { sl@0: PagestressLdd.DoConsumeRamFinish(); sl@0: } sl@0: sl@0: DoStats(); sl@0: #ifdef TEST_KERN_HEAP sl@0: __KHEAP_MARK; sl@0: __KHEAP_CHECK(0); sl@0: __KHEAP_MARKEND; sl@0: #endif sl@0: } sl@0: sl@0: if (!TestSilent) sl@0: { sl@0: test.Next(_L("Close test driver")); sl@0: } sl@0: PagestressLdd.Close(); sl@0: RUNTEST(User::FreeLogicalDevice(KPageStressTestLddName), KErrNone); sl@0: sl@0: if (TestIsDemandPaged) sl@0: { sl@0: TInt minSize = tempPages.iMinSize; sl@0: TInt maxSize = tempPages.iMaxSize; sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); sl@0: } sl@0: sl@0: #ifdef TEST_KERN_HEAP sl@0: __KHEAP_MARK; sl@0: __KHEAP_CHECK(0); sl@0: __KHEAP_MARKEND; sl@0: #endif sl@0: TestingLowMem = EFalse; sl@0: sl@0: } sl@0: sl@0: // sl@0: // MultipleDefragThread sl@0: // sl@0: // Thread function, one created for each zone in a multiple thread test. sl@0: // sl@0: sl@0: LOCAL_C TInt MultipleDefragThread(TAny* aUseTb) sl@0: { sl@0: TInt numZones = 1; sl@0: TInt zoneId = (TInt)aUseTb; sl@0: sl@0: if (TestZoneCount > TEST_MAX_ZONE_THREADS) sl@0: { sl@0: numZones = TestZoneCount / TEST_MAX_ZONE_THREADS; sl@0: } sl@0: sl@0: while (1) sl@0: { sl@0: TInt index = 0; sl@0: TInt tempy = 0; sl@0: for (; index < numZones; index ++) sl@0: { sl@0: User::AfterHighRes(TEST_MAX_ZONE_THREADS*TickPeriod/4); sl@0: tempy = zoneId + (TEST_MAX_ZONE_THREADS * index); sl@0: if (tempy < (TInt)TestZoneCount) sl@0: { sl@0: RamstressLdd.DoMovePagesInZone(tempy); sl@0: } sl@0: if (TestDefragTestEnd) sl@0: break; sl@0: } sl@0: if (TestDefragTestEnd) sl@0: break; sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: // sl@0: // DoDefragAutoTest sl@0: // sl@0: // Call the auto tests whilst defraging in the background. sl@0: // sl@0: sl@0: void DoDefragAutoTest() sl@0: { sl@0: TUint localZoneCount = TestZoneCount; sl@0: if (TestZoneCount > TEST_MAX_ZONE_THREADS) sl@0: { sl@0: localZoneCount = TEST_MAX_ZONE_THREADS; sl@0: } sl@0: TInt size = (sizeof(RThread) * localZoneCount) sl@0: + (sizeof(TInt) * localZoneCount); sl@0: TUint8* pBuf = (TUint8*)User::AllocZ(size); sl@0: sl@0: test(pBuf != NULL); sl@0: RThread *pTheThreads = (RThread*)pBuf; sl@0: TInt *pThreadInUse = (TInt*)(pTheThreads + localZoneCount); sl@0: TInt ret; sl@0: TUint index; sl@0: for (index = 0; index < localZoneCount; index ++) sl@0: { sl@0: DBGS_PRINT((_L("%S : Starting Defrag Thread %d\n"), &TestNameBuffer, index)); sl@0: ret = pTheThreads[index].Create(KTestBlank,MultipleDefragThread,KDefaultStackSize,NULL,(TAny*) index); sl@0: if (ret == KErrNone) sl@0: { sl@0: pTheThreads[index].Resume(); sl@0: pThreadInUse[index] = 1; sl@0: } sl@0: else sl@0: { sl@0: DBGS_PRINT((_L("%S : Starting Defrag Thread Failed %d\n"), &TestNameBuffer, index)); sl@0: } sl@0: } sl@0: sl@0: // Do the full auto tests... sl@0: PerformAutoTest(TestIsDemandPaged); sl@0: sl@0: TestDefragTestEnd = ETrue; sl@0: RamstressLdd.DoSetEndFlag(1); sl@0: TBool anyUsed = ETrue; sl@0: sl@0: DBGS_PRINT((_L("%S : Waiting for Defrag Threads to exit...\n"), &TestNameBuffer)); sl@0: TUint killNext = User::TickCount(); sl@0: while(anyUsed) sl@0: { sl@0: anyUsed = EFalse; sl@0: sl@0: // walk through the thread list to check which are still alive. sl@0: for (index = 0; index < localZoneCount; index++) sl@0: { sl@0: if (pThreadInUse[index]) sl@0: { sl@0: if (pTheThreads[index].ExitType() != EExitPending) sl@0: { sl@0: if (pTheThreads[index].ExitType() == EExitPanic) sl@0: { sl@0: DBGS_PRINT((_L("%S : Defrag Thread %d Panic'd\n"), &TestNameBuffer, index)); sl@0: } sl@0: else sl@0: { sl@0: DBGS_PRINT((_L("%S : Defrag Thread %d Exited\n"), &TestNameBuffer, index)); sl@0: } sl@0: pTheThreads[index].Close(); sl@0: pThreadInUse[index] = EFalse; sl@0: } sl@0: else sl@0: { sl@0: anyUsed = ETrue; sl@0: TUint now = User::TickCount(); sl@0: TUint time = TUint((TUint64)(now-killNext)*(TUint64)TickPeriod/(TUint64)1000000); sl@0: const TUint killTimeStep = (TEST_DOT_PERIOD+9)/10; // 1/10th of a dot sl@0: if(time>TEST_DOT_PERIOD+killTimeStep) sl@0: { sl@0: killNext += killTimeStep*1000000/TickPeriod; sl@0: DBGS_PRINT((_L("%S : killing Defrag Thread %d\n"), &TestNameBuffer, index)); sl@0: pTheThreads[index].Kill(KErrNone); sl@0: pTheThreads[index].Close(); sl@0: pThreadInUse[index] = EFalse; sl@0: } sl@0: } sl@0: } sl@0: } sl@0: User::After(500000); sl@0: } sl@0: DBGS_PRINT((_L("%S : Defrag Threads exited...\n"), &TestNameBuffer)); sl@0: RamstressLdd.DoSetEndFlag(0); sl@0: User::Free(pBuf); sl@0: } sl@0: sl@0: // sl@0: // DoDefragTest sl@0: // sl@0: // Test the ram defrag code. sl@0: // sl@0: sl@0: void DoDefragTest(void) sl@0: { sl@0: SVMCacheInfo tempPages; sl@0: memset(&tempPages, 0, sizeof(tempPages)); sl@0: sl@0: test.Next(_L("Ram Defrag : Get the number of zones")); sl@0: // first get the number of zones sl@0: TInt ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneCount,&TestZoneCount,0); sl@0: if(ret==KErrNotSupported) sl@0: { sl@0: test.Next(_L("TESTS NOT RUN - Ram Defrag appears to not be supported.\n")); sl@0: return; sl@0: } sl@0: test(ret == KErrNone); sl@0: test(TestZoneCount != 0); sl@0: test.Printf(_L("RAM Zones (count=%u)\n"),TestZoneCount); sl@0: sl@0: // now get the config of each of the zones. sl@0: TUint index; sl@0: struct SRamZoneConfig config; sl@0: struct SRamZoneUtilisation util; sl@0: test.Next(_L("Ram Defrag : Get info about the zones")); sl@0: for (index = 0; index < TestZoneCount; index ++) sl@0: { sl@0: ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneConfig,(TAny*)index, (TAny*)&config); sl@0: test(ret == KErrNone); sl@0: test.Printf(_L("config : id=%d index=%d base=0x%08x end=0x%08x pages=%d pref=%d flags=0x%x\n"), sl@0: config.iZoneId,config.iZoneIndex,config.iPhysBase,config.iPhysEnd,config.iPhysPages, sl@0: config.iPref,config.iFlags); sl@0: sl@0: ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation,(TAny*)index, (TAny*)&util); sl@0: test(ret == KErrNone); sl@0: test.Printf(_L("usage : id=%d index=%d pages=%d free=%d unknown=%d fixed=%d move=%d discard=%d other=%d\n"), sl@0: util.iZoneId,util.iZoneIndex,util.iPhysPages,util.iFreePages, sl@0: util.iAllocUnknown,util.iAllocFixed,util.iAllocMovable,util.iAllocDiscardable,util.iAllocOther); sl@0: } sl@0: // Now test for zones out of range. sl@0: test.Next(_L("Ram Defrag : test out of range indexes")); sl@0: ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneConfig,(TAny*)(TestZoneCount + 1), (TAny*)&config); sl@0: test(ret != KErrNone); sl@0: ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation,(TAny*)(TestZoneCount + 1), (TAny*)&util); sl@0: test(ret != KErrNone); sl@0: sl@0: ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneConfig,(TAny*)-1, (TAny*)&config); sl@0: test(ret != KErrNone); sl@0: ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation,(TAny*)-1, (TAny*)&util); sl@0: test(ret != KErrNone); sl@0: test.Next(_L("Ram Defrag : test out of range enums")); sl@0: ret = UserSvr::HalFunction(EHalGroupRam,-1, 0, 0); sl@0: test(ret != KErrNone); sl@0: ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation + 1,0, 0); sl@0: test(ret != KErrNone); sl@0: sl@0: TInt r = User::LoadLogicalDevice(KRamStressTestLddName); sl@0: RUNTEST1(r==KErrNone || r==KErrAlreadyExists); sl@0: RUNTEST(RamstressLdd.Open(),KErrNone); sl@0: //TestDebug = ETrue; sl@0: RUNTEST(RamstressLdd.DoSetDebugFlag((TInt)TestDebug),KErrNone); sl@0: sl@0: test.Next(_L("Ram Defrag : set VM cache to stress free...")); sl@0: sl@0: if (TestIsDemandPaged) sl@0: { sl@0: // get the old cache info sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0); sl@0: sl@0: TInt minSize = 512 * 4096; sl@0: TInt maxSize = 32767 * 4096; sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); sl@0: } sl@0: sl@0: test.Next(_L("Ram Defrag : move all pages in all zone in 1 thread...")); sl@0: sl@0: for (index = 0; index < TestZoneCount; index ++) sl@0: { sl@0: test.Printf(_L("Ram Defrag : moving pages in zone %u\n"),index); sl@0: ret = RamstressLdd.DoMovePagesInZone(index); sl@0: if (ret != KErrNone) sl@0: { sl@0: test.Printf(_L("Ram Defrag : moving pages in zone failed %u err=%d\n"), index, ret); sl@0: } sl@0: } sl@0: sl@0: sl@0: test.Next(_L("Ram Defrag : Get info after test")); sl@0: for (index = 0; index < TestZoneCount; index ++) sl@0: { sl@0: ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation,(TAny*)index, (TAny*)&util); sl@0: test(ret == KErrNone); sl@0: test.Printf(_L("usage : id=%d index=%d pages=%d free=%d unknown=%d fixed=%d move=%d discard=%d other=%d\n"), sl@0: util.iZoneId,util.iZoneIndex,util.iPhysPages,util.iFreePages, sl@0: util.iAllocUnknown,util.iAllocFixed,util.iAllocMovable,util.iAllocDiscardable,util.iAllocOther); sl@0: } sl@0: sl@0: test.Next(_L("Ram Defrag : Page moving on multiple threads with auto test running.")); sl@0: sl@0: TestingDefrag = ETrue; sl@0: TestDefragTestEnd = EFalse; sl@0: sl@0: DoDefragAutoTest(); sl@0: TestingDefrag = EFalse; sl@0: /* sl@0: * End of test cleanup. sl@0: */ sl@0: sl@0: test.Next(_L("Ram Defrag : reset VM cache back to stressed.")); sl@0: if (TestIsDemandPaged) sl@0: { sl@0: TInt minSize = tempPages.iMinSize; sl@0: TInt maxSize = tempPages.iMaxSize; sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); sl@0: } sl@0: RamstressLdd.Close(); sl@0: test.Next(_L("Ram Defrag : Done")); sl@0: } sl@0: sl@0: // sl@0: // PerformExceptionThread sl@0: // sl@0: // Generate a Panic sl@0: // sl@0: sl@0: LOCAL_C TInt PerformExceptionThread(TAny* ) sl@0: { sl@0: User::AfterHighRes(1000000); sl@0: // this line will cause a Kern::Exec 0 !!! sl@0: test.Printf(_L("Hello World\n")); sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: // sl@0: // DoExceptionInAnotherThread sl@0: // sl@0: // Test the d_exc and minkda functionality with faulting processes. sl@0: // sl@0: sl@0: void DoExceptionInAnotherThread(void) sl@0: { sl@0: TRequestStatus theStatus; sl@0: RThread theThread; sl@0: sl@0: TInt ret = theThread.Create(KTestBlank,PerformExceptionThread,KDefaultStackSize,NULL,NULL); sl@0: test(ret == KErrNone); sl@0: theThread.Logon(theStatus); sl@0: RUNTEST1(theStatus == KRequestPending); sl@0: theThread.Resume(); sl@0: theThread.Close(); sl@0: User::WaitForRequest(theStatus); sl@0: } sl@0: sl@0: // sl@0: // DoTestD_Exc sl@0: // sl@0: // Test the d_exc and minkda functionality with faulting processes. sl@0: // sl@0: sl@0: TInt DoTestD_Exc() sl@0: { sl@0: if (!TestSilent) sl@0: { sl@0: test.Next(_L("DoTestD_Exc : d_exc check test.")); sl@0: } sl@0: DBGS_PRINT((_L("%S : DoTestD_Exc start...\n"), &TestNameBuffer)); sl@0: // first we need to spawn d_exc.exe sl@0: RProcess dexcProcess; sl@0: TInt ret = dexcProcess.Create(_L("d_exc.exe"),_L("-b")); sl@0: RUNTEST1(KErrNone == ret); sl@0: TRequestStatus dexcStatus; sl@0: dexcProcess.Logon(dexcStatus); sl@0: RUNTEST1(dexcStatus == KRequestPending); sl@0: dexcProcess.Resume(); sl@0: sl@0: DBGS_PRINT((_L("%S : DoTestD_Exc started d_exc.exe\n"), &TestNameBuffer)); sl@0: sl@0: DoExceptionInAnotherThread(); sl@0: sl@0: DBGS_PRINT((_L("%S : DoTestD_Exc test completed\n"), &TestNameBuffer)); sl@0: // check that d_exc and minkda don't die! sl@0: RUNTEST1(dexcProcess.ExitType() == EExitPending); sl@0: sl@0: DBGS_PRINT((_L("%S : DoTestD_Exc d_exc still running\n"), &TestNameBuffer)); sl@0: sl@0: // kill off d_exc! sl@0: dexcProcess.Kill(KErrNone); sl@0: dexcProcess.Close(); sl@0: User::WaitForRequest(dexcStatus); sl@0: DBGS_PRINT((_L("%S : DoTestD_Exc d_exc killed and exiting\n"), &TestNameBuffer)); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** sl@0: Get name of the hash file used for an EXE or DLL which has been sl@0: copied to writable media. sl@0: sl@0: @param aOrigName Name of EXE or DLL which has been copied to sl@0: writable media. This does not have to be sl@0: qualified because only the name and extension sl@0: are used. sl@0: @param aHashName On return this is set to the absolute filename sl@0: which should contain the file's hash. This sl@0: function does not create the file, or its containing sl@0: directory. sl@0: */ sl@0: sl@0: static void GetHashFileName(const TDesC& aOrigName, TDes& aHashName) sl@0: { sl@0: aHashName.Copy(KSysHash); sl@0: aHashName[0] = (TUint8) RFs::GetSystemDriveChar(); sl@0: const TParsePtrC ppc(aOrigName); sl@0: aHashName.Append(ppc.NameAndExt()); sl@0: } sl@0: sl@0: // sl@0: // HashFile sl@0: // take hash of files require full drive:/path/name.ext sl@0: // sl@0: sl@0: void HashFile(const TDesC& aFileName, RFs& aFs) sl@0: { sl@0: CSHA1* sha1 = CSHA1::NewL(); sl@0: CleanupStack::PushL(sha1); sl@0: sl@0: TBuf<50> hashfile; sl@0: hashfile = KSysHash; sl@0: hashfile[0] = (TUint8) RFs::GetSystemDriveChar(); sl@0: sl@0: TInt r = aFs.MkDirAll(hashfile); sl@0: RUNTEST1(r==KErrNone || r==KErrAlreadyExists); sl@0: sl@0: RFile fDest; sl@0: r = fDest.Open(aFs, aFileName, EFileRead | EFileStream); sl@0: if (r != KErrNone) sl@0: { sl@0: if (TestingReaper && (r == KErrInUse)) sl@0: { sl@0: TBool whinged = EFalse; sl@0: while (r == KErrInUse) sl@0: { sl@0: User::After(2000000); sl@0: if (!whinged) sl@0: { sl@0: DBGS_PRINT((_L("HashFile() retrying Open for %S (%d)\n"), &aFileName, r)); sl@0: whinged = ETrue; sl@0: } sl@0: r = fDest.Open(aFs, aFileName, EFileRead | EFileStream); sl@0: } sl@0: sl@0: } sl@0: else sl@0: { sl@0: DBGS_PRINT((_L("fDest.Open returned %d\n"), r)); sl@0: } sl@0: } sl@0: User::LeaveIfError(r); sl@0: CleanupClosePushL(fDest); sl@0: sl@0: TBool done; sl@0: TBuf8<512> content; sl@0: do sl@0: { sl@0: r = fDest.Read(content); sl@0: if (r!=KErrNone) sl@0: DBGS_PRINT((_L("fDest.Read returned %d\n"), r)); sl@0: User::LeaveIfError(r); sl@0: done = (content.Length() == 0); sl@0: if (! done) sl@0: sha1->Update(content); sl@0: } while (! done); sl@0: CleanupStack::PopAndDestroy(&fDest); sl@0: sl@0: // write hash to \sys\hash sl@0: TBuf8<SHA1_HASH> hashVal = sha1->Final(); sl@0: sl@0: TFileName fnSrc(aFileName); sl@0: GetHashFileName(aFileName, fnSrc); sl@0: RFile fHash; sl@0: r = fHash.Replace(aFs, fnSrc, EFileWrite | EFileStream); sl@0: if (r != KErrNone) sl@0: DBGS_PRINT((_L("fHash.Replace returned %d\n"), r)); sl@0: User::LeaveIfError(r); sl@0: CleanupClosePushL(fHash); sl@0: r = fHash.Write(hashVal); sl@0: if (r != KErrNone) sl@0: DBGS_PRINT((_L("fHash.Write returned %d\n"), r)); sl@0: User::LeaveIfError(r); sl@0: sl@0: CleanupStack::PopAndDestroy(2, sha1); sl@0: } sl@0: sl@0: // sl@0: // CopyFileToMMc sl@0: // sl@0: // Copy a file to the MMC card and create a hash of it. sl@0: // sl@0: sl@0: TInt CopyFileToMMc(RFs& aFs,CFileMan* aFileMan, TPtrC aPath, TPtrC aOldFilename, TPtrC aNewFilename) sl@0: { sl@0: TInt retVal = aFs.MkDirAll(aPath); sl@0: RUNTEST1(retVal==KErrNone || retVal==KErrAlreadyExists); sl@0: sl@0: TFileName newPath; sl@0: TFileName oldPath; sl@0: sl@0: oldPath.Format(_L("%S%S"),&KRomPath, &aOldFilename); sl@0: newPath.Format(_L("%S%S"),&aPath, &aNewFilename); sl@0: DBGD_PRINT((_L("Copying %S to %S\n"), &oldPath, &newPath)); sl@0: retVal = aFileMan->Copy(oldPath, newPath, CFileMan::EOverWrite); sl@0: if (retVal == KErrNone) sl@0: { sl@0: retVal = aFileMan->Attribs(newPath, KEntryAttNormal, KEntryAttReadOnly, 0); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("%S : Attribs failed (%d)\n"), &newPath, retVal)); sl@0: } sl@0: TEntry anEntry; sl@0: retVal = aFs.Entry(newPath, anEntry); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("%S : aFs.Entry failed (%d)\n"), &newPath, retVal)); sl@0: } sl@0: TRAPD(r, HashFile(newPath, aFs)); sl@0: RUNTEST1(r == KErrNone); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("Failed to copy file %d\n"), retVal)); sl@0: DBGD_PRINT((_L("%S : now %S (%d)\n"), &newPath, EXISTS(retVal), retVal)); sl@0: return retVal; sl@0: } sl@0: sl@0: // sl@0: // CopyAndFragmentFiles sl@0: // sl@0: // Copy the test files to a specified location edeavouring to fragment as much as possible. sl@0: // sl@0: sl@0: TBool CopyAndFragmentFiles(RFs& aFs,CFileMan* aFileMan, TPtrC aPath, ETestMediaType aMediaType) sl@0: { sl@0: TInt retVal = aFs.MkDirAll(aPath); sl@0: RUNTEST1(retVal==KErrNone || retVal==KErrAlreadyExists); sl@0: #define FILECOUNTMAX (PAGELDRTST_MAX_DLLS + 2) sl@0: RFile theInFiles[FILECOUNTMAX]; sl@0: RFile theOutFiles[FILECOUNTMAX]; sl@0: TInt inFileSize[FILECOUNTMAX]; sl@0: TInt inFilePos[FILECOUNTMAX]; sl@0: TBool fileOk[FILECOUNTMAX]; sl@0: sl@0: TInt index; sl@0: TFileName newPath; sl@0: TFileName oldPath; sl@0: sl@0: for (index = 0; index < FILECOUNTMAX; index ++) sl@0: { sl@0: inFileSize[index] = 0; sl@0: inFilePos[index] = 0; sl@0: fileOk[index] = EFalse; sl@0: sl@0: if (index < PAGELDRTST_MAX_DLLS) sl@0: { sl@0: oldPath.Format(_L("%S%S%d%S"), &KRomPath, &KDllBaseName, index, &TestPlExtNames[KTestMediaBase]); sl@0: newPath.Format(_L("%S%S%d%S"), &aPath, &KDllBaseName, index, &TestPlExtNames[aMediaType]); sl@0: } sl@0: else if (index < (PAGELDRTST_MAX_DLLS + 1)) sl@0: { sl@0: oldPath.Format(_L("%S%S"), &KRomPath, &TestPsExeNames[KTestMediaBase]); sl@0: newPath.Format(_L("%S%S"), &aPath, &TestPsExeNames[aMediaType]); sl@0: } sl@0: else sl@0: { sl@0: oldPath.Format(_L("%S%S"), &KRomPath, &TestPlExeNames[KTestMediaBase]); sl@0: newPath.Format(_L("%S%S"), &aPath, &TestPlExeNames[aMediaType]); sl@0: } sl@0: sl@0: retVal = theInFiles[index].Open(aFs, oldPath, EFileRead); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("%S : Failed to open for read (%d)\n"), &oldPath, retVal)); sl@0: break; sl@0: } sl@0: retVal = theInFiles[index].Size(inFileSize[index]); sl@0: if (retVal != KErrNone) sl@0: { sl@0: theInFiles[index].Close(); sl@0: DBGS_PRINT((_L("%S : Failed to get file size (%d)\n"), &newPath, retVal)); sl@0: break; sl@0: } sl@0: retVal = theOutFiles[index].Replace(aFs, newPath, EFileWrite); sl@0: if (retVal != KErrNone) sl@0: { sl@0: theInFiles[index].Close(); sl@0: DBGS_PRINT((_L("%S : Failed to open for write (%d)\n"), &newPath, retVal)); sl@0: break; sl@0: } sl@0: sl@0: fileOk[index] = ETrue; sl@0: } sl@0: sl@0: const TInt KBufferSize = 3333; sl@0: TBuf8<KBufferSize> buffer; sl@0: TBool stillGoing; sl@0: sl@0: do sl@0: { sl@0: stillGoing = EFalse; sl@0: for (index = 0; index < FILECOUNTMAX; index ++) sl@0: { sl@0: if (!fileOk[index]) sl@0: break; sl@0: if (inFilePos[index] < inFileSize[index]) sl@0: { sl@0: retVal = theInFiles[index].Read(buffer); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("theInFiles[%d] read failed (%d)\n"), index, retVal)); sl@0: break; sl@0: } sl@0: retVal = theOutFiles[index].Write(buffer); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("theOutFiles[%d] Write failed (%d)\n"), index, retVal)); sl@0: break; sl@0: } sl@0: retVal = theOutFiles[index].Flush(); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("theOutFiles[%d] flush failed (%d)\n"), index, retVal)); sl@0: break; sl@0: } sl@0: inFilePos[index] += buffer.Length(); sl@0: if (inFilePos[index] < inFileSize[index]) sl@0: stillGoing = ETrue; sl@0: } sl@0: } sl@0: } sl@0: while (stillGoing); sl@0: sl@0: TBool allOk = retVal == KErrNone; sl@0: for (index = 0; index < FILECOUNTMAX; index ++) sl@0: { sl@0: if (!fileOk[index]) sl@0: { sl@0: allOk = EFalse; sl@0: break; sl@0: } sl@0: theInFiles[index].Close(); sl@0: theOutFiles[index].Close(); sl@0: if (index < PAGELDRTST_MAX_DLLS) sl@0: { sl@0: newPath.Format(_L("%S%S%d%S"), &aPath, &KDllBaseName, index, &TestPlExtNames[aMediaType]); sl@0: } sl@0: else if (index < (PAGELDRTST_MAX_DLLS + 1)) sl@0: { sl@0: newPath.Format(_L("%S%S"), &aPath, &TestPsExeNames[aMediaType]); sl@0: } sl@0: else sl@0: { sl@0: newPath.Format(_L("%S%S"), &aPath, &TestPlExeNames[aMediaType]); sl@0: } sl@0: sl@0: retVal = aFileMan->Attribs(newPath, KEntryAttNormal, KEntryAttReadOnly, 0); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("%S : Attribs failed (%d)\n"), &newPath, retVal)); sl@0: allOk = EFalse; sl@0: } sl@0: TEntry anEntry; sl@0: retVal = aFs.Entry(newPath, anEntry); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("%S : aFs.Entry failed (%d)\n"), &newPath, retVal)); sl@0: allOk = EFalse; sl@0: } sl@0: TRAPD(r, HashFile(newPath, aFs)); sl@0: if (r != KErrNone) sl@0: { sl@0: allOk = EFalse; sl@0: } sl@0: DBGD_PRINT((_L("%S : %S!\n"), &newPath, EXISTS(!allOk))); sl@0: } sl@0: return allOk; sl@0: } sl@0: sl@0: // sl@0: // CheckFilePresence sl@0: // sl@0: // Checks all the files required for the test are present and copies some tests to the MMC card sl@0: // sl@0: sl@0: void CheckFilePresence(TBool aDoFileCopy) sl@0: { sl@0: TUint start = User::TickCount(); sl@0: sl@0: RFs fs; sl@0: if (KErrNone != fs.Connect()) sl@0: { sl@0: DBGS_PRINT(_L("CheckFilePresence : Can't connect to the FS\n")); sl@0: return ; sl@0: } sl@0: sl@0: TFileName filename; sl@0: TFileName newFilename; sl@0: TEntry anEntry; sl@0: TInt index; sl@0: TInt retVal; sl@0: TInt dllIndex; sl@0: sl@0: // now we need to add the MMC files sl@0: TInt drvNum = FindMMCDriveNumber(fs); sl@0: TBuf<32> mmcPath; sl@0: mmcPath.Format(_L("%S"),&KMmcDefaultPath); sl@0: if (drvNum >= 0) sl@0: mmcPath[0] = 'a' + drvNum; sl@0: sl@0: TBool allOk; sl@0: //TInt indexMax = aDoFileCopy ? KTestMediaMmc : KTestMediaCOUNT; sl@0: for (index = 0; index < TEST_MEDIA_COUNT_HACK; index ++) sl@0: { sl@0: allOk = ETrue; sl@0: filename.Format(_L("%S%S"),(index == KTestMediaMmc) ? & mmcPath : &KRomPath, &TestPsExeNames[index]); sl@0: if (KErrNone != fs.Entry(filename, anEntry)) sl@0: allOk = EFalse; sl@0: sl@0: filename.Format(_L("%S%S"),(index == KTestMediaMmc) ? & mmcPath : &KRomPath, &TestPlExeNames[index]); sl@0: if (KErrNone != fs.Entry(filename, anEntry)) sl@0: allOk = EFalse; sl@0: sl@0: for (dllIndex = 0; dllIndex < PAGELDRTST_MAX_DLLS; dllIndex ++) sl@0: { sl@0: filename.Format(_L("%S%S%d%S"), (index == KTestMediaMmc) ? & mmcPath : &KRomPath, &KDllBaseName, dllIndex, &TestPlExtNames[index]); sl@0: if (KErrNone != fs.Entry(filename, anEntry)) sl@0: allOk = EFalse; sl@0: } sl@0: TestDllExesExist[index] = allOk; sl@0: DBGS_PRINT((_L("%S : %S!\n"), &TestPsExeNames[index], EXISTS(!TestDllExesExist[index]))); sl@0: } sl@0: TInt nandDrvNum = FindFsNANDDrive(fs); sl@0: if (aDoFileCopy && (drvNum >= 0) && (nandDrvNum >= 0)) sl@0: { sl@0: CTrapCleanup* cleanupStack = CTrapCleanup::New(); sl@0: if(!cleanupStack) sl@0: DBGS_PRINT((_L("Cleanup stack failed\n"))); sl@0: CFileMan* pFileMan = NULL; sl@0: TRAP(retVal, pFileMan = CFileMan::NewL(fs)); sl@0: sl@0: // First make a clean copy of the DLLs to the MMC card. sl@0: allOk = ETrue; sl@0: if (KErrNone != CopyFileToMMc(fs, pFileMan, mmcPath, TestPsExeNames[KTestMediaBase], TestPsExeNames[KTestMediaMmc])) sl@0: allOk = EFalse; sl@0: if (KErrNone != CopyFileToMMc(fs, pFileMan, mmcPath, TestPlExeNames[KTestMediaBase], TestPlExeNames[KTestMediaMmc])) sl@0: allOk = EFalse; sl@0: for (dllIndex = 0; dllIndex < PAGELDRTST_MAX_DLLS; dllIndex ++) sl@0: { sl@0: filename.Format(_L("%S%d%S"), &KDllBaseName, dllIndex, &TestPlExtNames[KTestMediaBase]); sl@0: newFilename.Format(_L("%S%d%S"), &KDllBaseName, dllIndex, &TestPlExtNames[KTestMediaMmc]); sl@0: if (KErrNone != CopyFileToMMc(fs, pFileMan, mmcPath, filename, newFilename)) sl@0: allOk = EFalse; sl@0: } sl@0: TestDllExesExist[KTestMediaMmc] = allOk; sl@0: DBGS_PRINT((_L("%S : %S! (Drive %c)\n"), &TestPsExeNames[index], EXISTS(!TestDllExesExist[index]), mmcPath[0])); sl@0: #ifdef TEST_ADD_FRAGD_MEDIA sl@0: //now make some fragmented files on the MMC card. sl@0: TestDllExesExist[KTestMediaMmcFrag] = CopyAndFragmentFiles(fs, pFileMan, mmcPath, KTestMediaMmcFrag); sl@0: DBGS_PRINT((_L("%S : %S! (Drive %c)\n"), &TestPsExeNames[KTestMediaMmcFrag], EXISTS(!TestDllExesExist[KTestMediaMmcFrag]), mmcPath[0])); sl@0: sl@0: //now make some fragmented files on the NAND card. sl@0: if (nandDrvNum >= 0) sl@0: { sl@0: mmcPath[0] = 'a' + nandDrvNum; sl@0: TestDllExesExist[KTestMediaNandFrag] = CopyAndFragmentFiles(fs, pFileMan, mmcPath, KTestMediaNandFrag); sl@0: DBGS_PRINT((_L("%S : %S! (Drive %c)\n"), &TestPsExeNames[KTestMediaNandFrag], EXISTS(!TestDllExesExist[KTestMediaNandFrag]), mmcPath[0])); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("CheckFilePresence : Failed to get NAND drive number\n"))); sl@0: #endif // TEST_ADD_FRAGD_MEDIA sl@0: delete pFileMan; pFileMan = NULL; sl@0: delete cleanupStack; cleanupStack = NULL; sl@0: } sl@0: sl@0: fs.Close(); sl@0: sl@0: TUint end = User::TickCount(); sl@0: TUint time = TUint((TUint64)(end-start)*(TUint64)TickPeriod/(TUint64)1000000); sl@0: DBGS_PRINT((_L("CheckFilePresence : %d secs elapsed\n"), time)); sl@0: } sl@0: sl@0: // sl@0: // DoDeleteFile sl@0: // sl@0: // Delete a file and remove the hash sl@0: // sl@0: sl@0: void DoDeleteFile(CFileMan* aFileMan, TBool aSilent,TFileName& aFileName ) sl@0: { sl@0: TFileName hashName; sl@0: RLoader l; sl@0: test(l.Connect() == KErrNone); sl@0: sl@0: DBGD_PRINT((_L("Deleting %S ...\n"), &aFileName)); sl@0: if (!aSilent) sl@0: DBGD_PRINT((_L("Deleting %S\n"), &aFileName)); sl@0: TInt retVal = aFileMan->Delete(aFileName); sl@0: if (retVal != KErrNone) sl@0: { sl@0: if (TestingReaper) sl@0: { sl@0: aFileMan->Attribs(aFileName, KEntryAttNormal, KEntryAttReadOnly, 0); sl@0: retVal = l.Delete(aFileName); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("RLoader::Delete %S Failed %d\n"), &aFileName, retVal)); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if (!aSilent) sl@0: DBGS_PRINT((_L("Deleting %S Failed %d\n"), &aFileName, retVal)); sl@0: } sl@0: } sl@0: GetHashFileName(aFileName, hashName); sl@0: retVal = aFileMan->Delete(hashName); sl@0: if (retVal != KErrNone) sl@0: { sl@0: if (TestingReaper && (retVal == KErrInUse)) sl@0: { sl@0: retVal = l.Delete(hashName); sl@0: if (retVal != KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("RLoader::Delete %S Failed %d\n"), &hashName, retVal)); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if (!aSilent) sl@0: DBGS_PRINT((_L("Deleting %S Failed %d\n"), &hashName, retVal)); sl@0: } sl@0: } sl@0: l.Close(); sl@0: } sl@0: sl@0: // sl@0: // CleanupFiles sl@0: // sl@0: // Remove any copied files and created directories. sl@0: // sl@0: sl@0: void CleanupFiles(TBool silent) sl@0: { sl@0: TUint start = User::TickCount(); sl@0: sl@0: RFs fs; sl@0: if (KErrNone != fs.Connect()) sl@0: { sl@0: DBGS_PRINT(_L("CleanupFiles : Can't connect to the FS\n")); sl@0: return ; sl@0: } sl@0: sl@0: CTrapCleanup* cleanupStack = CTrapCleanup::New(); sl@0: if(!cleanupStack) sl@0: if (!silent) sl@0: DBGS_PRINT((_L("Cleanup stack failed\n"))); sl@0: sl@0: CFileMan* pFileMan = NULL; sl@0: TInt retVal; sl@0: TRAP(retVal, pFileMan = CFileMan::NewL(fs)); sl@0: sl@0: TFileName newPath; sl@0: TInt index; sl@0: TInt dllIndex; sl@0: sl@0: TBuf<32> path; sl@0: path.Format(_L("%S"),&KMmcDefaultPath); sl@0: TInt mmcDrvNum = FindMMCDriveNumber(fs); sl@0: TInt nandDrvNum = FindFsNANDDrive(fs); sl@0: for (index = KTestMediaMmc; index < KTestMediaCOUNT; index ++) sl@0: { sl@0: #ifdef TEST_ADD_FRAGD_MEDIA sl@0: if (index == KTestMediaNandFrag) sl@0: { sl@0: if (nandDrvNum < 0) sl@0: continue; sl@0: path[0] = 'a' + nandDrvNum; sl@0: } sl@0: else sl@0: { sl@0: if (mmcDrvNum < 0) sl@0: continue; sl@0: path[0] = 'a' + mmcDrvNum; sl@0: } sl@0: #else sl@0: path[0] = 'a' + mmcDrvNum; sl@0: #endif sl@0: newPath.Format(_L("%S%S"),&path, &TestPsExeNames[index]); sl@0: DoDeleteFile(pFileMan, silent, newPath); sl@0: sl@0: newPath.Format(_L("%S%S"),&path, &TestPlExeNames[index]); sl@0: DoDeleteFile(pFileMan, silent, newPath); sl@0: sl@0: for (dllIndex = 0; dllIndex < PAGELDRTST_MAX_DLLS; dllIndex ++) sl@0: { sl@0: newPath.Format(_L("%S%S%d%S"), &path, &KDllBaseName, dllIndex, &TestPlExtNames[index]); sl@0: DoDeleteFile(pFileMan, silent, newPath); sl@0: } sl@0: } sl@0: if (nandDrvNum >= 0) sl@0: { sl@0: path[0] = 'a' + nandDrvNum; sl@0: fs.RmDir(path); sl@0: } sl@0: if (mmcDrvNum >= 0) sl@0: { sl@0: path[0] = 'a' + mmcDrvNum; sl@0: fs.RmDir(path); sl@0: } sl@0: sl@0: delete pFileMan; pFileMan = NULL; sl@0: delete cleanupStack; cleanupStack = NULL; sl@0: fs.Close(); sl@0: TUint end = User::TickCount(); sl@0: TUint time = TUint((TUint64)(end-start)*(TUint64)TickPeriod/(TUint64)1000000); sl@0: DBGS_PRINT((_L("CleanupFiles : %d secs elapsed\n"), time)); sl@0: } sl@0: sl@0: #ifdef _DEBUG sl@0: sl@0: // sl@0: // FindLocalDriveNumber sl@0: // sl@0: // Find the local drive sl@0: // sl@0: sl@0: TInt FindLocalDriveNumber(RFs &aFs, TInt aFsDrvNum) sl@0: { sl@0: RFile file; sl@0: TBuf<256> fileName; sl@0: fileName.Append((TChar)('A' + aFsDrvNum)); sl@0: fileName+=_L(":\\f32-tst\\"); sl@0: TInt r=aFs.MkDirAll(fileName); sl@0: TInt locDriveNumber = -1; sl@0: if (r==KErrNone || r== KErrAlreadyExists) sl@0: { sl@0: fileName += _L("tempy.txt"); sl@0: r=file.Replace(aFs,fileName,EFileWrite); sl@0: if (r!=KErrNone) sl@0: DBGS_PRINT((_L("FindLocalDriveNumber : Error %d: file '%S' could not be created\n"),r,&fileName)); sl@0: RUNTEST1(r==KErrNone); sl@0: r=file.Write(_L8("Flies as big as sparrows indoletly buzzing in the warm air, heavy with the stench of rotting carcasses")); sl@0: if (r!=KErrNone) sl@0: { sl@0: DBGS_PRINT((_L("FindLocalDriveNumber : Error %d: could not write to file %d (%S)\n"),r,aFsDrvNum, &fileName)); sl@0: } sl@0: else sl@0: { sl@0: // write caching may be enabled to flush the cache... sl@0: TRequestStatus flushStatus; sl@0: file.Flush(flushStatus); sl@0: User::WaitForRequest(flushStatus); sl@0: // get the block map sl@0: SBlockMapInfo info; sl@0: TInt64 start=0; sl@0: r=file.BlockMap(info, start, -1,ETestDebug); sl@0: if (r==KErrNone || r==KErrCompletion) sl@0: { sl@0: locDriveNumber=info.iLocalDriveNumber; sl@0: DBGD_PRINT((_L("FindLocalDriveNumber : locDriveNumber %d\n"), locDriveNumber)); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("FindLocalDriveNumber : Error %d: error getting blockmap for drive %d (%S)\n"),r,aFsDrvNum, &fileName)); sl@0: } sl@0: aFs.Delete(fileName); sl@0: file.Close(); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("FindLocalDriveNumber : Error %d: error creating dir \n"),r)); sl@0: return locDriveNumber; sl@0: } sl@0: sl@0: // sl@0: // ResetConcurrencyStats sl@0: // sl@0: // Reset the stats sl@0: // sl@0: sl@0: void ResetConcurrencyStats(RFs& aFs) sl@0: { sl@0: if(TestBootedFromMmc) sl@0: { sl@0: TInt fsDriveNum = FindMMCDriveNumber(aFs); sl@0: if (fsDriveNum >= 0) sl@0: { sl@0: TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum); sl@0: if (locDriveNumber >= 0) sl@0: { sl@0: RUNTEST(PagingInfo::ResetConcurrency(locDriveNumber,EMediaPagingStatsRomAndCode),KErrNone); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("ResetConcurrencyStats MMC : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum)); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("ResetConcurrencyStats MMC : Failed to get fsDriveNum %d\n"), fsDriveNum)); sl@0: } sl@0: else sl@0: { sl@0: TInt fsDriveNum = FindFsNANDDrive(aFs); sl@0: if (fsDriveNum >= 0) sl@0: { sl@0: TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum); sl@0: if (locDriveNumber >= 0) sl@0: { sl@0: RUNTEST(PagingInfo::ResetConcurrency(locDriveNumber,EMediaPagingStatsRomAndCode),KErrNone); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("ResetConcurrencyStats NAND : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum)); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("ResetConcurrencyStats NAND : Failed to get fsDriveNum %d\n"), fsDriveNum)); sl@0: } sl@0: } sl@0: sl@0: // sl@0: // ResetBenchmarks sl@0: // sl@0: // Reset the stats sl@0: // sl@0: sl@0: void ResetBenchmarks(RFs& aFs) sl@0: { sl@0: if(TestBootedFromMmc) sl@0: { sl@0: TInt fsDriveNum = FindMMCDriveNumber(aFs); sl@0: if (fsDriveNum >= 0) sl@0: { sl@0: TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum); sl@0: if (locDriveNumber >= 0) sl@0: { sl@0: RUNTEST(PagingInfo::ResetBenchmarks(locDriveNumber,EMediaPagingStatsRomAndCode),KErrNone); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("ResetBenchmarks MMC : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum)); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("ResetBenchmarks MMC : Failed to get fsDriveNum %d\n"), fsDriveNum)); sl@0: } sl@0: else sl@0: { sl@0: TInt fsDriveNum = FindFsNANDDrive(aFs); sl@0: if (fsDriveNum >= 0) sl@0: { sl@0: TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum); sl@0: if (locDriveNumber >= 0) sl@0: { sl@0: RUNTEST(PagingInfo::ResetBenchmarks(locDriveNumber,EMediaPagingStatsRomAndCode),KErrNone); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("ResetBenchmarks NAND : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum)); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("ResetBenchmarks NAND : Failed to get fsDriveNum %d\n"), fsDriveNum)); sl@0: } sl@0: } sl@0: sl@0: // sl@0: // DisplayConcurrencyStats sl@0: // sl@0: // Display the stats sl@0: // sl@0: sl@0: void DisplayConcurrencyStats(RFs& aFs) sl@0: { sl@0: if(TestBootedFromMmc) sl@0: { sl@0: TInt fsDriveNum = FindMMCDriveNumber(aFs); sl@0: if (fsDriveNum >= 0) sl@0: { sl@0: TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum); sl@0: if (locDriveNumber >= 0) sl@0: { sl@0: DBGS_PRINT((_L("MMC stats\n"))); sl@0: RUNTEST1(PagingInfo::PrintConcurrency(locDriveNumber,EMediaPagingStatsRomAndCode)==KErrNone); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("DisplayConcurrencyStats MMC : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum)); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("DisplayConcurrencyStats MMC : Failed to get fsDriveNum %d\n"), fsDriveNum)); sl@0: } sl@0: else sl@0: { sl@0: TInt fsDriveNum = FindFsNANDDrive(aFs); sl@0: if (fsDriveNum >= 0) sl@0: { sl@0: TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum); sl@0: sl@0: if (locDriveNumber >= 0) sl@0: { sl@0: DBGS_PRINT((_L("NAND stats\n"))); sl@0: RUNTEST1(PagingInfo::PrintConcurrency(locDriveNumber,EMediaPagingStatsRomAndCode)==KErrNone); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("DisplayConcurrencyStats NAND : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum)); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("DisplayConcurrencyStats NAND : Failed to get fsDriveNum %d\n"), fsDriveNum)); sl@0: } sl@0: } sl@0: sl@0: void DisplayBenchmarks(RFs& aFs) sl@0: { sl@0: if(TestBootedFromMmc) sl@0: { sl@0: TInt fsDriveNum = FindMMCDriveNumber(aFs); sl@0: if (fsDriveNum >= 0) sl@0: { sl@0: TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum); sl@0: if(locDriveNumber>=0) sl@0: { sl@0: DBGS_PRINT((_L("MMC benchmarks\n"))); sl@0: RUNTEST1(PagingInfo::PrintBenchmarks(locDriveNumber,EMediaPagingStatsRomAndCode)==KErrNone); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("DisplayBenchmarks MMC : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum)); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("DisplayBenchmarks MMC : Failed to get fsDriveNum %d\n"), fsDriveNum)); sl@0: } sl@0: else sl@0: { sl@0: TInt fsDriveNum = FindFsNANDDrive(aFs); sl@0: if (fsDriveNum >= 0) sl@0: { sl@0: TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum); sl@0: if(locDriveNumber>=0) sl@0: { sl@0: DBGS_PRINT((_L("NAND benchmarks\n"))); sl@0: RUNTEST1(PagingInfo::PrintBenchmarks(locDriveNumber,EMediaPagingStatsRomAndCode)==KErrNone); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("DisplayBenchmarks NAND : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum)); sl@0: } sl@0: else sl@0: DBGS_PRINT((_L("DisplayBenchmarks NAND : Failed to get fsDriveNum %d\n"), fsDriveNum)); sl@0: } sl@0: } sl@0: sl@0: #endif sl@0: sl@0: void DoStats() sl@0: { sl@0: if (TestIsDemandPaged) sl@0: { sl@0: SVMCacheInfo tempPages; sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0); sl@0: DBGS_PRINT((_L("DPC : min %d max %d curr %d\n"), sl@0: tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize)); sl@0: DBGS_PRINT((_L(" : maxFree %d freeRam %d\n"), sl@0: tempPages.iMaxFreeSize, FreeRam())); sl@0: } sl@0: sl@0: #ifdef _DEBUG sl@0: if (TestWeAreTheTestBase && !TestSilent) sl@0: { sl@0: RFs fs; sl@0: if (KErrNone != fs.Connect()) sl@0: { sl@0: DBGS_PRINT(_L("ResetConcurrencyStats : Can't connect to the FS\n")); sl@0: return; sl@0: } sl@0: sl@0: #ifndef TEST_MINIMAL_STATS sl@0: DisplayConcurrencyStats(fs); sl@0: DisplayBenchmarks(fs); sl@0: #endif sl@0: #ifndef TEST_DONT_RESET_STATS sl@0: ResetConcurrencyStats(fs); sl@0: ResetBenchmarks(fs); sl@0: #endif sl@0: fs.Close(); sl@0: } sl@0: #endif sl@0: } sl@0: sl@0: sl@0: // sl@0: // E32Main sl@0: // sl@0: // Main entry point. sl@0: // sl@0: sl@0: TInt E32Main() sl@0: { sl@0: #ifndef TEST_ON_UNPAGED sl@0: TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress(); sl@0: if(!romHeader->iPageableRomStart) sl@0: { sl@0: TestIsDemandPaged = EFalse; sl@0: } sl@0: #endif sl@0: // Turn off lazy dll unloading sl@0: RLoader l; sl@0: if (l.Connect() == KErrNone) sl@0: { sl@0: l.CancelLazyDllUnload(); sl@0: l.Close(); sl@0: } sl@0: sl@0: HAL::Get(HAL::ESystemTickPeriod, TickPeriod); sl@0: sl@0: SVMCacheInfo tempPages; sl@0: memset(&tempPages, 0, sizeof(tempPages)); sl@0: sl@0: TBool parseResult = ParseCommandLine(); sl@0: sl@0: if (TestExit) sl@0: { sl@0: return KErrNone; sl@0: } sl@0: sl@0: TUint start = User::TickCount(); sl@0: sl@0: AreWeTheTestBase(); sl@0: sl@0: if (TestIsDemandPaged) sl@0: { sl@0: TInt minSize = TestMinCacheSize; sl@0: TInt maxSize = TestMaxCacheSize; sl@0: sl@0: SVMCacheInfo tempPages; sl@0: sl@0: // get the old cache info sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0); sl@0: // set the cache to our test value sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); sl@0: } sl@0: if (!TestSilent) sl@0: { sl@0: test.Title(); sl@0: test.Start(_L("Demand Paging loader stress tests...")); sl@0: test.Printf(_L("%S (%d)\n"), &TestNameBuffer, TestWeAreTheTestBase); sl@0: test.Printf(_L("TestBootedFromMmc %d\n"), TestBootedFromMmc); sl@0: sl@0: if (TestWeAreTheTestBase) sl@0: CleanupFiles(ETrue); sl@0: sl@0: CheckFilePresence(TestWeAreTheTestBase); sl@0: } sl@0: sl@0: if (parseResult) sl@0: { sl@0: if (TestLowMem) sl@0: { sl@0: DoLowMemTest(ETrue); sl@0: } sl@0: if (TestSingle) sl@0: { sl@0: RUNTEST(DoSingleTest(),KErrNone); sl@0: } sl@0: if (TestMultiple) sl@0: { sl@0: RUNTEST(DoMultipleTest(),KErrNone); sl@0: } sl@0: if (TestD_Exc) sl@0: { sl@0: RUNTEST(DoTestD_Exc(),KErrNone); sl@0: } sl@0: if (TestChunks) sl@0: { sl@0: DoChunkTests(); sl@0: } sl@0: if (TestReaper) sl@0: { sl@0: DoReaperTests(); sl@0: } sl@0: if (TestBtrace) sl@0: { sl@0: DoBtraceTest(); sl@0: } sl@0: if (TestDefrag) sl@0: { sl@0: DoDefragTest(); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: #ifdef _DEBUG sl@0: if (TestWeAreTheTestBase) sl@0: { sl@0: RFs fs; sl@0: if (KErrNone == fs.Connect()) sl@0: { sl@0: //fs.SetDebugRegister(KCACHE); sl@0: ResetConcurrencyStats(fs); sl@0: ResetBenchmarks(fs); sl@0: fs.Close(); sl@0: } sl@0: } sl@0: #endif sl@0: sl@0: while (1) sl@0: { sl@0: if (TestIsDemandPaged) sl@0: { sl@0: #ifdef TEST_RUN_AUTOTEST sl@0: PerformAutoTest(); sl@0: #endif //TEST_RUN_AUTOTEST sl@0: sl@0: #ifndef TEST_SHORT_TEST sl@0: #ifdef TEST_RUN_LOWMEMTEST sl@0: DoLowMemTest(ETrue); sl@0: #endif //TEST_RUN_LOWMEMTEST sl@0: #ifdef TEST_RUN_CHUNKTEST sl@0: DoChunkTests(); sl@0: #endif //TEST_RUN_CHUNKTEST sl@0: #ifdef TEST_RUN_REAPERTEST sl@0: DoReaperTests(); sl@0: #endif //TEST_RUN_REAPERTEST sl@0: #endif //TEST_SHORT_TEST sl@0: } sl@0: sl@0: #ifdef TEST_RUN_DEFRAGTEST sl@0: DoDefragTest(); sl@0: #endif //TEST_RUN_DEFRAGTEST sl@0: sl@0: if (TestStressFree) sl@0: { sl@0: TInt minSize = 512 * 4096; sl@0: TInt maxSize = 32767 * 4096; sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); sl@0: sl@0: test.Printf(_L("%S Stress Free!!\n"), &TestNameBuffer, TestWeAreTheTestBase); sl@0: TestStressFree = EFalse; sl@0: } sl@0: else sl@0: { sl@0: break; sl@0: } sl@0: } sl@0: sl@0: #ifndef TEST_SHORT_TEST sl@0: #ifndef TEST_NO_DEXC_IN_AUTO sl@0: #ifdef TEST_RUN_D_EXCTEST sl@0: RUNTEST(DoTestD_Exc(),KErrNone); sl@0: #endif //TEST_RUN_D_EXCTEST sl@0: #endif //TEST_NO_DEXC_IN_AUTO sl@0: if (TestWeAreTheTestBase && TestFullAutoTest && TestIsDemandPaged) sl@0: { sl@0: RProcess theProcess; sl@0: TRequestStatus status; sl@0: sl@0: TInt retVal = theProcess.Create(_L("t_pageldrtst_rom.exe"),_L("fullauto")); sl@0: if (retVal != KErrNotFound) sl@0: { sl@0: RUNTEST1(KErrNone == retVal); sl@0: theProcess.Logon(status); sl@0: RUNTEST1(status == KRequestPending); sl@0: theProcess.Resume(); sl@0: #ifdef TEST_THRASHING_TEST sl@0: while (1) sl@0: { sl@0: if (theProcess.ExitType() != EExitPending) sl@0: { sl@0: RUNTEST1(theProcess.ExitType() != EExitPanic); sl@0: break; sl@0: } sl@0: User::AfterHighRes(1); sl@0: } sl@0: User::WaitForRequest(status); sl@0: #else sl@0: User::WaitForRequest(status); sl@0: if (theProcess.ExitType() != EExitPending) sl@0: { sl@0: RUNTEST1(theProcess.ExitType() != EExitPanic); sl@0: } sl@0: #endif //TEST_THRASHING_TEST sl@0: theProcess.Close(); sl@0: } sl@0: } sl@0: #endif //TEST_SHORT_TEST sl@0: #ifdef _DEBUG sl@0: if (TestWeAreTheTestBase && !TestSilent) sl@0: { sl@0: RFs fs; sl@0: if (KErrNone == fs.Connect()) sl@0: { sl@0: DisplayConcurrencyStats(fs); sl@0: DisplayBenchmarks(fs); sl@0: fs.Close(); sl@0: } sl@0: } sl@0: #endif sl@0: } sl@0: sl@0: if (TestWeAreTheTestBase && !TestNoClean) sl@0: CleanupFiles(EFalse); sl@0: sl@0: if (TestIsDemandPaged) sl@0: { sl@0: TInt minSize = tempPages.iMinSize; sl@0: TInt maxSize = tempPages.iMaxSize; sl@0: // put the cache back to the the original values. sl@0: UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); sl@0: } sl@0: if (!TestSilent) sl@0: { sl@0: TUint end = User::TickCount(); sl@0: TUint time = TUint((TUint64)(end-start)*(TUint64)TickPeriod/(TUint64)1000000); sl@0: test.Printf(_L("%S : Complete (%u seconds)\n"), &TestNameBuffer, time); sl@0: test.End(); sl@0: } sl@0: return KErrNone; sl@0: }