os/kernelhwsrv/kerneltest/f32test/demandpaging/loader/t_pageldrtst.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // f32test\demandpaging\loader\t_pageldrtst.cpp
    15 // Demand Paging Loader Stress Tests
    16 // Demand Paging Loader stress tests attempt to cause as much paging as possible
    17 // whilst putting the system various types of load.
    18 // t_pageldrtst.exe is the root of the tests, it in turn will start copies of 
    19 // itself stored in various types of media (t_pageldrtst_rom.exe for example).
    20 // It also loads DLLs from various media, each DLL containing simple functions 
    21 // that are aligned on page boundaries, so each function call is likely to 
    22 // cause a page fault.
    23 // Usage:
    24 // t_pageldrtst and t_pageldrtst_rom
    25 // Common command lines:
    26 // t_pageldrtst - run the auto test suite
    27 // t_pageldrtst lowmem - run the low memory tests
    28 // t_pageldrtst chunks - run the chunk tests
    29 // t_pageldrtst chunks+ - run the chunk tests (same as used in autotest)
    30 // t_pageldrtst echunks - run the really stressful chunk tests
    31 // t_pageldrtst auto debug - run the autotest but with debug output to the serial port
    32 // t_pageldrtst d_exc - run the d_exc tests
    33 // Arguments:
    34 // single - run the tests in a single thread
    35 // multiple <numThreads> - run the tests in multiple threads where <numThreads>
    36 // auto - dummy param to trick the tests into running the auto test suite with extra params
    37 // fullauto - param to make the tests perform the full automatic stress test
    38 // interleave - force thread interleaving
    39 // prio - each thread reschedules in between each function call, causes lots of context changes
    40 // media - perform media access during the tests, very stressful
    41 // mmc - only use the mmc media for media access to test file caching
    42 // min - min cache size in pages
    43 // max - max cache size in pages
    44 // chunks - simple chunk stress tests
    45 // chunks+ - the chunk auto tests
    46 // echunks - extremem chunks tests
    47 // nochunkdata - don't check the integrity of the data in the chunks
    48 // lowmem - low memory tests
    49 // dll - only load dll's
    50 // exe - only start exe's (t_pagestress)
    51 // self - only start copies of self (t_pageldrtst from various media)
    52 // complete - dll, exe and self.
    53 // rom - only load from ROM
    54 // base - only load the base DLL and exe's (from code)
    55 // mixed - rom and base.
    56 // all_media - load dlls and exes from all media
    57 // debug - switch on debugging information
    58 // silent - no output to the screen or serial port
    59 // noclean - don't delete copied files on exit
    60 // d_exc - run the d_exc tests
    61 // global - load dlls once globally
    62 // thread - load dlls once per thread
    63 // func - load dlls in the test function (default and most stressful)
    64 // forward - patern in which to execute function calls 
    65 // backward - patern in which to execute function calls 			
    66 // random - patern in which to execute function calls 			
    67 // all - patern in which to execute function calls (forward, backward and random)
    68 // inst - for debugging a parameter passed to a spawned exe to give it an id.
    69 // iters <count> - the number of times to loop (a '-' means run forever)
    70 // reaper - test the reaper.
    71 // btrace - test the btrace code.
    72 // defrag - test the ram defrag code.
    73 // stressfree - set the page cache to stress free size and run tests.
    74 // t_pageldrtst causes a large ammount of paging by repeatedly calling 
    75 // functions from multiple DLLs which include 64 functions which have 
    76 // been aligned on page boundaries from multiple threads, whilst causing 
    77 // background paging by spawning copies of itself and t_pagestress.
    78 // The test also endeavours to stress the loader by loading and unloading
    79 // DLLs from multiple threads from various types of media at the same 
    80 // time as stressing the media, testing chunks, the reaper and changing
    81 // thread priorities.
    82 // 002 Load thrashing, test rapid loading and unloading of DLLs from 
    83 // multiple threads (DEF100158)
    84 // 003 Multiple threads loading DLLs in random pattern
    85 // 004 Multiple threads loading EXE, SELF and DLLs in random pattern with
    86 // all media, loaded in thread with prio change
    87 // 005 Multiple threads loading EXE, SELF and DLLs in random pattern with
    88 // all media, loaded globally with prio change
    89 // 006 Multiple threads loading EXE, SELF and DLLs in random pattern with
    90 // all media, loaded in func with process interleaving
    91 // 007 Multiple threads loading EXE, SELF and DLLs in random pattern with
    92 // all media, loaded in func with process interleaving, prio change
    93 // and media access
    94 // 008 Low Memory setup test
    95 // 009 Low Memory, Multiple threads loading EXE, SELF and DLLs in random 
    96 // pattern, loaded in func.
    97 // 010 Low Memory setup test
    98 // 011 Low Memory, Multiple threads loading EXE, SELF and DLLs in random 
    99 // pattern, loaded in func with process interleaving, 
   100 // prio change and media access
   101 // 012 Close test driver
   102 // 013 Chunk tests, Multiple threads loading EXE, SELF and DLLs in random 
   103 // pattern with ROM / ROFS media, loaded in func with prio change 
   104 // 014 Reaper tests with Multiple threads loading EXE, SELF and DLLs in random 
   105 // pattern with all media 
   106 // 015 Reaper tests with Multiple threads loading EXE, SELF and DLLs in random 
   107 // pattern with all media, prio change and process interleaving
   108 // 016 d_exc check test
   109 // 
   110 //
   111 
   112 //! @SYMTestCaseID			KBASE-T_PAGELDRTST-0326
   113 //! @SYMTestType			UT
   114 //! @SYMPREQ				PREQ1110
   115 //! @SYMTestCaseDesc		Demand Paging Loader Stress Tests
   116 //! @SYMTestActions			001 Demand Paging loader stress tests...
   117 //! @SYMTestExpectedResults All tests should pass.
   118 //! @SYMTestPriority        High
   119 //! @SYMTestStatus          Implemented
   120 
   121 #include <e32test.h>
   122 #include <e32rom.h>
   123 #include <e32svr.h>
   124 #include <u32hal.h>
   125 #include <f32file.h>
   126 #include <f32dbg.h>
   127 #include <e32msgqueue.h>
   128 #include <e32math.h>
   129 #include <e32btrace.h>
   130 #include <d32btrace.h>
   131 #include <d32locd.h>
   132 #include <hal.h>
   133 
   134 #include "t_hash.h"
   135 #include "paging_info.h"
   136 
   137 #ifndef TEST_AUTOTEST
   138 #define TEST_RUN_REAPERTEST
   139 #define TEST_RUN_LOWMEMTEST
   140 #define TEST_RUN_DEFRAGTEST
   141 #define TEST_RUN_D_EXCTEST
   142 #define TEST_RUN_CHUNKTEST
   143 #define TEST_RUN_AUTOTEST
   144 RTest test(_L("T_PAGELDRTST"));
   145 #else
   146 #ifdef TEST_RUN_REAPERTEST
   147 RTest test(_L("T_PAGELDRTST_REAPER"));
   148 #endif
   149 #ifdef TEST_RUN_LOWMEMTEST
   150 RTest test(_L("T_PAGELDRTST_LOWMEM"));
   151 #endif
   152 #ifdef TEST_RUN_DEFRAGTEST
   153 RTest test(_L("T_PAGELDRTST_DEFRAG"));
   154 #endif
   155 #ifdef TEST_RUN_D_EXCTEST
   156 RTest test(_L("T_PAGELDRTST_D_EXC"));
   157 #endif
   158 #ifdef TEST_RUN_CHUNKTEST
   159 RTest test(_L("T_PAGELDRTST_CHUNK"));
   160 #endif
   161 #ifdef TEST_RUN_AUTOTEST
   162 RTest test(_L("T_PAGELDRTST_AUTO"));
   163 #endif
   164 #endif //TEST_AUTOTEST
   165 
   166 const TInt KMessageBufSize = 80;
   167 typedef TBuf<KMessageBufSize> TMessageBuf;
   168 
   169 //#define TEST_SHORT_TEST
   170 //#define TEST_THRASHING_TEST
   171 //#define TEST_ADD_FAT_MEDIA
   172 #define TEST_DONT_RESET_STATS
   173 #define TEST_MINIMAL_STATS
   174 //#define TEST_KERN_HEAP
   175 #define TEST_ADD_FRAGD_MEDIA
   176 #ifdef TEST_ADD_FRAGD_MEDIA
   177 #endif
   178 
   179 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
   180 //#define WANT_FS_CACHE_STATS 
   181 #endif
   182 
   183 #ifdef __X86__
   184 #define TEST_ON_UNPAGED
   185 #define TEST_NO_DEXC_IN_AUTO
   186 #endif
   187 
   188 
   189 #include "t_pagestress.h"
   190 #include "t_pageldrtstdll.h"
   191 
   192 #include "t_ramstress.h"
   193 
   194 TBool		TestDebug					= EFalse;
   195 TBool		TestSilent					= EFalse;
   196 TBool		TestExit					= EFalse;
   197 #define TEST_EXE			0x01
   198 #define TEST_DLL			0x02
   199 #define TEST_SELF			0x04
   200 #define TEST_EXE_SELF		(TEST_EXE | TEST_SELF)
   201 #define TEST_EXE_SELF_DLL	(TEST_EXE | TEST_SELF | TEST_DLL)
   202 TInt		TestLoading				    = TEST_EXE_SELF_DLL;
   203 
   204 #define TEST_MEDIA_BASE			(1 << KTestMediaBase)
   205 #define TEST_MEDIA_ROM			(1 << KTestMediaRom)
   206 #define TEST_MEDIA_ROFS			(1 << KTestMediaRofs)
   207 #define TEST_MEDIA_EXT			(1 << KTestMediaExt)
   208 #define TEST_MEDIA_FAT			(1 << KTestMediaFat)
   209 #define TEST_MEDIA_MMC			(1 << KTestMediaMmc)
   210 #define TEST_MEDIA_ROM_BASE		(TEST_MEDIA_ROM | TEST_MEDIA_BASE)
   211 #define TEST_MEDIA_ALL		(TEST_MEDIA_ROM | TEST_MEDIA_BASE | TEST_MEDIA_ROFS | TEST_MEDIA_EXT | TEST_MEDIA_MMC)
   212 
   213 typedef enum
   214 {
   215 	KTestMediaBase = 0,
   216 	KTestMediaRom,
   217 	KTestMediaExt,
   218 	KTestMediaRofs,
   219 #ifdef TEST_ADD_FAT_MEDIA
   220 	KTestMediaFat,  // this is the last one that is always present.
   221 #endif
   222 	KTestMediaMmc,
   223 #ifdef TEST_ADD_FRAGD_MEDIA
   224 	KTestMediaNandFrag,
   225 	KTestMediaMmcFrag,
   226 #endif
   227 	KTestMediaCOUNT,
   228 }ETestMediaType;
   229 #ifdef TEST_ADD_FAT_MEDIA
   230 #define TEST_MEDIA_COUNT_HACK   (KTestMediaFat + 1)
   231 #else
   232 #define TEST_MEDIA_COUNT_HACK   (KTestMediaRofs + 1)
   233 #endif
   234 
   235 typedef enum
   236 {
   237 	KTestMediaAccessNone = 0,
   238 	KTestMediaAccessBasic,
   239 	KTestMediaAccessMultipleThreads,
   240 	KTestMediaAccessMultiplePattern,
   241 	KTestMediaAccessMixed,
   242 	KTestMediaAccessCOUNT,
   243 }ETestMediaAccess;
   244 
   245 TInt		TestWhichMedia			    = TEST_MEDIA_ROM_BASE;
   246 TInt		DriveNumber=-1;   // Parameter - Which drive?  -1 = autodetect.
   247 TBool		TestSingle					= EFalse;
   248 TBool		TestMultiple				= EFalse;
   249 TInt		TestMaxLoops				= 20;
   250 #define TEST_2MEDIA_THREADS		20
   251 #define TEST_ALLMEDIA_THREADS	20
   252 TInt		TestMultipleThreadCount		= TEST_2MEDIA_THREADS;
   253 TInt		TestInstanceId				= 0;
   254 TBool		TestWeAreTheTestBase        = EFalse;
   255 TBool		TestBootedFromMmc			= EFalse;
   256 TBool		TestOnlyFromMmc				= EFalse;
   257 TBool		TestD_Exc					= EFalse;
   258 TBool		TestNoClean					= EFalse;
   259 TBool		TestFullAutoTest			= EFalse;
   260 #define TEST_DLL_GLOBAL		0x01
   261 #define TEST_DLL_THREAD		0x02
   262 #define TEST_DLL_FUNC		0x04
   263 TInt		TestLoadDllHow				= TEST_DLL_FUNC;
   264 TBool		TestIsAutomated				= EFalse;
   265 
   266 #define TEST_INTERLEAVE_PRIO		EPriorityMore//EPriorityRealTime //23 // KNandThreadPriority - 1
   267 TBool		TestInterleave				= EFalse;
   268 TFileName	TestNameBuffer;
   269 TBool		TestPrioChange				= EFalse;
   270 
   271 volatile TBool		TestStopMedia				= EFalse;
   272 ETestMediaAccess TestMediaAccess        = KTestMediaAccessNone;
   273 #define TEST_NUM_FILES		5
   274 
   275 RSemaphore	TestMultiSem;
   276 RMsgQueue<TMessageBuf> TestMsgQueue;
   277 
   278 #define TEST_LM_NUM_FREE	0
   279 #define TEST_LM_BLOCKSIZE	1
   280 #define TEST_LM_BLOCKS_FREE	4
   281 TBool		TestLowMem					= EFalse;
   282 TBool		TestingLowMem				= EFalse;
   283 RPageStressTestLdd PagestressLdd;
   284 RRamStressTestLdd  RamstressLdd;
   285 
   286 TBool		TestBtrace					= EFalse;
   287 TBool		TestDefrag					= EFalse;
   288 TBool		TestChunks					= EFalse;
   289 TBool		TestChunksPlus				= EFalse;
   290 TBool		TestExtremeChunks			= EFalse;
   291 TBool		TestChunkData				= ETrue;
   292 TBool		TestingChunks				= EFalse;
   293 volatile TBool		TestDefragTestEnd			= EFalse;
   294 TBool		TestingDefrag				= EFalse;
   295 volatile TBool		TestThreadsExit				= EFalse;
   296 TInt		TestPageSize				= 4096;
   297 RChunk		TestChunk;
   298 TInt		TestCommitEnd = 0;
   299 TUint8*		TestChunkBase = NULL;
   300 #define TEST_NUM_PAGES			64
   301 #define TEST_NUM_CHUNK_PAGES	(TEST_NUM_PAGES * 2)
   302 TBool		TestChunkPageState[TEST_NUM_CHUNK_PAGES];
   303 
   304 TBool		TestReaper					= EFalse;
   305 TBool		TestingReaper				= EFalse;
   306 TBool		TestingReaperCleaningFiles  = EFalse;
   307 #define TEST_REAPER_ITERS			20
   308 #define TEST_DOT_PERIOD				30
   309 TBool		TestStressFree				= EFalse;
   310 TInt		TestMinCacheSize = 64 * 4096;
   311 TInt		TestMaxCacheSize = 128 * 4096;
   312 TBool		TestIsDemandPaged = ETrue;
   313 #define TEST_MAX_ZONE_THREADS		8
   314 TUint		TestZoneCount = 0;
   315 TInt TickPeriod = 15625;
   316 
   317 #define TEST_NONE		0x0
   318 #define TEST_THRASH		0x1
   319 #define TEST_FORWARD	0x2
   320 #define TEST_BACKWARD	0x4
   321 #define TEST_RANDOM		0x8
   322 #define TEST_ALL		(TEST_RANDOM | TEST_BACKWARD | TEST_FORWARD)
   323 TUint32	TestWhichTests				= TEST_ALL;
   324 _LIT(KRomPath, "z:\\sys\\bin\\");
   325 _LIT(KMmcDefaultPath, "d:\\sys\\bin\\");
   326 
   327 #define EXISTS(__val) ((__val == KErrNone) ? &KFileExists : &KFileMissing)
   328 _LIT(KSysHash,"?:\\Sys\\Hash\\");
   329 _LIT(KTestBlank, "");
   330 _LIT(KFileExists, "Exists");
   331 _LIT(KFileMissing, "Missing");
   332 _LIT(KMultipleTest, "Multiple");
   333 _LIT(KSingleTest,   "Single  ");
   334 _LIT(KTestExe, "Exe ");
   335 _LIT(KTestDll, "Dll ");
   336 _LIT(KTestSelf, "Self ");
   337 _LIT(KTestBase, "Base ");
   338 _LIT(KTestRom, "ROM ");
   339 _LIT(KTestAll, "All ");
   340 _LIT(KTestGlobal, "Global");
   341 _LIT(KTestThread, "Thread");
   342 _LIT(KTestFunc,  "Func");
   343 _LIT(KTestInter, "Interleave ");
   344 _LIT(KTestPrio, "Prio ");
   345 _LIT(KTestMedia, "Media ");
   346 _LIT(KTestLowMem, "LowMem ");
   347 _LIT(KTestChunking, "Chunks ");
   348 _LIT(KTestEChunking, "EChunks ");
   349 _LIT(KTestChunkingPlus, "Chunks+ ");
   350 _LIT(KTestReaper, "Reaper ");
   351 _LIT(KTestThrash, "Thrash ");
   352 _LIT(KTestForward, "Forward ");
   353 _LIT(KTestBackward, "Backward ");
   354 _LIT(KTestRandom, "Random ");
   355 
   356 typedef struct 
   357 	{
   358 	TBool				testFullAutoOnly;
   359 	TInt				testLoading;
   360 	TInt				testWhichMedia;
   361 	TBool				testMultiple;
   362 	TInt				testMaxLoops;
   363 	TInt				testMultipleThreadCount;
   364 	TBool				testLoadDllHow;
   365 	TBool				testInterleave;
   366 	TBool				testPrioChange;
   367 	ETestMediaAccess	testMediaAccess;
   368 	TUint32				testWhichTests;
   369 	TBool				testLowMem;
   370 	TInt				testFreeRam;
   371 	}TTheTests; 
   372 
   373 typedef struct
   374 	{
   375 	TInt	ok;
   376 	TInt	fail;
   377 	}TChunkTestPair;
   378 
   379 typedef struct
   380 	{
   381 	TChunkTestPair	lock;
   382 	TChunkTestPair	unlock;
   383 	TChunkTestPair	decommit;
   384 	TChunkTestPair	commit;
   385 	TChunkTestPair	check;
   386 	}
   387 TChunkTestStats;
   388 
   389 TChunkTestStats	TestChunkStats[TEST_NUM_CHUNK_PAGES];
   390 
   391 
   392 TPtrC TestPsExeNames[KTestMediaCOUNT] = {	_L("t_pagestress.exe"), 
   393 											_L("t_pagestress_rom.exe"), 
   394 											_L("t_pagestress_ext.exe"), 
   395 											_L("t_pagestress_rofs.exe"), 
   396 #ifdef TEST_ADD_FAT_MEDIA
   397 											_L("t_pagestress_fat.exe"),
   398 #endif
   399 											_L("t_pagestress_mmc.exe"),
   400 #ifdef TEST_ADD_FRAGD_MEDIA
   401 											_L("t_pagestress_nfr.exe"),
   402 											_L("t_pagestress_mfr.exe"),
   403 #endif
   404 											};
   405 
   406 TPtrC TestPlExeNames[KTestMediaCOUNT] = {	_L("t_pageldrtst.exe"), 
   407 											_L("t_pageldrtst_rom.exe"), 
   408 											_L("t_pageldrtst_ext.exe"), 
   409 											_L("t_pageldrtst_rofs.exe"), 
   410 #ifdef TEST_ADD_FAT_MEDIA
   411 											_L("t_pageldrtst_fat.exe"),
   412 #endif
   413 											_L("t_pageldrtst_mmc.exe"),
   414 #ifdef TEST_ADD_FRAGD_MEDIA
   415 											_L("t_pageldrtst_nfr.exe"),
   416 											_L("t_pageldrtst_mfr.exe"),
   417 #endif
   418 											};
   419 
   420 _LIT(KDllBaseName,   "t_pageldrtst");
   421 
   422 TPtrC TestPlExtNames[KTestMediaCOUNT] = {	_L(".dll"),
   423 											_L("_rom.dll"),
   424 											_L("_ext.dll"),
   425 											_L("_rofs.dll"),
   426 #ifdef TEST_ADD_FAT_MEDIA
   427 											_L("_fat.dll"),
   428 #endif
   429 											_L("_mmc.dll"),
   430 #ifdef TEST_ADD_FRAGD_MEDIA
   431 											_L("_nfr.dll"),
   432 											_L("_mfr.dll"),
   433 #endif
   434 											};
   435 
   436 
   437 TBool TestDllExesExist[KTestMediaCOUNT] = { EFalse, 
   438 											EFalse,
   439 											EFalse,
   440 											EFalse,
   441 #ifdef TEST_ADD_FAT_MEDIA
   442 											EFalse,
   443 #endif
   444 											EFalse,
   445 #ifdef TEST_ADD_FRAGD_MEDIA
   446 											EFalse,
   447 											EFalse,
   448 #endif
   449 											};
   450 #define DBGS_PRINT(__args)\
   451 	if (!TestSilent) test.Printf __args;
   452 
   453 #define DBGD_PRINT(__args)\
   454 	if (TestDebug) test.Printf __args;
   455 
   456 void SendDebugMessage(RMsgQueue<TMessageBuf> *aMsgQueue = NULL, 
   457 					  TMessageBuf            *aBuffer = NULL,
   458 					  RSemaphore	 		 *aTheSem = NULL)
   459 	{
   460 	for (;;)
   461 		{
   462 		aTheSem->Wait();
   463 		TInt r = aMsgQueue->Send(*aBuffer);
   464 		aTheSem->Signal();
   465 		if (r != KErrOverflow)
   466 			return;
   467 		User::After(0);
   468 		}
   469 	}
   470 
   471 #define DEBUG_PRINT(__args)\
   472 if (!TestSilent) \
   473 	{\
   474 	if (aMsgQueue && aBuffer && aTheSem)\
   475 		{\
   476 		aBuffer->Zero();\
   477 		aBuffer->Format __args ;\
   478 		SendDebugMessage(aMsgQueue, aBuffer, aTheSem);\
   479 		}\
   480 	else\
   481 		{\
   482 		test.Printf __args ;\
   483 		}\
   484 	}
   485 
   486 #define RUNTEST(__test, __error)\
   487 	if (!TestSilent)\
   488 		test(__test == __error);\
   489 	else\
   490 		__test;
   491 
   492 #define RUNTEST1(__test)\
   493 	if (!TestSilent)\
   494 		test(__test);
   495 
   496 
   497 #define DEBUG_PRINT1(__args)\
   498 if (TestDebug)\
   499 	{\
   500 	DEBUG_PRINT(__args)\
   501 	}
   502 
   503 #define DOTEST(__operation, __condition)\
   504 	if (aLowMem) \
   505 		{\
   506 		__operation;\
   507 		while (!__condition)\
   508 			{\
   509 			DBGD_PRINT((_L("Releasing some memory on line %d\n"), __LINE__));\
   510 			if (pTheSem)\
   511 				pTheSem->Wait();\
   512 			PagestressLdd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE);\
   513 			if (pTheSem)\
   514 				pTheSem->Signal();\
   515 			__operation;\
   516 			}\
   517 		RUNTEST1(__condition);\
   518 		}\
   519 	else\
   520 		{\
   521 		__operation;\
   522 		RUNTEST1(__condition);\
   523 		}
   524 
   525 #define DOTEST1(__var, __func, __ok, __fail)\
   526 	if (aLowMem) \
   527 		{\
   528 		__var = __func;\
   529 		while (__var == __fail)\
   530 			{\
   531 			DBGD_PRINT((_L("Releasing some memory on line %d\n"), __LINE__));\
   532 			if (pTheSem)\
   533 				pTheSem->Wait();\
   534 			PagestressLdd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE);\
   535 			if (pTheSem)\
   536 				pTheSem->Signal();\
   537 			__var = __func;\
   538 			}\
   539 		if (__var != __ok)\
   540 			DBGS_PRINT((_L("Failing on line %d with error %d\n"), __LINE__, __var));\
   541 		RUNTEST1(__var == __ok);\
   542 		}\
   543 	else\
   544 		{\
   545 		__var = __func;\
   546 		RUNTEST1(__var == __ok);\
   547 		}
   548 
   549 #define DOLOADALLOC(__numDlls, __pTheLibs, __theSem)\
   550 	if (TestingLowMem)\
   551 		{\
   552 		__pTheLibs = (PageLdrRLibrary *)User::AllocZ(sizeof(PageLdrRLibrary) * __numDlls);\
   553 		while (__pTheLibs == NULL)\
   554 			{\
   555 			DEBUG_PRINT1((_L("Releasing some memory for alloc on line %d\n"), __LINE__));\
   556 			if (__theSem)\
   557 				__theSem->Wait();\
   558 			PagestressLdd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE);\
   559 			if (__theSem)\
   560 				__theSem->Signal();\
   561 			__pTheLibs = (PageLdrRLibrary *)User::AllocZ(sizeof(PageLdrRLibrary) * __numDlls);\
   562 			}\
   563 		}\
   564 	else\
   565 		{\
   566 		__pTheLibs = (PageLdrRLibrary *)User::AllocZ(sizeof(PageLdrRLibrary) * __numDlls);\
   567 		if (__pTheLibs == NULL)\
   568 			return KErrGeneral;\
   569 		}
   570 
   571 #define TEST_NEXT(__args) \
   572 	if (!TestSilent)\
   573 		test.Next __args;
   574 
   575 void DoStats();
   576 void CheckFilePresence(TBool aDoFileCopy);
   577 void CleanupFiles(TBool silent);
   578 typedef TInt (*TCallFunction)(TUint32 funcIndex, TInt param1, TInt param2);
   579 
   580 class PageLdrRLibrary : public RLibrary
   581 	{
   582 public:
   583 	TInt TestLoadLibrary(const TDesC& aFileName, TInt aThreadIndex, RMsgQueue<TMessageBuf> *aMsgQueue, TMessageBuf *aBuffer, RSemaphore  *aTheSem);
   584 	TInt CloseLibrary();
   585 	
   586 public:	
   587 	TBool				iInUse;
   588 	TUint32				iFuncCount;
   589 	TLibraryFunction	iInitFunc;
   590 	TLibraryFunction	iFunctionCountFunc;
   591 	TCallFunction       iCallFunctionFunc;
   592 	TLibraryFunction	iSetCloseFunc;
   593 	};
   594 
   595 TInt PageLdrRLibrary::CloseLibrary()
   596 	{
   597 	if (iInUse)
   598 		{
   599 		if (iSetCloseFunc)
   600 			(iSetCloseFunc)();
   601 		Close();
   602 		iFuncCount = 0;
   603 		iInitFunc = NULL;
   604 		iFunctionCountFunc = NULL;
   605 		iCallFunctionFunc = NULL;
   606 		iSetCloseFunc = NULL;
   607 		iInUse = EFalse;
   608 		}
   609 	return KErrNone;
   610 	}
   611 
   612 PageLdrRLibrary		theGlobalLibs[PAGELDRTST_MAX_DLLS * KTestMediaCOUNT];
   613 
   614 ////////////////////////////////////////////////////////////
   615 // Template functions encapsulating ControlIo magic
   616 //
   617 GLDEF_D template <class C>
   618 GLDEF_C TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c)
   619 {
   620     TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C));
   621 
   622     TInt r = fs.ControlIo(drv, fkn, ptrC);
   623 
   624     return r;
   625 }
   626 
   627 //
   628 // FreeRam
   629 //
   630 // Get available free ram.
   631 //
   632 
   633 TInt FreeRam()
   634 	{
   635 	// wait for any async cleanup in the supervisor to finish first...
   636 	UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
   637 
   638 	TMemoryInfoV1Buf meminfo;
   639 	TInt r=UserHal::MemoryInfo(meminfo);
   640 	test (r==KErrNone);
   641 	return meminfo().iFreeRamInBytes;
   642 	}
   643 
   644 //
   645 // FindFsNANDDrive
   646 //
   647 // Find the NAND drive
   648 //
   649 
   650 static TInt FindFsNANDDrive(RFs& aFs)
   651 	{
   652 	TDriveList driveList;
   653 	TDriveInfo driveInfo;
   654 	TInt r=aFs.DriveList(driveList);
   655     if (r == KErrNone)
   656 		{
   657 		for (TInt drvNum= (DriveNumber<0)?0:DriveNumber; drvNum<KMaxDrives; ++drvNum)
   658 			{
   659 			if(!driveList[drvNum])
   660 				continue;   //-- skip unexisting drive
   661 
   662 			if (aFs.Drive(driveInfo, drvNum) == KErrNone)
   663 				{
   664 				if(driveInfo.iMediaAtt&KMediaAttPageable)
   665 					{
   666 					TBool readOnly = driveInfo.iMediaAtt & KMediaAttWriteProtected;		// skip ROFS partitions
   667 					if(!readOnly && (driveInfo.iType != EMediaHardDisk))
   668 						{
   669 						if ((drvNum==DriveNumber) || (DriveNumber<0))		// only test if running on this drive
   670 							{
   671 							return (drvNum);
   672 							}
   673 						}
   674 					}
   675 				}
   676 			}
   677 		}
   678 	return (-1);
   679 	}
   680 
   681 //
   682 // FindMMCDriveNumber
   683 // 
   684 // Find the first read write drive.
   685 //
   686 
   687 TInt FindMMCDriveNumber(RFs& aFs)
   688 	{
   689 	TDriveInfo driveInfo;
   690 	for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum)
   691 		{
   692 		TInt r = aFs.Drive(driveInfo, drvNum);
   693 		if (r >= 0)
   694 			{
   695 			if (driveInfo.iType == EMediaHardDisk)
   696 				return (drvNum);
   697 			}
   698 		}
   699 	return -1;
   700 	}
   701 
   702 
   703 //
   704 // PageLdrRLibrary::TestLoadLibrary
   705 //
   706 // Load a library and initialise information about that library
   707 //
   708 
   709 TInt PageLdrRLibrary::TestLoadLibrary(const TDesC&           aFileName,
   710 									  TInt					 aThreadIndex,
   711 									  RMsgQueue<TMessageBuf> *aMsgQueue = NULL, 
   712 									  TMessageBuf           *aBuffer = NULL,
   713 									  RSemaphore			*aTheSem = NULL)
   714 	{
   715 	TInt retVal = KErrNone;
   716 	if (TestingLowMem)
   717 		{
   718 		TBool whinged = EFalse;
   719 		TInt initialFreeRam = 0;
   720 		TInt freeRam = 0;
   721 
   722 		while (1)
   723 			{
   724 			initialFreeRam = FreeRam();
   725 			retVal = Load(aFileName);
   726 			freeRam = FreeRam();
   727 			if (retVal == KErrNoMemory)
   728 				{
   729 				if (!whinged && (freeRam > (4 * TestPageSize)))
   730 					{
   731 					whinged = ETrue;
   732 					DEBUG_PRINT1((_L("Load() %d pages %S\n"), (freeRam / TestPageSize), &aFileName));
   733 					if (TestIsDemandPaged)
   734 						{
   735 						SVMCacheInfo  tempPages;
   736 						UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
   737 
   738 						DEBUG_PRINT1((_L("DPC : min %d max %d curr %d\n"), 
   739 									tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize));
   740 						DEBUG_PRINT1((_L("    : maxFree %d freeRam %d\n"),
   741 									tempPages.iMaxFreeSize, FreeRam()));
   742 						}
   743 					}
   744 				DEBUG_PRINT1((_L("Load() releasing some memory for %S (%d)\n"), &aFileName, retVal));
   745 				if (aTheSem)
   746 					aTheSem->Wait();
   747 				PagestressLdd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE);
   748 				if (aTheSem)
   749 					aTheSem->Signal();
   750 				}
   751 			else
   752 				{
   753 				if (whinged)
   754 					{
   755 					DEBUG_PRINT((_L("Load() Ok %d pages (%d) %S\n"), ((initialFreeRam - freeRam) / TestPageSize), (freeRam / TestPageSize), &aFileName));
   756 					}
   757 				break;
   758 				}
   759 			}
   760 		}
   761 	else
   762 		{
   763 		DEBUG_PRINT1((_L("Loading %S (%d)\n"), &aFileName, aThreadIndex));	 
   764 		retVal = Load(aFileName);
   765 		if (retVal != KErrNone)
   766 			{
   767 			DEBUG_PRINT1((_L("Load failed %S (%d)\n"), &aFileName, aThreadIndex));	 
   768 			if (TestingReaper )
   769 				{
   770 				TInt tempIndex = 0;
   771 				TBool whinged = EFalse;
   772 				while (    (   (retVal == KErrNotFound) 
   773 							|| (retVal == KErrPermissionDenied) 
   774 							|| (retVal == KErrCorrupt) 
   775 							|| (retVal == KErrInUse)) 
   776 						&& (    TestingReaperCleaningFiles
   777 							|| (tempIndex < TEST_REAPER_ITERS)))
   778 					{
   779 					User::After(2000000);
   780 					if (!whinged)
   781 						{
   782 						DEBUG_PRINT((_L("Load() retrying load for %S (%d)\n"), &aFileName, retVal));
   783 						whinged = ETrue;
   784 						}
   785 					retVal = Load(aFileName);
   786 					if (!TestingReaperCleaningFiles)
   787 						{
   788 						tempIndex ++;
   789 						}
   790 					}
   791 				if (retVal != KErrNone)
   792 					{
   793 					DEBUG_PRINT((_L("Load() failing for %S (%d) idx %d\n"), &aFileName, retVal, tempIndex));
   794 					}
   795 				}
   796 			else if (TestingDefrag)
   797 				{
   798 				TInt tempIndex = 0;
   799 				TBool whinged = EFalse;
   800 				while ((retVal == KErrGeneral) && (tempIndex < 10))
   801 					{
   802 					User::After(20000);
   803 					if (!whinged)
   804 						{
   805 						DEBUG_PRINT((_L("Load() retrying load for %S (%d)\n"), &aFileName, retVal));
   806 						whinged = ETrue;
   807 						}
   808 					retVal = Load(aFileName);
   809 					tempIndex ++;
   810 					}
   811 				if (retVal != KErrNone)
   812 					{
   813 					DEBUG_PRINT((_L("Load() failing for %S (%d) idx %d\n"), &aFileName, retVal, tempIndex));
   814 					}
   815 				}
   816 			}
   817 		}
   818 	DEBUG_PRINT1((_L("Loaded %S (%d)\n"), &aFileName, aThreadIndex));	 
   819 	if (retVal == KErrNone)
   820 		{
   821 		iInUse = ETrue;
   822 		iInitFunc = Lookup(PAGELDRTST_FUNC_Init);
   823 		iFunctionCountFunc = Lookup(PAGELDRTST_FUNC_FunctionCount);
   824 		iCallFunctionFunc = (TCallFunction)Lookup(PAGELDRTST_FUNC_CallFunction);
   825 		iSetCloseFunc = Lookup(PAGELDRTST_FUNC_SetClose);
   826 		if (   (iInitFunc != NULL)
   827 			&& (iFunctionCountFunc != NULL)
   828 			&& (iCallFunctionFunc != NULL)
   829 			&& (iSetCloseFunc != NULL))
   830 			{
   831 			retVal = (iInitFunc)();
   832 			if (retVal == KErrNone)
   833 				{
   834 				iFuncCount = (iFunctionCountFunc)();
   835 				if (iFuncCount != 0)
   836 					{
   837 					DEBUG_PRINT1((_L("Loaded ok %S (%d)\n"), &aFileName, aThreadIndex));	 
   838 					return KErrNone;	
   839 					}
   840 				retVal = KErrGeneral;
   841 				DEBUG_PRINT((_L("!!! bad count %S (%d)\n"), &aFileName, aThreadIndex));	 
   842 				}
   843 			else
   844 				{
   845 				DEBUG_PRINT((_L("!!! init failed %S (%d)\n"), &aFileName, aThreadIndex));	 
   846 				retVal = KErrGeneral;
   847 				}
   848 			}
   849 		else
   850 			{
   851 			DEBUG_PRINT((_L("!!! missing %S (%d)\n"), &aFileName, aThreadIndex));	 
   852 			retVal = KErrGeneral;
   853 			}
   854 		}
   855 	else
   856 		{
   857 		DEBUG_PRINT((_L("Load() failed %S %d\n"), &aFileName, retVal));
   858 #ifdef WANT_FS_CACHE_STATS
   859 		RFs			 fs;
   860 		if (KErrNone != fs.Connect())
   861 			{
   862 			DEBUG_PRINT(_L("TestLoadLibrary : Can't connect to the FS\n"));
   863 			}
   864 		else
   865 			{
   866 			TFileCacheStats stats1;
   867 			TInt drvNum = FindMMCDriveNumber(fs); 
   868 			controlIo(fs,drvNum, KControlIoFileCacheStats, stats1);
   869 		
   870 			DEBUG_PRINT((_L("FSC: drv %d %c free %d used %d locked %d\n"),
   871 						drvNum, 'a' + drvNum,
   872 						stats1.iFreeCount,
   873 						stats1.iUsedCount,
   874 						stats1.iLockedSegmentCount));
   875 			DEBUG_PRINT((_L("   : alloc %d lock %d closed %d\n"),
   876 						stats1.iAllocatedSegmentCount,
   877 						stats1.iFileCount,
   878 						stats1.iFilesOnClosedQueue));
   879 			fs.Close();
   880 			}
   881 #endif //WANT_FS_CACHE_STATS 
   882 
   883 		if (TestIsDemandPaged)
   884 			{
   885 			SVMCacheInfo  tempPages;
   886 			UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
   887 
   888 			DEBUG_PRINT((_L("DPC : min %d max %d curr %d\n"), 
   889 						tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize));
   890 			DEBUG_PRINT((_L("    : maxFree %d freeRam %d\n"),
   891 						tempPages.iMaxFreeSize, FreeRam()));
   892 			}
   893 		}
   894 	return retVal;
   895 	}
   896 
   897 //
   898 // GetNumDlls
   899 //
   900 // Work out how many Dlls we will play with
   901 //
   902 TInt GetNumDlls()
   903 	{
   904 	TInt maxDllIndex;
   905 
   906 	switch (TestWhichMedia)
   907 		{
   908 		default:
   909 		case TEST_MEDIA_BASE:	
   910 		case TEST_MEDIA_ROM:
   911 			maxDllIndex = PAGELDRTST_MAX_DLLS;
   912 		break;
   913 
   914 		case TEST_MEDIA_ROM_BASE:
   915 			maxDllIndex = PAGELDRTST_MAX_DLLS * 2;
   916 		break;
   917 
   918 		case TEST_MEDIA_ALL:
   919 			maxDllIndex = PAGELDRTST_MAX_DLLS * KTestMediaCOUNT;
   920 		break;
   921 		}
   922 	return maxDllIndex;
   923 	}
   924 
   925 //
   926 // LoadTheLibs
   927 //
   928 // Open DLLs for use in the tests.
   929 //
   930 
   931 TInt LoadTheLibs(PageLdrRLibrary       *aTheLibs,
   932                  TInt                   aLibCount,
   933 				 TInt				    aThreadIndex, 
   934                  RMsgQueue<TMessageBuf> *aMsgQueue = NULL, 
   935 				 TMessageBuf           *aBuffer = NULL, 
   936 				 RSemaphore			   *aTheSem = NULL)
   937 	{
   938 	TBuf<128>			nameBuffer;
   939 	TInt				dllIndex = 0;
   940 	TInt				realDllIndex = 0;
   941 	TInt				dllOffset = -1;
   942 	TInt				testWhich;
   943 	RThread				thisThread;
   944 
   945 	memset(aTheLibs, 0, sizeof(*aTheLibs) * aLibCount);
   946 	for (dllIndex = 0; dllIndex < aLibCount; dllIndex ++)
   947 		{
   948 		realDllIndex = (dllIndex + aThreadIndex) % PAGELDRTST_MAX_DLLS;
   949 //		realDllIndex = (dllIndex) % PAGELDRTST_MAX_DLLS;
   950 		if (realDllIndex == 0)
   951 			dllOffset ++;
   952 
   953 		if ((TestWhichMedia & TEST_MEDIA_ALL) == TEST_MEDIA_ALL)
   954 			testWhich = (dllIndex + dllOffset) % KTestMediaCOUNT;
   955 		else if ((TestWhichMedia & TEST_MEDIA_ALL) == TEST_MEDIA_ROM_BASE)
   956 			testWhich = ((dllIndex + dllOffset) & 1) ? KTestMediaBase : KTestMediaRom;
   957 		else if (TestWhichMedia & TEST_MEDIA_BASE )
   958 			testWhich = KTestMediaBase;
   959 		else
   960 			testWhich = KTestMediaRom;
   961 		
   962 		if (!TestDllExesExist[testWhich])
   963 			testWhich = KTestMediaBase;
   964 
   965 		nameBuffer.Format(_L("%S%d%S"), &KDllBaseName, realDllIndex, &TestPlExtNames[testWhich]);
   966 		
   967 		DEBUG_PRINT1((_L("LoadTheLibs[%02d] - loading %S\n"), aThreadIndex, &nameBuffer));
   968 		TInt theErr = aTheLibs[dllIndex].TestLoadLibrary(nameBuffer, aThreadIndex, aMsgQueue, aBuffer, aTheSem);
   969 		if (theErr != KErrNone)
   970 			{
   971 			DEBUG_PRINT((_L("LoadTheLibs[%02d] - fail %S %d\n"), aThreadIndex, &nameBuffer, theErr));
   972 			return KErrGeneral;
   973 			}
   974 		else
   975 			{
   976 			DEBUG_PRINT1((_L("LoadTheLibs[%02d] - loaded %S OK\n"), aThreadIndex, &nameBuffer));
   977 			}
   978 		if (TestThreadsExit)
   979 			{
   980 			DEBUG_PRINT((_L("LoadTheLibs[%02d] - cancelled\n"), aThreadIndex));
   981 			return KErrCancel;
   982 			}
   983 		if (TestPrioChange)
   984 			{
   985 			TThreadPriority originalThreadPriority = thisThread.Priority();
   986 			DEBUG_PRINT1((_L("LoadTheLibs[%02d] before priority change\n"), aThreadIndex));
   987 			thisThread.SetPriority(EPriorityLess);
   988 			User::AfterHighRes(0);
   989 			thisThread.SetPriority(originalThreadPriority);
   990 			DEBUG_PRINT1((_L("LoadTheLibs[%02d] after priority change\n"), aThreadIndex));
   991 			}
   992 		}
   993 	DEBUG_PRINT((_L("LoadTheLibs[%02d] done\n"), aThreadIndex));
   994 	return KErrNone;
   995 	}
   996 
   997 //
   998 // CloseTheLibs
   999 //
  1000 // Close the DLLs that we have previously opened
  1001 //
  1002 
  1003 void CloseTheLibs (PageLdrRLibrary       *aTheLibs,
  1004                    TInt                   aLibCount)
  1005 	{
  1006 	TInt				dllIndex = 0;
  1007 	
  1008 	for (dllIndex = 0; dllIndex < aLibCount; dllIndex ++)
  1009 		{
  1010 		aTheLibs[dllIndex].CloseLibrary();
  1011 		}
  1012 	memset(aTheLibs, 0, sizeof(*aTheLibs) * aLibCount);
  1013 	}
  1014 
  1015 //
  1016 // RunThreadForward
  1017 //
  1018 // Walk through the function pointer array (forwards) calling each function
  1019 //
  1020 
  1021 TInt RunThreadForward(TInt				     aThreadIndex, 
  1022 					  PageLdrRLibrary		*aTheLibs,
  1023 					  TInt					 aMaxDllIndex,
  1024 					  RMsgQueue<TMessageBuf> *aMsgQueue = NULL, 
  1025 					  TMessageBuf			*aBuffer = NULL, 
  1026 					  RSemaphore			*aTheSem = NULL)
  1027 	{
  1028 	TInt				seed = 1;
  1029 	TUint32				index = 0;
  1030 	RThread				thisThread;
  1031 	PageLdrRLibrary    *pTheLibs = NULL;
  1032 	TInt				dllIndex = 0;
  1033 
  1034 	if (TestLoadDllHow == TEST_DLL_FUNC)
  1035 		{
  1036 		DOLOADALLOC(aMaxDllIndex, pTheLibs, aTheSem);
  1037 		if (pTheLibs)
  1038 			{
  1039 			TInt retVal = LoadTheLibs(pTheLibs, aMaxDllIndex, aThreadIndex, aMsgQueue, aBuffer, aTheSem);
  1040 			if (retVal != KErrNone)
  1041 				{
  1042 				DEBUG_PRINT((_L("Forward[%d] - load fail\n"), aThreadIndex));
  1043 				CloseTheLibs (pTheLibs, aMaxDllIndex);
  1044 				User::Free(pTheLibs);
  1045 				return retVal;
  1046 				}
  1047 			}
  1048 		else
  1049 			{
  1050 			DEBUG_PRINT((_L("Forward[%d] - alloc fail\n"), aThreadIndex));
  1051 			return KErrGeneral;
  1052 			}
  1053 		}
  1054 	else
  1055 		{
  1056 		pTheLibs = aTheLibs;
  1057 		}
  1058 	
  1059 	for (dllIndex = 0; dllIndex < aMaxDllIndex; dllIndex ++)
  1060 		{
  1061 		index = 0;
  1062 		while (index < pTheLibs[dllIndex].iFuncCount)
  1063 			{
  1064 			if (TestPrioChange)
  1065 				{
  1066 				TThreadPriority originalThreadPriority = thisThread.Priority();
  1067 				thisThread.SetPriority(EPriorityLess);
  1068 				User::AfterHighRes(0);
  1069 				thisThread.SetPriority(originalThreadPriority);
  1070 				}
  1071 			if (pTheLibs[dllIndex].iCallFunctionFunc)
  1072 				seed = pTheLibs[dllIndex].iCallFunctionFunc(index, seed, index);
  1073 			else
  1074 				DEBUG_PRINT((_L("Forward[%d] : dll %d was NULL\n"), aThreadIndex, dllIndex));
  1075 			index ++;
  1076 			if (TestThreadsExit)
  1077 				break;
  1078 			}
  1079 		if (TestThreadsExit)
  1080 			break;
  1081 		}
  1082 	if (TestLoadDllHow == TEST_DLL_FUNC)
  1083 		{
  1084 		CloseTheLibs(pTheLibs, aMaxDllIndex);
  1085 		User::Free(pTheLibs);
  1086 		}
  1087 	return KErrNone;
  1088 	}
  1089 
  1090 //
  1091 // RunThreadBackward
  1092 //
  1093 // Walk through the function pointer array (backwards) calling each function
  1094 //
  1095 
  1096 TInt RunThreadBackward(TInt				      aThreadIndex, 
  1097 					   PageLdrRLibrary		 *aTheLibs,
  1098 					   TInt					  aMaxDllIndex,
  1099 					   RMsgQueue<TMessageBuf> *aMsgQueue = NULL, 
  1100 					   TMessageBuf			 *aBuffer = NULL,
  1101 					   RSemaphore			 *aTheSem = NULL)
  1102 	{
  1103 	TInt				seed = 1;
  1104 	TUint32				index = 0;
  1105 	RThread				thisThread;
  1106 	PageLdrRLibrary    *pTheLibs = NULL;
  1107 	TInt				dllIndex = 0;
  1108 
  1109 	if (TestLoadDllHow == TEST_DLL_FUNC)
  1110 		{
  1111 		DOLOADALLOC(aMaxDllIndex, pTheLibs, aTheSem);
  1112 		if (pTheLibs)
  1113 			{
  1114 			TInt retVal = LoadTheLibs(pTheLibs, aMaxDllIndex, aThreadIndex, aMsgQueue, aBuffer, aTheSem);
  1115 			if (retVal != KErrNone)
  1116 				{
  1117 				DEBUG_PRINT((_L("Backward[%d] - load fail\n"), aThreadIndex));
  1118 				CloseTheLibs (pTheLibs, aMaxDllIndex);
  1119 				User::Free(pTheLibs);
  1120 				return retVal;
  1121 				}
  1122 			}
  1123 		else
  1124 			{
  1125 			DEBUG_PRINT((_L("Backward[%d] - alloc fail\n"), aThreadIndex));
  1126 			return KErrGeneral;
  1127 			}
  1128 		}	
  1129 	else
  1130 		{
  1131 		pTheLibs = aTheLibs;
  1132 		}
  1133 
  1134 	for (dllIndex = aMaxDllIndex - 1; dllIndex >= 0; dllIndex --)
  1135 		{
  1136 		index = pTheLibs[dllIndex].iFuncCount;
  1137 		while (index > 0)
  1138 			{
  1139 			if (TestPrioChange)
  1140 				{
  1141 				TThreadPriority originalThreadPriority = thisThread.Priority();
  1142 				thisThread.SetPriority(EPriorityLess);
  1143 				User::AfterHighRes(0);
  1144 				thisThread.SetPriority(originalThreadPriority);
  1145 				}
  1146 			if (pTheLibs[dllIndex].iCallFunctionFunc)
  1147 				seed = pTheLibs[dllIndex].iCallFunctionFunc(index, seed, index);
  1148 			else
  1149 				DEBUG_PRINT((_L("Backward[%d] : dll %d was NULL\n"), aThreadIndex, dllIndex));
  1150 			index --;
  1151 			if (TestThreadsExit)
  1152 				break;
  1153 			}
  1154 		if (TestThreadsExit)
  1155 			break;
  1156 		}
  1157 	if (TestLoadDllHow == TEST_DLL_FUNC)
  1158 		{
  1159 		CloseTheLibs(pTheLibs, aMaxDllIndex);
  1160 		User::Free(pTheLibs);
  1161 		}
  1162 	return KErrNone;
  1163 	}
  1164 
  1165 //
  1166 // RunThreadRandom
  1167 //
  1168 // Walk through the function pointer array in a random order a number of times calling each function
  1169 //
  1170 
  1171 TInt RunThreadRandom(TInt				    aThreadIndex, 
  1172 					 PageLdrRLibrary	   *aTheLibs,
  1173 					 TInt				    aMaxDllIndex,
  1174 					 RMsgQueue<TMessageBuf> *aMsgQueue = NULL, 
  1175 					 TMessageBuf		   *aBuffer = NULL,
  1176 					 RSemaphore			   *aTheSem = NULL)
  1177 	{
  1178 	TInt				seed = 1;
  1179 	TUint				randNum;
  1180 	RThread				thisThread;
  1181 	PageLdrRLibrary    *pTheLibs = NULL;
  1182 	TUint				dllIndex = 0;
  1183 	
  1184 	if (TestLoadDllHow == TEST_DLL_FUNC)
  1185 		{
  1186 		DOLOADALLOC(aMaxDllIndex, pTheLibs, aTheSem);
  1187 		if (pTheLibs)
  1188 			{
  1189 			TInt retVal = LoadTheLibs(pTheLibs, aMaxDllIndex, aThreadIndex, aMsgQueue, aBuffer, aTheSem);
  1190 			if (retVal != KErrNone)
  1191 				{
  1192 				DEBUG_PRINT((_L("Random[%d] - load fail\n"), aThreadIndex));
  1193 				CloseTheLibs (pTheLibs, aMaxDllIndex);
  1194 				User::Free(pTheLibs);
  1195 				return retVal;
  1196 				}
  1197 			}
  1198 		else
  1199 			{
  1200 			DEBUG_PRINT((_L("Random[%d] - alloc fail\n"), aThreadIndex));
  1201 			return KErrGeneral;
  1202 			}
  1203 		}
  1204 	else
  1205 		{
  1206 		pTheLibs = aTheLibs;
  1207 		}
  1208 
  1209 	
  1210 	TUint funcCount = (TUint)pTheLibs[0].iFuncCount;
  1211 	TInt iterCount = aMaxDllIndex * funcCount;
  1212 	
  1213 	// reduce the time for auto tests by reducing the number of cycles.
  1214 	if (TestIsAutomated)
  1215 		iterCount /= 4;
  1216 
  1217 	while (iterCount > 0)
  1218 		{
  1219 		if (TestPrioChange)
  1220 			{
  1221 			TThreadPriority originalThreadPriority = thisThread.Priority();
  1222 			thisThread.SetPriority(EPriorityLess);
  1223 			User::AfterHighRes(0);
  1224 			thisThread.SetPriority(originalThreadPriority);
  1225 			}
  1226 		
  1227 		randNum = (TUint)Math::Random();
  1228 		dllIndex = randNum % (TUint)aMaxDllIndex;
  1229 
  1230 		randNum %= funcCount;
  1231 
  1232 		if (   (randNum < funcCount)
  1233 		    && ((TInt)dllIndex < aMaxDllIndex))
  1234 			{
  1235 			if (pTheLibs[dllIndex].iCallFunctionFunc)
  1236 				{
  1237 				seed = pTheLibs[dllIndex].iCallFunctionFunc(randNum, seed, randNum);
  1238 				}
  1239 			else
  1240 				DEBUG_PRINT((_L("Random[%d] : dll %d was NULL\n"), aThreadIndex, dllIndex));
  1241 			}
  1242 		else
  1243 			{
  1244 			DEBUG_PRINT((_L("Random[%d] : %d ERROR dllIndex %u rand %u\n"), aThreadIndex, iterCount, dllIndex, randNum));
  1245 			}
  1246 		
  1247 		--iterCount;
  1248 		if (TestThreadsExit)
  1249 			break;
  1250 		}
  1251 
  1252 	if (TestLoadDllHow == TEST_DLL_FUNC)
  1253 		{
  1254 		CloseTheLibs(pTheLibs, aMaxDllIndex);
  1255 		User::Free(pTheLibs);
  1256 		}
  1257 	return KErrNone;
  1258 	}
  1259 
  1260 
  1261 //
  1262 // ThrashThreadLoad
  1263 //
  1264 // Load and unload the DLLs rapidly to show up a timing window in the kernel.
  1265 //
  1266 
  1267 TInt ThrashThreadLoad (TInt				      aThreadIndex, 
  1268 					   PageLdrRLibrary		 *aTheLibs,
  1269 					   TInt					  aMaxDllIndex,
  1270 					   RMsgQueue<TMessageBuf> *aMsgQueue = NULL, 
  1271 					   TMessageBuf			 *aBuffer = NULL,
  1272 					   RSemaphore			 *aTheSem = NULL)
  1273 	{
  1274 	if (TestLoadDllHow == TEST_DLL_FUNC)
  1275 		{
  1276 		PageLdrRLibrary    *pTheLibs = NULL;
  1277 		DOLOADALLOC(aMaxDllIndex, pTheLibs, aTheSem);
  1278 		if (pTheLibs)
  1279 			{
  1280 			TInt retVal = LoadTheLibs(pTheLibs, aMaxDllIndex, aThreadIndex, aMsgQueue, aBuffer, aTheSem);
  1281 			if (retVal != KErrNone)
  1282 				{
  1283 				DEBUG_PRINT((_L("Thrash[%d] - load fail\n"), aThreadIndex));
  1284 				CloseTheLibs (pTheLibs, aMaxDllIndex);
  1285 				User::Free(pTheLibs);
  1286 				return retVal;
  1287 				}
  1288 			}
  1289 		else
  1290 			{
  1291 			DEBUG_PRINT((_L("Thrash[%d] - alloc fail\n"), aThreadIndex));
  1292 			return KErrGeneral;
  1293 			}
  1294 
  1295 		CloseTheLibs(pTheLibs, aMaxDllIndex);
  1296 		User::Free(pTheLibs);
  1297 		}
  1298 	return KErrNone;
  1299 	}
  1300 
  1301 
  1302 //
  1303 // PerformTestThread
  1304 //
  1305 // This is the function that actually does the work.
  1306 // It is complicated a little because test.Printf can only be called from the first thread that calls it 
  1307 // so if we are using multiple threads we need to use a message queue to pass the debug info from the
  1308 // child threads back to the parent for the parent to then call printf.
  1309 //
  1310 //
  1311 
  1312 LOCAL_C TInt PerformTestThread(TInt					  aThreadIndex, 
  1313 							   RMsgQueue<TMessageBuf> *aMsgQueue = NULL, 
  1314 							   TMessageBuf			 *aBuffer = NULL,
  1315 							   RSemaphore			 *aTheSem = NULL)
  1316 	{
  1317 	TUint start = User::TickCount();
  1318 
  1319 	TFullName n(RThread().Name());
  1320 
  1321 	DEBUG_PRINT((_L("%S : thread %d Executing %S\n"), &TestNameBuffer, aThreadIndex, &n));
  1322 	
  1323 	// now select how we do the test...
  1324 	TInt	iterIndex;
  1325 
  1326 	PageLdrRLibrary    *pTheLibs = theGlobalLibs;
  1327 	TInt				maxDllIndex = GetNumDlls();
  1328 
  1329 	switch (TestLoadDllHow)
  1330 		{
  1331 		case TEST_DLL_THREAD:
  1332 			pTheLibs = NULL;
  1333 			DOLOADALLOC(maxDllIndex, pTheLibs, aTheSem);
  1334 			if (pTheLibs)
  1335 				{
  1336 				TInt retVal = LoadTheLibs(pTheLibs, maxDllIndex, aThreadIndex, aMsgQueue, aBuffer, aTheSem);
  1337 				if (retVal != KErrNone)
  1338 					{
  1339 					DEBUG_PRINT((_L("Perform[%d] - load fail\n"), aThreadIndex));
  1340 					CloseTheLibs (pTheLibs, maxDllIndex);
  1341 					User::Free(pTheLibs);
  1342 					return retVal;
  1343 					}
  1344 				}
  1345 			else
  1346 				{
  1347 				DEBUG_PRINT((_L("Perform[%d] - alloc fail\n"), aThreadIndex));
  1348 				return KErrGeneral;
  1349 				}
  1350 		break;
  1351 
  1352 		case TEST_DLL_GLOBAL:
  1353 			pTheLibs = theGlobalLibs;
  1354 		break;
  1355 
  1356 		case TEST_DLL_FUNC:
  1357 		default:
  1358 		// do nowt
  1359 		break;
  1360 		}
  1361 
  1362 	TInt    retVal = KErrNone;
  1363 	if (TEST_ALL == (TestWhichTests & TEST_ALL))
  1364 		{
  1365 		#define LOCAL_ORDER_INDEX1	6
  1366 		#define LOCAL_ORDER_INDEX2	3
  1367 		TInt	order[LOCAL_ORDER_INDEX1][LOCAL_ORDER_INDEX2] = {	{TEST_FORWARD, TEST_BACKWARD,TEST_RANDOM},
  1368 																	{TEST_FORWARD, TEST_RANDOM,  TEST_BACKWARD},
  1369 																	{TEST_BACKWARD,TEST_FORWARD, TEST_RANDOM},
  1370 																	{TEST_BACKWARD,TEST_RANDOM,  TEST_FORWARD},
  1371 																	{TEST_RANDOM,  TEST_FORWARD, TEST_BACKWARD},
  1372 																	{TEST_RANDOM,  TEST_BACKWARD,TEST_FORWARD}};
  1373 		TInt	whichOrder = 0;
  1374 
  1375 		for (iterIndex = 0; ; )
  1376 			{
  1377 			TInt    selOrder = ((aThreadIndex + 1) * (iterIndex + 1)) % LOCAL_ORDER_INDEX1;
  1378 			for (whichOrder = 0; whichOrder < LOCAL_ORDER_INDEX2; whichOrder ++)
  1379 				{
  1380 				switch (order[selOrder][whichOrder])
  1381 					{
  1382 						case TEST_FORWARD:
  1383 						DEBUG_PRINT((_L("%S : %d Iter %d.%d Forward\n"),
  1384 							&TestNameBuffer, aThreadIndex, iterIndex, whichOrder));
  1385 						retVal = RunThreadForward(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem);
  1386 						break;
  1387 
  1388 						case TEST_BACKWARD:
  1389 						DEBUG_PRINT((_L("%S : %d Iter %d.%d Backward\n"),
  1390 							&TestNameBuffer, aThreadIndex, iterIndex, whichOrder));
  1391 						retVal = RunThreadBackward(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem);
  1392 						break;
  1393 
  1394 						case TEST_RANDOM:
  1395 						DEBUG_PRINT((_L("%S : %d Iter %d.%d Random\n"),
  1396 							&TestNameBuffer, aThreadIndex, iterIndex, whichOrder));
  1397 						retVal = RunThreadRandom(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem);
  1398 						break;
  1399 						
  1400 						default: // this is really an error.
  1401 						break;
  1402 					}
  1403 				DEBUG_PRINT((_L("%S : %d Iter %d.%d finished %d\n"),
  1404 					&TestNameBuffer, aThreadIndex, iterIndex, whichOrder, retVal));
  1405 				if ((retVal == KErrCancel) && iterIndex > 0)
  1406 					retVal = KErrNone;
  1407 				if ((retVal != KErrNone) || TestThreadsExit)
  1408 					break;
  1409 				}
  1410 			if ((retVal != KErrNone) || TestThreadsExit)
  1411 				break;
  1412 			if (++iterIndex >= TestMaxLoops)
  1413 				break;
  1414 			User::AfterHighRes(TEST_DOT_PERIOD/3*1000000);
  1415 			}
  1416 		}
  1417 	else
  1418 		{
  1419 		if (TestWhichTests & TEST_FORWARD)
  1420 			{
  1421 			for (iterIndex = 0; ; )
  1422 				{
  1423 				DEBUG_PRINT((_L("%S : %d Iter %d Forward\n"), &TestNameBuffer, aThreadIndex, iterIndex));
  1424 				retVal = RunThreadForward(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem);
  1425 				DEBUG_PRINT((_L("%S : %d Iter %d finished %d\n"), &TestNameBuffer, aThreadIndex, iterIndex, retVal));
  1426 				if ((retVal == KErrCancel) && iterIndex > 0)
  1427 					retVal = KErrNone;
  1428 				if ((retVal != KErrNone) || TestThreadsExit)
  1429 					break;
  1430 				if (++iterIndex >= TestMaxLoops)
  1431 					break;
  1432 				User::AfterHighRes(TEST_DOT_PERIOD/3*1000000);
  1433 				}
  1434 			}
  1435 			
  1436 		if (TestWhichTests & TEST_BACKWARD)
  1437 			{
  1438 			for (iterIndex = 0; ; )
  1439 				{
  1440 				DEBUG_PRINT((_L("%S : %d Iter %d Backward\n"), &TestNameBuffer, aThreadIndex, iterIndex));
  1441 				retVal = RunThreadBackward(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem);
  1442 				DEBUG_PRINT((_L("%S : %d Iter %d finished %d\n"), &TestNameBuffer, aThreadIndex, iterIndex, retVal));
  1443 				if ((retVal == KErrCancel) && iterIndex > 0)
  1444 					retVal = KErrNone;
  1445 				if ((retVal != KErrNone) || TestThreadsExit)
  1446 					break;
  1447 				if (++iterIndex >= TestMaxLoops)
  1448 					break;
  1449 				User::AfterHighRes(TEST_DOT_PERIOD/3*1000000);
  1450 				}
  1451 			}
  1452 
  1453 		if (TestWhichTests & TEST_RANDOM)
  1454 			{
  1455 			for (iterIndex = 0; ; )
  1456 				{
  1457 				DEBUG_PRINT((_L("%S : %d Iter %d Random\n"), &TestNameBuffer, aThreadIndex, iterIndex));
  1458 				retVal = RunThreadRandom(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem);
  1459 				DEBUG_PRINT((_L("%S : %d Iter %d finished %d\n"), &TestNameBuffer, aThreadIndex, iterIndex, retVal));
  1460 				if ((retVal == KErrCancel) && iterIndex > 0)
  1461 					retVal = KErrNone;
  1462 				if ((retVal != KErrNone) || TestThreadsExit)
  1463 					break;
  1464 				if (++iterIndex >= TestMaxLoops)
  1465 					break;
  1466 				User::AfterHighRes(TEST_DOT_PERIOD/3*1000000);
  1467 				}
  1468 			}
  1469 		
  1470 		if (TestWhichTests & TEST_THRASH)
  1471 			{
  1472 			for (iterIndex = 0; ; )
  1473 				{
  1474 				DEBUG_PRINT((_L("%S : %d Iter %d Thrash Load\n"), &TestNameBuffer, aThreadIndex, iterIndex));
  1475 				retVal = ThrashThreadLoad(aThreadIndex, pTheLibs, maxDllIndex, aMsgQueue, aBuffer, aTheSem);
  1476 				DEBUG_PRINT((_L("%S : %d Iter %d finished %d\n"), &TestNameBuffer, aThreadIndex, iterIndex, retVal));
  1477 				if ((retVal == KErrCancel) && iterIndex > 0)
  1478 					retVal = KErrNone;
  1479 				if ((retVal != KErrNone) || TestThreadsExit)
  1480 					break;
  1481 				if (++iterIndex >= TestMaxLoops)
  1482 					break;
  1483 				User::AfterHighRes(TEST_DOT_PERIOD/3*1000000);
  1484 				}
  1485 			}
  1486 		}
  1487 
  1488 	if (TestLoadDllHow == TEST_DLL_THREAD)
  1489 		{
  1490 		CloseTheLibs(pTheLibs, maxDllIndex);
  1491 		User::Free(pTheLibs);
  1492 		}
  1493 
  1494 	DEBUG_PRINT((_L("%S : thread %d Exit (tick %u)\n"), &TestNameBuffer, aThreadIndex, User::TickCount() - start));
  1495 	return retVal;
  1496 	}
  1497 
  1498 
  1499 //
  1500 // MultipleTestThread
  1501 //
  1502 // Thread function, one created for each thread in a multiple thread test.
  1503 //
  1504 
  1505 LOCAL_C TInt MultipleTestThread(TAny* aUseTb)
  1506 	{
  1507 	TInt			ret;
  1508 	TMessageBuf		localBuffer;
  1509 
  1510 	if (TestInterleave)	
  1511 		{
  1512 		RThread				thisThread;
  1513 		thisThread.SetPriority((TThreadPriority) TEST_INTERLEAVE_PRIO);
  1514 		}
  1515 
  1516 	ret = PerformTestThread((TInt) aUseTb, &TestMsgQueue, &localBuffer, &TestMultiSem);
  1517 	if (!TestingChunks)
  1518 		{
  1519 		if (ret != KErrNone) 
  1520 			User::Panic(_L("LOAD"), KErrGeneral);
  1521 		}
  1522 	return KErrNone;
  1523 	}
  1524 
  1525 //
  1526 // StartExe
  1527 //
  1528 // Start an executable.
  1529 //
  1530 
  1531 TInt StartExe(RProcess& aTheProcesses, TRequestStatus* aPrStatus, TInt aIndex, TBool aLoadSelf, TBool aLowMem, RSemaphore *pTheSem = NULL)
  1532 	{
  1533 	TBuf<256>		buffer;
  1534 	TInt			testWhich = KTestMediaRom;
  1535 	//y_LIT(KTestDebug, "debug");
  1536 	_LIT(KTestSilent, "silent");
  1537 
  1538 	if ((TestWhichMedia & TEST_MEDIA_ALL) == TEST_MEDIA_ALL)
  1539 		testWhich = aIndex % KTestMediaCOUNT;
  1540 	else if ((TestWhichMedia & TEST_MEDIA_ALL) == TEST_MEDIA_ROM_BASE)
  1541 		testWhich = (aIndex & 1) ? KTestMediaBase : KTestMediaRom;
  1542 	else if (TestWhichMedia & TEST_MEDIA_BASE )
  1543 		testWhich = KTestMediaBase;
  1544 	else
  1545 		testWhich = KTestMediaRom;
  1546 
  1547 	if (!TestDllExesExist[testWhich])
  1548 		testWhich = KTestMediaBase;
  1549 
  1550 	buffer.Zero();
  1551 	TInt ret;
  1552 	if (aLoadSelf)
  1553 		{
  1554 		buffer.Format(_L("single random dll %S iters %d inst %d"),
  1555 			/* TestDebug ? &KTestDebug : */ &KTestSilent, TestMaxLoops, aIndex);
  1556 		if (TestExtremeChunks)
  1557 			buffer.Append(_L(" echunks"));
  1558 		else if (TestChunksPlus)
  1559 			buffer.Append(_L(" chunks prio"));
  1560 		if (TestChunkData == EFalse)
  1561 			buffer.Append(_L(" nochunkdata"));
  1562 		DBGS_PRINT((_L("%S : Starting Process %d %S %S\n"),
  1563 			&TestNameBuffer, aIndex, &TestPlExeNames[testWhich], &buffer));
  1564 		DOTEST1(ret,aTheProcesses.Create(TestPlExeNames[testWhich],buffer),KErrNone, KErrNoMemory);
  1565 		}
  1566 	else
  1567 		{
  1568 		buffer.Format(_L("single random %S iters %d inst %d"),
  1569 			/* TestDebug ? &KTestDebug : */ &KTestSilent, TestMaxLoops, aIndex);
  1570 		DBGS_PRINT((_L("%S : Starting Process %d %S %S\n"),
  1571 			&TestNameBuffer, aIndex, &TestPsExeNames[testWhich], &buffer));
  1572 		DOTEST1(ret,aTheProcesses.Create(TestPsExeNames[testWhich],buffer),KErrNone, KErrNoMemory);
  1573 		}
  1574 	if (ret == KErrNone)
  1575 		{
  1576 		if(aPrStatus)
  1577 			{
  1578 			aTheProcesses.Logon(*aPrStatus);
  1579 			RUNTEST1(*aPrStatus == KRequestPending);	
  1580 			}
  1581 		aTheProcesses.Resume();
  1582 		}
  1583 	return ret;
  1584 	}
  1585 
  1586 //
  1587 // PerformRomAndFileSystemAccessThread
  1588 // 
  1589 // Access the rom and dump it out to one of the writeable partitions...
  1590 // really just to make the media server a little busy during the test.
  1591 //
  1592 TInt PerformRomAndFileSystemAccessThread(TInt					aThreadId,
  1593 										 RMsgQueue<TMessageBuf> *aMsgQueue, 
  1594 										 TMessageBuf		   *aBuffer,
  1595 										 RSemaphore			   *aTheSem,
  1596 										 TBool					aLowMem)
  1597 	{
  1598 	RThread		 thisThread;
  1599 	TUint		 maxBytes = KMaxTUint;
  1600 	TInt		 startTime = User::TickCount();
  1601 	RSemaphore	*pTheSem = aTheSem;
  1602 	RFs fs;
  1603 	RFile file;
  1604 
  1605 	if (KErrNone != fs.Connect())
  1606 		{
  1607 		DEBUG_PRINT(_L("PerformRomAndFileSystemAccessThread : Can't connect to the FS\n"));
  1608 		return KErrGeneral;
  1609 		}
  1610 
  1611 	// get info about the ROM...
  1612 	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
  1613 	TUint8* start;
  1614 	TUint8* end;
  1615 	if(romHeader->iPageableRomStart)
  1616 		{
  1617 		start = (TUint8*)romHeader + romHeader->iPageableRomStart;
  1618 		end = start + romHeader->iPageableRomSize;
  1619 		}
  1620 	else
  1621 		{
  1622 		start = (TUint8*)romHeader;
  1623 		end = start + romHeader->iUncompressedSize;
  1624 		}
  1625 	if (end <= start)
  1626 		return KErrGeneral;
  1627 
  1628 	// read all ROM pages in a random order...and write out to file in ROFs
  1629 	TInt pageSize = 0;
  1630 	UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&pageSize,0);
  1631 
  1632 	TUint size = end - start - pageSize;
  1633 	if(size > maxBytes)
  1634 		size = maxBytes;
  1635 
  1636 	TUint32 random = 1 + aThreadId;
  1637 	TPtrC8  sourceData;
  1638 	TUint8* theAddr;
  1639 	HBufC8* checkData;
  1640 
  1641 	DOTEST((checkData = HBufC8::New(pageSize + 10)),
  1642 	       (checkData != NULL));
  1643 	
  1644 	if (!checkData)
  1645 		{
  1646 		DEBUG_PRINT((_L("RomAndFSThread %S : failed to alloc read buffer\n"), &TestNameBuffer));
  1647 		}
  1648 
  1649 	TInt		drvNum = (TestBootedFromMmc || TestOnlyFromMmc) ? FindMMCDriveNumber(fs) : FindFsNANDDrive(fs);
  1650 	TBuf<32>	filename;
  1651 	
  1652 	filename.Format(_L("?:\\Pageldrtst%d.tmp"), aThreadId);
  1653 	if (drvNum >= 0)
  1654 		{
  1655 		DEBUG_PRINT((_L("%S : Filename %S\n"), &TestNameBuffer, &filename));
  1656 		}
  1657 	else
  1658 		{
  1659 		DEBUG_PRINT((_L("RomAndFSThread : error getting drive num\n")));
  1660 		drvNum = 3; //make it 'd' by default.
  1661 		}
  1662 	filename[0] = 'a' + drvNum;
  1663 
  1664 #ifdef WANT_FS_CACHE_STATS 
  1665 	TInt allocatedSegmentCount = 0;
  1666 	TInt filesOnClosedQueue = 0;
  1667 #endif
  1668 	TInt ret;
  1669 	while(1)
  1670 		{
  1671 		for(TInt i = size / (pageSize); i>0; --i)
  1672 			{
  1673 			DEBUG_PRINT1((_L("%S : Opening the file\n"), &TestNameBuffer));
  1674 			DOTEST((ret = file.Replace(fs, filename, EFileWrite)),
  1675 				   (KErrNone == ret));
  1676 
  1677 			random = random * 69069 + 1;
  1678 			theAddr = (TUint8 *)(start + ((TInt64(random) * TInt64(size - pageSize)) >> 32));
  1679 			sourceData.Set(theAddr,pageSize);
  1680 			DEBUG_PRINT1((_L("%S : Writing the file\n"), &TestNameBuffer));
  1681 			ret = file.Write(sourceData);
  1682 			if (ret != KErrNone)
  1683 				{
  1684 				DEBUG_PRINT((_L("%S : Write returned error %d\n"), &TestNameBuffer, ret));
  1685 				}
  1686 			DEBUG_PRINT1((_L("%S : Closing the file\n"), &TestNameBuffer));
  1687 			file.Close();
  1688 			
  1689 			if (checkData)
  1690 				{
  1691 				TPtr8  theBuf = checkData->Des();
  1692 
  1693 #ifdef WANT_FS_CACHE_STATS 
  1694 				// Page cache
  1695 				TFileCacheStats stats1;
  1696 				TFileCacheStats stats2;
  1697 				ret = controlIo(fs,drvNum, KControlIoFileCacheStats, stats1);
  1698 				if ((ret != KErrNone) && (ret != KErrNotSupported))
  1699 					{
  1700 					DEBUG_PRINT((_L("%S : KControlIoFileCacheStats 1 failed %d\n"), &TestNameBuffer, ret));
  1701 					}
  1702 
  1703 				if (aThreadId & 1)
  1704 					{
  1705 					// flush closed files queue
  1706 					ret = fs.ControlIo(drvNum, KControlIoFlushClosedFiles);
  1707 					if (ret != KErrNone)
  1708 						{
  1709 						DEBUG_PRINT((_L("%S : KControlIoFlushClosedFiles failed %d\n"), &TestNameBuffer, ret));
  1710 						}
  1711 					}
  1712 				else
  1713 #endif //WANT_FS_CACHE_STATS 
  1714 					{
  1715 					// rename file to make sure it has cleared the cache.				
  1716 					TBuf<32>	newname;
  1717 					newname.Format(_L("d:\\Pageldrtst%d.temp"), aThreadId);
  1718 					if (drvNum >= 0)
  1719 						{
  1720 						newname[0] = 'a' + drvNum;
  1721 						}
  1722 					fs.Rename(filename, newname);
  1723 					filename = newname;
  1724 					}
  1725 #ifdef WANT_FS_CACHE_STATS 
  1726 				ret = controlIo(fs,drvNum, KControlIoFileCacheStats, stats2);
  1727 				if (ret != KErrNone && ret != KErrNotSupported)
  1728 					{
  1729 					DEBUG_PRINT((_L("%S : KControlIoFileCacheStats2 failed %d\n"), &TestNameBuffer, ret));
  1730 					}
  1731 
  1732 				allocatedSegmentCount = (allocatedSegmentCount > stats1.iAllocatedSegmentCount) ? allocatedSegmentCount : stats1.iAllocatedSegmentCount;
  1733 				filesOnClosedQueue = (filesOnClosedQueue > stats1.iFilesOnClosedQueue) ? filesOnClosedQueue : stats1.iFilesOnClosedQueue;
  1734 #endif //WANT_FS_CACHE_STATS 
  1735 
  1736 				DOTEST((ret = file.Open(fs, filename, EFileRead)),
  1737 					   (KErrNone == ret));
  1738 				// now read back the page that we wrote and compare with the source.
  1739 				ret = file.Read(0, theBuf, pageSize);
  1740 				if (ret == KErrNone)
  1741 					{		
  1742 					ret = sourceData.Compare(theBuf);
  1743 					if (ret != 0)
  1744 						{
  1745 						DEBUG_PRINT((_L("%S : read compare error %d\n"), &TestNameBuffer, ret));
  1746 						}
  1747 					}
  1748 				else
  1749 					{
  1750 					DEBUG_PRINT((_L("%S : failed read compare, error %d\n"), &TestNameBuffer, ret));
  1751 					}
  1752 				file.Close();
  1753 				}
  1754 			DEBUG_PRINT1((_L("%S : Deleting the file\n"), &TestNameBuffer));
  1755 			ret = fs.Delete(filename);
  1756 			if (KErrNone != ret)
  1757 				{
  1758 				DEBUG_PRINT((_L("%S [%d] Delete %S Failed %d!\n"), &TestNameBuffer, aThreadId, &filename, ret));
  1759 				}
  1760 		
  1761 			if (TestPrioChange)
  1762 				{
  1763 				TThreadPriority originalThreadPriority = thisThread.Priority();
  1764 				DEBUG_PRINT1((_L("%S [%d] media thread before priority change, stop = %d\n"), &TestNameBuffer, aThreadId, TestStopMedia));
  1765 				thisThread.SetPriority(EPriorityLess);
  1766 				User::AfterHighRes(0);
  1767 				thisThread.SetPriority(originalThreadPriority);
  1768 				DEBUG_PRINT1((_L("%S [%d] media thread after priority change, stop = %d\n"), &TestNameBuffer, aThreadId, TestStopMedia));
  1769 				}
  1770 			if (TestStopMedia)
  1771 				break;
  1772 			}
  1773 		if (TestStopMedia)
  1774 			break;
  1775 		}
  1776 
  1777 #ifdef WANT_FS_CACHE_STATS 
  1778 	DEBUG_PRINT((_L("%S : [%d] allocPageCount %d filesClosedQueue %d \n"),&TestNameBuffer, aThreadId,allocatedSegmentCount,filesOnClosedQueue));
  1779 #endif //WANT_FS_CACHE_STATS 
  1780 
  1781 	if (checkData)
  1782 		{
  1783 		delete checkData;
  1784 		}
  1785 	fs.Close();
  1786 	DEBUG_PRINT1((_L("Done in %d ticks\n"), User::TickCount() - startTime));
  1787 	return KErrNone;
  1788 	}
  1789 
  1790 //
  1791 // PerformFileSystemAccessThread
  1792 // 
  1793 // Access the rom and dump it out to one of the writeable partitions...
  1794 // really just to make the media server a little busy during the test.
  1795 //
  1796 TInt PerformFileSystemAccessThread(TInt					    aThreadId,
  1797 								   RMsgQueue<TMessageBuf>   *aMsgQueue, 
  1798 								   TMessageBuf	           *aBuffer,
  1799 								   RSemaphore			   *aTheSem,
  1800 								   TBool					aLowMem)
  1801 	{
  1802 	RThread		 thisThread;
  1803 	TInt		 startTime = User::TickCount();
  1804 	RSemaphore	*pTheSem = aTheSem;
  1805 	RFs			 fs;
  1806 	RFile		 file;
  1807 	if (KErrNone != fs.Connect())
  1808 		{
  1809 		DEBUG_PRINT(_L("PerformFileSystemAccessThread : Can't connect to the FS\n"));
  1810 		return KErrGeneral;
  1811 		}
  1812 
  1813 	// read all ROM pages in a random order...and write out to file in ROFs
  1814 	TInt pageSize = 0;
  1815 	UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&pageSize,0);
  1816 
  1817 	HBufC8* checkData;
  1818 	HBufC8* sourceData;
  1819 	TUint32 random = 1 + aThreadId;
  1820 	TInt	dataSize = pageSize + (pageSize / 2);
  1821 	
  1822 	DOTEST((sourceData = HBufC8::New(dataSize)),
  1823 	       (sourceData != NULL));
  1824 	if (!sourceData)
  1825 		{
  1826 		DEBUG_PRINT((_L("RomAndFSThread %S : failed to alloc read buffer\n"), &TestNameBuffer));
  1827 		fs.Close();
  1828 		return KErrGeneral;
  1829 		}
  1830 
  1831 	DOTEST((checkData = HBufC8::New(dataSize)),
  1832 	       (checkData != NULL));
  1833 	if (!checkData)
  1834 		{
  1835 		DEBUG_PRINT((_L("RomAndFSThread %S : failed to alloc read buffer\n"), &TestNameBuffer));
  1836 		}
  1837 
  1838 	TInt		drvNum = (TestBootedFromMmc || TestOnlyFromMmc) ? FindMMCDriveNumber(fs) : FindFsNANDDrive(fs);
  1839 	TBuf<32>	filename;
  1840 	
  1841 	if (drvNum < 0)
  1842 		{
  1843 		drvNum = 3; //make it 'd' by default.
  1844 		DEBUG_PRINT((_L("FSAccessThread : error getting drive num\n")));
  1845 		}
  1846 
  1847 #ifdef WANT_FS_CACHE_STATS 
  1848 	TInt allocatedSegmentCount = 0;
  1849 	TInt filesOnClosedQueue = 0;
  1850 #endif
  1851 	TInt fileIndex;
  1852 	TInt ret;
  1853 
  1854 	TPtr8  pBuf = sourceData->Des();
  1855 	
  1856 	while (1)
  1857 		{
  1858 		TUint32 randomStart = random;
  1859 		// write the file
  1860 		for (fileIndex = 0; fileIndex < TEST_NUM_FILES; fileIndex ++)
  1861 			{
  1862 			filename.Format(_L("%c:\\pldrtst%d_%d.tmp"), 'a' + drvNum, aThreadId, fileIndex);
  1863 
  1864 			DEBUG_PRINT1((_L("%S : Opening the file\n"), &TestNameBuffer));
  1865 
  1866 			DOTEST ((ret = file.Replace(fs, filename, EFileWrite)),
  1867 				   (KErrNone == ret));
  1868 
  1869 			pBuf.Zero();			
  1870 			if (fileIndex & 1)
  1871 				{
  1872 				TInt fillSize = dataSize / sizeof(TUint32);
  1873 				while (fillSize > 0)
  1874 					{
  1875 					random = random * 69069 + 1;
  1876 					pBuf.Append((const TUint8 *) &random, sizeof(random));
  1877 					fillSize --;
  1878 					}
  1879 				}
  1880 			else
  1881 				{
  1882 				pBuf.Fill('x',dataSize);
  1883 				}
  1884 		
  1885 
  1886 			DEBUG_PRINT1((_L("%S : Writing the file\n"), &TestNameBuffer));
  1887 			ret = file.Write(sourceData->Des());
  1888 			if (ret != KErrNone)
  1889 				{
  1890 				DEBUG_PRINT((_L("%S : Write returned error %d\n"), &TestNameBuffer, ret));
  1891 				}
  1892 			DEBUG_PRINT1((_L("%S : Closing the file\n"), &TestNameBuffer));
  1893 			file.Close();
  1894 			}
  1895 
  1896 		random = randomStart;
  1897 		// check the file
  1898 		for (fileIndex = 0; fileIndex < TEST_NUM_FILES; fileIndex ++)
  1899 			{
  1900 			filename.Format(_L("%c:\\pldrtst%d_%d.tmp"), 'a' + drvNum, aThreadId, fileIndex);
  1901 			
  1902 			if (checkData)
  1903 				{
  1904 				TPtr8  theBuf = checkData->Des();
  1905 
  1906 #ifdef WANT_FS_CACHE_STATS 
  1907 				// Page cache
  1908 				TFileCacheStats stats1;
  1909 				TFileCacheStats stats2;
  1910 				ret = controlIo(fs,drvNum, KControlIoFileCacheStats, stats1);
  1911 				if ((ret != KErrNone) && (ret != KErrNotSupported))
  1912 					{
  1913 					DEBUG_PRINT((_L("%S : KControlIoFileCacheStats 1 failed %d\n"), &TestNameBuffer, ret));
  1914 					}
  1915 
  1916 				if (aThreadId & 1)
  1917 					{
  1918 					// flush closed files queue
  1919 					ret = fs.ControlIo(drvNum, KControlIoFlushClosedFiles);
  1920 					if (ret != KErrNone)
  1921 						{
  1922 						DEBUG_PRINT((_L("%S : KControlIoFlushClosedFiles failed %d\n"), &TestNameBuffer, ret));
  1923 						}
  1924 					}
  1925 				else
  1926 #endif //WANT_FS_CACHE_STATS 
  1927 					{
  1928 					// rename file to make sure it has cleared the cache.				
  1929 					TBuf<32>	newname;
  1930 					newname.Format(_L("%c:\\pldrtst%d_%d.temp"), 'a' + drvNum, aThreadId, fileIndex);
  1931 					fs.Rename(filename, newname);
  1932 					filename = newname;
  1933 					}
  1934 #ifdef WANT_FS_CACHE_STATS 
  1935 				ret = controlIo(fs,drvNum, KControlIoFileCacheStats, stats2);
  1936 				if (ret != KErrNone && ret != KErrNotSupported)
  1937 					{
  1938 					DEBUG_PRINT((_L("%S : KControlIoFileCacheStats2 failed %d\n"), &TestNameBuffer, ret));
  1939 					}
  1940 				allocatedSegmentCount = (allocatedSegmentCount > stats1.iAllocatedSegmentCount) ? allocatedSegmentCount : stats1.iAllocatedSegmentCount;
  1941 				filesOnClosedQueue = (filesOnClosedQueue > stats1.iFilesOnClosedQueue) ? filesOnClosedQueue : stats1.iFilesOnClosedQueue;
  1942 #endif //WANT_FS_CACHE_STATS 
  1943 
  1944 				DOTEST((ret = file.Open(fs, filename, EFileRead)),
  1945 					   (KErrNone == ret));
  1946 				// now read back the page that we wrote and compare with the source.
  1947 				ret = file.Read(0, theBuf, dataSize);
  1948 				if (ret == KErrNone)
  1949 					{
  1950 					pBuf.Zero();			
  1951 					if (fileIndex & 1)
  1952 						{
  1953 						TInt fillSize = dataSize / sizeof(TUint32);
  1954 						while (fillSize > 0)
  1955 							{
  1956 							random = random * 69069 + 1;
  1957 							pBuf.Append((const TUint8 *) &random, sizeof(random));
  1958 							fillSize --;
  1959 							}
  1960 						}
  1961 					else
  1962 						{
  1963 						pBuf.Fill('x',dataSize);
  1964 						}
  1965 
  1966 					ret = sourceData->Des().Compare(theBuf);
  1967 					if (ret != 0)
  1968 						{
  1969 						DEBUG_PRINT((_L("%S :compare error %S %d\n"), &TestNameBuffer, &filename, ret));
  1970 						}
  1971 					}
  1972 				else
  1973 					{
  1974 					DEBUG_PRINT((_L("%S : failed read compare, error %d\n"), &TestNameBuffer, ret));
  1975 					}
  1976 				file.Close();
  1977 				}
  1978 			DEBUG_PRINT1((_L("%S : Deleting the file\n"), &TestNameBuffer));
  1979 			ret = fs.Delete(filename);
  1980 			if (KErrNone != ret)
  1981 				{
  1982 				DEBUG_PRINT((_L("%S [%d] Delete %S Failed %d!\n"), &TestNameBuffer, aThreadId, &filename, ret));
  1983 				}
  1984 			if (TestPrioChange)
  1985 				{
  1986 				TThreadPriority originalThreadPriority = thisThread.Priority();
  1987 				thisThread.SetPriority(EPriorityLess);
  1988 				User::AfterHighRes(0);
  1989 				thisThread.SetPriority(originalThreadPriority);
  1990 				}
  1991 			if (TestStopMedia)
  1992 				break;
  1993 			}
  1994 		if (TestStopMedia)
  1995 			break;
  1996 		}
  1997 #ifdef WANT_FS_CACHE_STATS 
  1998 	DEBUG_PRINT((_L("%S : [%d] allocPageCount %d filesClosedQueue %d \n"),&TestNameBuffer, aThreadId,allocatedSegmentCount,filesOnClosedQueue));
  1999 #endif //WANT_FS_CACHE_STATS 
  2000 
  2001 	if (checkData)
  2002 		{
  2003 		delete checkData;
  2004 		}
  2005 	delete sourceData;
  2006 	fs.Close();
  2007 	DEBUG_PRINT1((_L("Done in %d ticks\n"), User::TickCount() - startTime));
  2008 	return KErrNone;
  2009 	}
  2010 
  2011 //
  2012 // PerformRomAndFileSystemAccess
  2013 //
  2014 // Thread function, kicks off the file system access.
  2015 //
  2016 
  2017 LOCAL_C TInt PerformRomAndFileSystemAccess(TAny* aParam)
  2018 	{
  2019 	TMessageBuf			localBuffer;
  2020 	TInt				threadId = (TInt) aParam;
  2021 	TInt				retVal = KErrGeneral;
  2022 
  2023 	if (TestInterleave)	
  2024 		{
  2025 		RThread				thisThread;
  2026 		thisThread.SetPriority((TThreadPriority) TEST_INTERLEAVE_PRIO);
  2027 		}
  2028 
  2029 	switch (TestMediaAccess)
  2030 		{
  2031 		default:
  2032 		break;
  2033 		
  2034 		case KTestMediaAccessBasic:
  2035 		case KTestMediaAccessMultipleThreads:
  2036 			retVal = PerformRomAndFileSystemAccessThread(threadId, &TestMsgQueue, &localBuffer, &TestMultiSem, TestingLowMem);	
  2037 		break;
  2038 				
  2039 		case KTestMediaAccessMultiplePattern:
  2040 			retVal = PerformFileSystemAccessThread(threadId, &TestMsgQueue, &localBuffer, &TestMultiSem, TestingLowMem);
  2041 		break;
  2042 
  2043 		case KTestMediaAccessMixed:
  2044 			if (threadId < ((TestMultipleThreadCount + 1) / 2))
  2045 				retVal = PerformRomAndFileSystemAccessThread(threadId, &TestMsgQueue, &localBuffer, &TestMultiSem, TestingLowMem);	
  2046 			else
  2047 				retVal = PerformFileSystemAccessThread(threadId, &TestMsgQueue, &localBuffer, &TestMultiSem, TestingLowMem);
  2048 		break;
  2049 		}
  2050 	return retVal;
  2051 	}
  2052 
  2053 
  2054 //
  2055 // DisplayTestBanner
  2056 // 
  2057 // Output a header showing the test parameters.
  2058 //
  2059 
  2060 void DisplayTestBanner(TBool aMultiple)
  2061 	{
  2062 	DBGS_PRINT((_L("%S : what = %S%S%S(0x%x), media = %S%S%S(0x%x)\n"),
  2063 				aMultiple ? &KMultipleTest : &KSingleTest,
  2064 				TestLoading & TEST_EXE ? &KTestExe : &KTestBlank,
  2065  				TestLoading & TEST_DLL ? &KTestDll : &KTestBlank,
  2066  				TestLoading & TEST_SELF ? &KTestSelf : &KTestBlank,
  2067 				TestLoading,
  2068 				TestWhichMedia & TEST_MEDIA_BASE ? &KTestBase : &KTestBlank,
  2069 				TestWhichMedia & TEST_MEDIA_ROM ? &KTestRom : &KTestBlank,
  2070 				(TestWhichMedia & TEST_MEDIA_ALL) == TEST_MEDIA_ALL ? &KTestAll : &KTestBlank,
  2071 				TestWhichMedia));
  2072 	DBGS_PRINT((_L("         : maxLoops = %d, threads = %d, loadHow = %S (0x%x)\n"),
  2073 				TestMaxLoops,
  2074 				TestMultipleThreadCount,
  2075 				TestLoadDllHow == TEST_DLL_GLOBAL ? &KTestGlobal : TestLoadDllHow == TEST_DLL_THREAD ? &KTestThread : &KTestFunc, TestLoadDllHow));
  2076 	DBGS_PRINT((_L("         : options = %S%S%S%S%S%S, which = %S%S%S%S (0x%x)\n"),
  2077 				TestInterleave ? &KTestInter : &KTestBlank,
  2078 				TestPrioChange ? &KTestPrio: &KTestBlank,
  2079 				(TestMediaAccess == KTestMediaAccessNone) ? &KTestBlank : &KTestMedia,
  2080 				TestingLowMem ? &KTestLowMem : &KTestBlank, 
  2081 				TestExtremeChunks ? &KTestEChunking : TestChunksPlus ? &KTestChunkingPlus : TestingChunks ? &KTestChunking : &KTestBlank, 
  2082 				TestingReaper ? &KTestReaper : &KTestBlank, 
  2083 				TestWhichTests & TEST_THRASH ? &KTestThrash : &KTestBlank,
  2084 				TestWhichTests & TEST_FORWARD ? &KTestForward : &KTestBlank,
  2085 				TestWhichTests & TEST_BACKWARD ? &KTestBackward : &KTestBlank,
  2086 				TestWhichTests & TEST_RANDOM ? &KTestRandom : &KTestBlank,
  2087 				TestWhichTests));
  2088 	}
  2089 
  2090 //
  2091 // DoSingleTest
  2092 // 
  2093 // Perform the single thread test, spawning a number of threads.
  2094 //
  2095 
  2096 LOCAL_C TInt DoSingleTest(TBool aLowMem = EFalse)
  2097 	{
  2098 	TUint        start = User::TickCount();
  2099 	RSemaphore	*pTheSem = NULL;
  2100 	TInt ret = KErrNone;
  2101 	DisplayTestBanner(EFalse);
  2102 
  2103 	if (aLowMem)
  2104 		{
  2105 		DOTEST1(ret,TestMultiSem.CreateLocal(1),KErrNone, KErrNoMemory);
  2106 		pTheSem = &TestMultiSem;
  2107 		}
  2108 	if (TestLoading & TEST_EXE)
  2109 		{
  2110 		RProcess		theProcess;
  2111 		TRequestStatus	status;
  2112 		
  2113 		if (StartExe(theProcess, &status, 0, EFalse, aLowMem, pTheSem) == KErrNone)
  2114 			{
  2115 			User::WaitForRequest(status);
  2116 			if (theProcess.ExitType() == EExitPanic)
  2117 				{
  2118 				DBGS_PRINT((_L("%S : Process Panic'd...\n"), &TestNameBuffer));	
  2119 				}
  2120 			theProcess.Close();
  2121 			}
  2122 		}
  2123 
  2124 	if (TestLoading & TEST_SELF)
  2125 		{
  2126 		RProcess		theProcess;
  2127 		TRequestStatus	status;
  2128 		
  2129 		if (StartExe(theProcess, &status, 0, ETrue, aLowMem,pTheSem) == KErrNone)
  2130 			{
  2131 			User::WaitForRequest(status);
  2132 			if (theProcess.ExitType() == EExitPanic)
  2133 				{
  2134 				DBGS_PRINT((_L("%S : Process Panic'd...\n"), &TestNameBuffer));
  2135 				}
  2136 			theProcess.Close();
  2137 			}
  2138 		}
  2139 
  2140 	if (TestLoading	& TEST_DLL)
  2141 		{
  2142 		TInt maxDlls = GetNumDlls();
  2143 		if (TestLoadDllHow == TEST_DLL_GLOBAL)
  2144 			{
  2145 			TInt retVal = LoadTheLibs(theGlobalLibs, maxDlls, TestInstanceId, NULL, NULL, pTheSem);
  2146 			if (retVal != KErrNone)
  2147 				{
  2148 				DBGS_PRINT((_L("DoSingleTest - unable to load libs\n") ));
  2149 				CloseTheLibs (theGlobalLibs, PAGELDRTST_MAX_DLLS);
  2150 				if (aLowMem)
  2151 					{
  2152 					TestMultiSem.Close();
  2153 					}
  2154 				return KErrGeneral;
  2155 				}
  2156 			}
  2157 
  2158 		ret = PerformTestThread((TInt) TestInstanceId, NULL, NULL, pTheSem);
  2159 
  2160 		if (TestLoadDllHow == TEST_DLL_GLOBAL)
  2161 			{
  2162 			CloseTheLibs(theGlobalLibs, maxDlls);
  2163 			}
  2164 		}
  2165 	if (aLowMem)
  2166 		{
  2167 		TestMultiSem.Close();
  2168 		}
  2169 
  2170 	if (!TestSilent)
  2171 		{
  2172 		TInt end = User::TickCount();
  2173 		TInt time = TUint((TUint64)(end-start)*(TUint64)TickPeriod/(TUint64)1000000);
  2174 		DBGS_PRINT((_L("\n%S : Single Test : (%u seconds)\n"), &TestNameBuffer, time));
  2175 		}
  2176 
  2177 	return ret;
  2178 	}
  2179 
  2180 //
  2181 // FillPage
  2182 //
  2183 // Fill a page with test data
  2184 //
  2185 
  2186 void FillPage(TUint aOffset)
  2187 	{
  2188 	if (TestChunkData)
  2189 		{
  2190 		TUint32* ptr = (TUint32 *)((TUint8 *)TestChunkBase+aOffset);
  2191 		TUint32* ptrEnd = (TUint32 *)((TUint8 *)ptr + TestPageSize);
  2192 		do 
  2193 			{
  2194 			*ptr = 0x55000000 + aOffset;
  2195 			ptr ++;
  2196 			aOffset += 4;
  2197 			}
  2198 		while(ptr<ptrEnd);
  2199 		}
  2200 	}
  2201 
  2202 //
  2203 // CheckPage
  2204 //
  2205 // Check a page matches test data....
  2206 //
  2207 
  2208 TBool CheckPage(TUint index, TUint aOffset)
  2209 	{
  2210 	TBool ret = ETrue;
  2211 	if (TestChunkData)
  2212 		{
  2213 		TUint32* ptr = (TUint32 *)((TUint8 *)TestChunkBase+aOffset);
  2214 		TUint32* ptrEnd = (TUint32 *)((TUint8 *)ptr + TestPageSize);
  2215 		do
  2216 			{
  2217 			if (*ptr != (0x55000000 + aOffset)) 
  2218 				break;
  2219 			ptr ++;
  2220 			aOffset += 4;
  2221 			}
  2222 		while(ptr<ptrEnd);
  2223 		if (ptr==ptrEnd)
  2224 			{
  2225 			TestChunkStats[index].check.ok ++;
  2226 			}
  2227 		else
  2228 			{
  2229 			TestChunkStats[index].check.fail ++;
  2230 			ret = EFalse;
  2231 			}
  2232 		}
  2233 	return ret;
  2234 	}
  2235 
  2236 //
  2237 // DoSomeChunking
  2238 //
  2239 // Lock and unlock various pages in a chunk...
  2240 //
  2241 TUint   TestChunkingIndex = 0;
  2242 TUint   TestChunkingIndexFails = 0;
  2243 
  2244 void DoSomeChunking()
  2245 	{
  2246 	TUint       iters = TEST_NUM_CHUNK_PAGES / 4;
  2247 	TBool		lockit = EFalse;
  2248 	TBool		decomit = EFalse;
  2249 	TUint		index;
  2250 	TInt		ret;
  2251 	TInt		theOffset;
  2252 	
  2253 	while (iters)
  2254 		{
  2255 		TestChunkingIndex = TestChunkingIndex * 69069 + 1;
  2256 		index = TUint64((TUint64)TestChunkingIndex*(TUint64)TEST_NUM_CHUNK_PAGES)>>32;
  2257 		if (index >= TEST_NUM_CHUNK_PAGES)
  2258 			TestChunkingIndexFails ++;
  2259 
  2260 		theOffset = index * TestPageSize;
  2261 		if (theOffset < TestCommitEnd)
  2262 			{
  2263 			if (lockit)
  2264 				{
  2265 				if (decomit)
  2266 					{
  2267 					ret = TestChunk.Decommit(theOffset,TestPageSize);
  2268 					if (KErrNone == ret)
  2269 						TestChunkStats[index].decommit.ok ++;
  2270 					else
  2271 						TestChunkStats[index].decommit.fail ++;
  2272 					ret = TestChunk.Commit(theOffset,TestPageSize);
  2273 					if (KErrNone == ret)
  2274 						{
  2275 						TestChunkStats[index].commit.ok ++;
  2276 						FillPage(theOffset);
  2277 						TestChunkPageState[index] = ETrue;
  2278 						}
  2279 					else
  2280 						{
  2281 						TestChunkStats[index].commit.fail ++;
  2282 						TestChunkPageState[index] = EFalse;
  2283 						}
  2284 					ret = KErrNone;
  2285 					}
  2286 				else
  2287 					{
  2288 					ret = TestChunk.Lock(theOffset,TestPageSize);
  2289 					if (KErrNone == ret)
  2290 						{
  2291 						TestChunkStats[index].lock.ok ++;
  2292 						if (!CheckPage(index, theOffset))
  2293 							FillPage(theOffset);
  2294 						TestChunkPageState[index] = ETrue;
  2295 						}
  2296 					else
  2297 						{
  2298 						TestChunkStats[index].lock.fail ++;
  2299 						TestChunkPageState[index] = EFalse;
  2300 						}
  2301 					}
  2302 				decomit = !decomit;
  2303 				}
  2304 			else
  2305 				{
  2306 				if (TestChunkPageState[index])
  2307 					{
  2308 					// this one should still be locked so the data should be ok.
  2309 					if (KErrNone == TestChunk.Lock(theOffset,TestPageSize))
  2310 						{				
  2311 						TestChunkStats[index].lock.ok ++;
  2312 						CheckPage(index, theOffset);
  2313 						}
  2314 					else
  2315 						TestChunkStats[index].lock.fail ++;
  2316 					}
  2317 				ret = TestChunk.Unlock(theOffset,TestPageSize);
  2318 				if (KErrNone == ret)
  2319 					TestChunkStats[index].unlock.ok ++;
  2320 				else
  2321 					TestChunkStats[index].unlock.fail ++;
  2322 				TestChunkPageState[index] = EFalse;
  2323 				}
  2324 			if (KErrNone != ret)			
  2325 				{
  2326 				// so now we need to commit another page in this pages place.
  2327 				ret = TestChunk.Commit(theOffset,TestPageSize);
  2328 				if (KErrNone != ret)
  2329 					{
  2330 					TestChunkStats[index].commit.fail ++;
  2331 					//DBGS_PRINT((_L("%S : DoSomeChunking[%03d] index %03d failed to commit a page  %d\n"), &TestNameBuffer, iters, index, ret));
  2332 					TestChunkPageState[index] = EFalse;
  2333 					}
  2334 				else
  2335 					{
  2336 					TestChunkStats[index].commit.ok ++;
  2337 					FillPage(theOffset);
  2338 					TestChunkPageState[index] = ETrue;
  2339 					}
  2340 				}
  2341 			lockit = !lockit;
  2342 			}
  2343 		else
  2344 			{
  2345 			RDebug::Printf("DoSomeChunking - offset was bad %d / %d", theOffset, TestCommitEnd);
  2346 			}
  2347 		iters --;
  2348 		}
  2349 	}
  2350 
  2351 //
  2352 // DoMultipleTest
  2353 // 
  2354 // Perform the multiple thread test, spawning a number of threads.
  2355 // It is complicated a little because test.Printf can only be called from the first thread that calls it 
  2356 // so if we are using multiple threads we need to use a message queue to pass the debug info from the
  2357 // child threads back to the parent for the parent to then call printf.
  2358 //
  2359 
  2360 TInt DoMultipleTest(TBool aLowMem = EFalse)
  2361 	{
  2362 	TInt			 index;
  2363 	TUint            start = User::TickCount();
  2364 	RThread			*pTheThreads = NULL;
  2365 	TInt			*pThreadInUse = NULL;
  2366 
  2367 	RProcess		*pTheProcesses = NULL;
  2368 	TInt			*pProcessInUse = NULL;
  2369 
  2370 	RThread			*pMedThreads = NULL;
  2371 	TInt			*pMedInUse = NULL;
  2372 
  2373 	TRequestStatus	mediaStatus;
  2374 	RThread			mediaThread;
  2375 	TInt ret;
  2376 
  2377 	RSemaphore	*pTheSem = NULL;
  2378 
  2379 	DisplayTestBanner(ETrue);
  2380 	
  2381 	TestThreadsExit = EFalse;
  2382 
  2383 	DOTEST1(ret,TestMultiSem.CreateLocal(1),KErrNone, KErrNoMemory);
  2384 	
  2385 	pTheSem = &TestMultiSem;
  2386 	if (TestLoading & TEST_DLL)
  2387 		{
  2388 		DOTEST((pTheThreads  = (RThread *)User::AllocZ(sizeof(RThread) * TestMultipleThreadCount)),
  2389 		       (pTheThreads != NULL))
  2390 		DOTEST((pThreadInUse = (TInt *)User::AllocZ(sizeof(TInt) * TestMultipleThreadCount)),
  2391 		       (pThreadInUse != NULL));
  2392 		RUNTEST1(pTheThreads && pThreadInUse);
  2393 		if (!(pTheThreads && pThreadInUse))
  2394 			return KErrGeneral;
  2395 		}
  2396 
  2397 	if (TestLoading & TEST_EXE_SELF)
  2398 		{
  2399 		DOTEST((pTheProcesses = (RProcess *)User::AllocZ(sizeof(RProcess) * TestMultipleThreadCount)),
  2400 		       (pTheProcesses != NULL));
  2401 		DOTEST((pProcessInUse = (TInt *)User::AllocZ(sizeof(TInt) * TestMultipleThreadCount)),
  2402 		       (pProcessInUse != NULL));
  2403 		RUNTEST1(pTheProcesses && pProcessInUse);
  2404 		if (!(pTheProcesses && pProcessInUse))
  2405 			return KErrGeneral;
  2406 		}
  2407 	
  2408 	if (!TestSilent)
  2409 		{
  2410 		DOTEST1(ret,TestMsgQueue.CreateLocal(TestMultipleThreadCount * 10, EOwnerProcess),KErrNone, KErrNoMemory);
  2411 		if (ret != KErrNone)
  2412 			return KErrGeneral;
  2413 		}
  2414 
  2415 	if (TestMediaAccess != KTestMediaAccessNone)
  2416 		{
  2417 		if (TestMediaAccess != KTestMediaAccessBasic)
  2418 			{
  2419 			TestStopMedia = EFalse;
  2420 			DOTEST((pMedThreads  = (RThread *)User::AllocZ(sizeof(RThread) * TestMultipleThreadCount)),
  2421 				   (pMedThreads != NULL))
  2422 			DOTEST((pMedInUse = (TInt *)User::AllocZ(sizeof(TInt) * TestMultipleThreadCount)),
  2423 				   (pMedInUse != NULL));
  2424 			RUNTEST1(pMedThreads && pMedInUse);
  2425 			if (!(pMedThreads && pMedInUse))
  2426 				return KErrGeneral;
  2427 
  2428 			for (index = 0; index < TestMultipleThreadCount; index++)
  2429 				{
  2430 				DBGS_PRINT((_L("%S : Starting Media Thread %d\n"), &TestNameBuffer, index));
  2431 				DOTEST1(ret,pMedThreads[index].Create(KTestBlank,PerformRomAndFileSystemAccess,KDefaultStackSize,NULL,(TAny*) index),KErrNone, KErrNoMemory);
  2432 				if (ret == KErrNone)
  2433 					{
  2434 					pMedThreads[index].Resume();
  2435 					pMedInUse[index] = 1;
  2436 					}
  2437 				User::AfterHighRes(0);
  2438 				}
  2439 			}
  2440 		else
  2441 			{
  2442 			TestStopMedia = EFalse;
  2443 			DOTEST1(ret,mediaThread.Create(KTestBlank,PerformRomAndFileSystemAccess,KDefaultStackSize,NULL,(TAny *) 0),KErrNone, KErrNoMemory);
  2444 			if (ret == KErrNone)
  2445 				{
  2446 				mediaThread.Logon(mediaStatus);
  2447 				RUNTEST1(mediaStatus == KRequestPending);	
  2448 				mediaThread.Resume();
  2449 				}
  2450 			}
  2451 		}
  2452 
  2453 	TInt maxDlls = GetNumDlls();
  2454 	if (TestLoadDllHow == TEST_DLL_GLOBAL)
  2455 		{
  2456 		TInt retVal = LoadTheLibs(theGlobalLibs, maxDlls, 0, NULL, NULL, NULL);
  2457 		if (retVal != KErrNone)
  2458 			{
  2459 			DBGS_PRINT((_L("DoMultipleTest - unable to load libs\n")));
  2460 			CloseTheLibs (theGlobalLibs, maxDlls);
  2461 			if (!TestSilent)
  2462 				{
  2463 				TestMsgQueue.Close();
  2464 				}
  2465 			TestMultiSem.Close();
  2466 			return KErrGeneral;
  2467 			}
  2468 		}
  2469 
  2470 	// make sure we have a priority higher than that of the threads we spawn...
  2471 	RThread thisThread;
  2472 	TThreadPriority savedThreadPriority = thisThread.Priority();
  2473 	const TThreadPriority KMainThreadPriority = EPriorityMuchMore;
  2474 	__ASSERT_COMPILE(KMainThreadPriority>TEST_INTERLEAVE_PRIO);
  2475 	thisThread.SetPriority(KMainThreadPriority);
  2476 	
  2477 
  2478 	for (index = 0; index < TestMultipleThreadCount; index++)
  2479 		{
  2480 		if (TestLoading & TEST_EXE_SELF)
  2481 			{
  2482 			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))
  2483 				{
  2484 				User::AfterHighRes(0);
  2485 				pProcessInUse[index] = 1;
  2486 				}
  2487 			}
  2488 		
  2489 	
  2490 		if (TestLoading & TEST_DLL)
  2491 			{
  2492 			DBGS_PRINT((_L("%S : Starting Thread %d\n"), &TestNameBuffer, index));
  2493 			DOTEST1(ret,pTheThreads[index].Create(KTestBlank,MultipleTestThread,KDefaultStackSize,NULL,(TAny*) index),KErrNone, KErrNoMemory);
  2494 			if (ret == KErrNone)
  2495 				{
  2496 				pTheThreads[index].Resume();
  2497 				User::AfterHighRes(0);
  2498 				pThreadInUse[index] = 1;
  2499 				}
  2500 			}
  2501 		}
  2502 
  2503 	// wait for any child threads to exit and process any debug messages they pass back to the parent.
  2504 	TBool		anyUsed = ETrue;
  2505 	TMessageBuf	localBuffer;
  2506 	
  2507 	TInt		processOk = 0;
  2508 	TInt		threadOk = 0;
  2509 	TInt		processPanic = 0;
  2510 	TInt		threadPanic = 0;
  2511 	TUint		end = start;
  2512 	TUint		now;
  2513 	TUint		time;
  2514 	TUint		killNext = 0;
  2515 	TUint		numDots = 0;
  2516 	TUint		maxDots = (10*60)/TEST_DOT_PERIOD;	// No individual test should take longer than 10 minutes!
  2517 													// Most have been tuned to take between 2 and 8 minutes.
  2518 													// The autotests should not take more than 120 minutes total.
  2519 
  2520 	while(anyUsed)
  2521 		{
  2522 		TInt threadCount = 0;
  2523 		TInt processCount = 0;
  2524 		anyUsed = EFalse;
  2525 
  2526 		// check the message queue and call printf if we get a message.
  2527 		if (!TestSilent)
  2528 			{
  2529 			while (KErrNone == TestMsgQueue.Receive(localBuffer))
  2530 				{
  2531 				DBGS_PRINT((localBuffer));
  2532 				}
  2533 			}
  2534 
  2535 		// walk through the thread list to check which are still alive.
  2536 		for (index = 0; index < TestMultipleThreadCount; index++)
  2537 			{
  2538 			if (TestLoading & TEST_DLL)
  2539 				{
  2540 				if (pThreadInUse[index])
  2541 					{
  2542 					if (pTheThreads[index].ExitType() != EExitPending)
  2543 						{
  2544 						if (pTheThreads[index].ExitType() == EExitPanic)
  2545 							{
  2546 							DBGS_PRINT((_L("%S : Thread %d Panic'd after %u ticks \n"),
  2547 								&TestNameBuffer, index, User::TickCount() - start));	
  2548 							threadPanic ++;
  2549 							}
  2550 						else
  2551 							{
  2552 							DBGS_PRINT((_L("%S : Thread %d Exited after %u ticks \n"),
  2553 								&TestNameBuffer, index, User::TickCount() - start));	
  2554 							threadOk ++;
  2555 							}
  2556 						pTheThreads[index].Close();
  2557 						pThreadInUse[index] = EFalse;
  2558 						}
  2559 					else
  2560 						{
  2561 						threadCount += 1;
  2562 						anyUsed = ETrue;
  2563 						if (TestThreadsExit)
  2564 							{
  2565 							now = User::TickCount();
  2566 							time = TUint((TUint64)(now-end)*(TUint64)TickPeriod/(TUint64)1000000);
  2567 							if (time > TEST_DOT_PERIOD)
  2568 								{
  2569 								DBGS_PRINT((_L("%S : Thread %d still running\n"), &TestNameBuffer, index));	
  2570 								}
  2571 							time = TUint((TUint64)(now-killNext)*(TUint64)TickPeriod/(TUint64)1000000);
  2572 							const TUint killTimeStep = (TEST_DOT_PERIOD+9)/10; // 1/10th of a dot
  2573 							if(time>TEST_DOT_PERIOD+killTimeStep)
  2574 								{
  2575 								killNext += killTimeStep*1000000/TickPeriod;
  2576 								DBGS_PRINT((_L("%S : killing Thread %d\n"), &TestNameBuffer, index));	
  2577 								pTheThreads[index].Kill(KErrNone);
  2578 								pTheThreads[index].Close();
  2579 								pThreadInUse[index] = EFalse;
  2580 								}
  2581 							}
  2582 						}
  2583 					}
  2584 				}
  2585 			if (TestLoading & TEST_EXE_SELF)
  2586 				{
  2587 				if (pProcessInUse[index])
  2588 					{
  2589 					if (pTheProcesses[index].ExitType() != EExitPending)
  2590 						{
  2591 						if (pTheProcesses[index].ExitType() == EExitPanic)
  2592 							{
  2593 							DBGS_PRINT((_L("%S : Process %d Panic'd after %u ticks \n"),
  2594 								&TestNameBuffer,
  2595 								index + ((TestLoading & TEST_DLL) ? TestMultipleThreadCount : 0),
  2596 								User::TickCount() - start));	
  2597 							processPanic ++;
  2598 							}
  2599 						else
  2600 							{
  2601 							DBGS_PRINT((_L("%S : Process %d Exited after %u ticks \n"),
  2602 								&TestNameBuffer,
  2603 								index + ((TestLoading & TEST_DLL) ? TestMultipleThreadCount : 0),
  2604 								User::TickCount() - start));	
  2605 							processOk ++;
  2606 							}
  2607 
  2608 						pTheProcesses[index].Close();
  2609 						pProcessInUse[index] = EFalse;
  2610 						}
  2611 					else
  2612 						{
  2613 						processCount += 1;
  2614 						anyUsed = ETrue;
  2615 						if (TestThreadsExit)
  2616 							{
  2617 							now = User::TickCount();
  2618 							time = TUint((TUint64)(now-end)*(TUint64)TickPeriod/(TUint64)1000000);
  2619 							if (time > TEST_DOT_PERIOD)
  2620 								{
  2621 								DBGS_PRINT((_L("%S : Process %d still running; killing it.\n"),
  2622 									&TestNameBuffer, index));
  2623 								pTheProcesses[index].Kill(EExitKill);
  2624 								pTheProcesses[index].Close();
  2625 								pProcessInUse[index] = EFalse;
  2626 								}
  2627 							
  2628 							}
  2629 						}
  2630 					}
  2631 				}
  2632 			}
  2633 
  2634 		now = User::TickCount();
  2635 		time = TUint((TUint64)(now-end)*(TUint64)TickPeriod/(TUint64)1000000);
  2636 
  2637 		DBGD_PRINT((_L("%S : %d seconds (%d ticks) %d threads, %d processes still alive\n"),
  2638 			&TestNameBuffer, time, now, threadCount, processCount));
  2639 
  2640 		if (time > TEST_DOT_PERIOD)
  2641 			{
  2642 			DBGS_PRINT((_L(".")));
  2643 			numDots ++;
  2644 			end += TEST_DOT_PERIOD*1000000/TickPeriod;
  2645 			if (TestingReaper)
  2646 				{
  2647 				TestingReaperCleaningFiles = ETrue;
  2648 				CleanupFiles(EFalse);
  2649 				CheckFilePresence(ETrue);
  2650 				TestingReaperCleaningFiles = EFalse;
  2651 				}
  2652 			if ((numDots >= maxDots) && (!TestThreadsExit))
  2653 				{
  2654 				DBGS_PRINT((_L("Taking longer than %d dots...exiting test case."), maxDots));
  2655 				TestThreadsExit = ETrue;
  2656 				killNext = end;
  2657 				}
  2658 			}
  2659 
  2660 		if (TestingChunks)
  2661 			{
  2662 			DoSomeChunking();
  2663 			}
  2664 
  2665 #ifdef TEST_THRASHING_TEST
  2666 		User::AfterHighRes(1000);
  2667 #else
  2668 		User::AfterHighRes(TickPeriod);
  2669 #endif
  2670 		}
  2671 
  2672 	DBGD_PRINT((_L("%S : all test threads presumably gone now\n"), &TestNameBuffer));
  2673 
  2674 	if (TestMediaAccess != KTestMediaAccessNone)
  2675 		{
  2676 		if (TestMediaAccess != KTestMediaAccessBasic)
  2677 			{
  2678 			TBool killMedia = EFalse;
  2679 			TestStopMedia = ETrue;
  2680 			anyUsed = ETrue;
  2681 			DBGS_PRINT((_L("%S : Waiting for media threads to exit...\n"), &TestNameBuffer));	
  2682 			end = User::TickCount();
  2683 			while (anyUsed)
  2684 				{
  2685 				anyUsed = EFalse;
  2686 
  2687 				// check the message queue and call printf if we get a message.
  2688 				if (!TestSilent)
  2689 					{
  2690 					while (KErrNone == TestMsgQueue.Receive(localBuffer))
  2691 						{
  2692 						DBGS_PRINT((localBuffer));
  2693 						}
  2694 					}
  2695 
  2696 				for (index = 0; index < TestMultipleThreadCount; index++)
  2697 					{
  2698 					if (pMedInUse[index])
  2699 						{
  2700 						if (pMedThreads[index].ExitType() != EExitPending)
  2701 							{
  2702 							if (pMedThreads[index].ExitType() == EExitPanic)
  2703 								{
  2704 								DBGS_PRINT((_L("%S : Media Thread %d Panic'd after %u ticks \n"),
  2705 									&TestNameBuffer, index, User::TickCount() - start));	
  2706 								threadPanic ++;
  2707 								}
  2708 							else
  2709 								{
  2710 								DBGS_PRINT((_L("%S : Media Thread %d Exited after %u ticks \n"),
  2711 									&TestNameBuffer, index, User::TickCount() - start));	
  2712 								threadOk ++;
  2713 								}
  2714 							pMedInUse[index] = EFalse;
  2715 							}
  2716 						else
  2717 							{
  2718 							anyUsed = ETrue;
  2719 							if (killMedia)
  2720 								{
  2721 								DBGS_PRINT((_L("%S : Media Thread %d still going after %u ticks; killing it!\n"),
  2722 									&TestNameBuffer, index, User::TickCount() - start));	
  2723 								pMedThreads[index].Kill(EExitKill);
  2724 								}
  2725 							}
  2726 						}
  2727 					}
  2728 				now = User::TickCount();
  2729 				time = TUint((TUint64)(now-end)*(TUint64)TickPeriod/(TUint64)1000000);
  2730 				if (time > TEST_DOT_PERIOD)
  2731 					{
  2732 					DBGS_PRINT((_L(".")));
  2733 					end += TEST_DOT_PERIOD*1000000/TickPeriod;
  2734 					killMedia = ETrue;
  2735 					}
  2736 
  2737 				User::AfterHighRes(50000);
  2738 
  2739 				}
  2740 			DBGS_PRINT((_L("%S : Media threads exited...\n"), &TestNameBuffer));	
  2741 			User::Free(pMedThreads);
  2742 			User::Free(pMedInUse);
  2743 			}
  2744 		else
  2745 			{
  2746 			TestStopMedia = ETrue;
  2747 			DBGS_PRINT((_L("%S : Waiting for media thread to exit...\n"), &TestNameBuffer));	
  2748 			end = User::TickCount();
  2749 			while (mediaThread.ExitType() == EExitPending)
  2750 				{
  2751 				now = User::TickCount();
  2752 				time = TUint((TUint64)(now-end)*(TUint64)TickPeriod/(TUint64)1000000);
  2753 				if (time > TEST_DOT_PERIOD)
  2754 					{
  2755 					DBGS_PRINT((_L("%S : Media thread still going after %u seconds; killing it!\n"),
  2756 						&TestNameBuffer, time));
  2757 					mediaThread.Kill(EExitKill);
  2758 					}
  2759 				User::AfterHighRes(50000);
  2760 				}
  2761 			User::WaitForRequest(mediaStatus);
  2762 			mediaThread.Close();
  2763 			DBGS_PRINT((_L("%S : Media thread exited...\n"), &TestNameBuffer));	
  2764 			}
  2765 		}
  2766 
  2767 	DBGD_PRINT((_L("%S : all media threads presumably gone now\n"), &TestNameBuffer));
  2768 
  2769 	if (!TestSilent)
  2770 		{
  2771 		TestMsgQueue.Close();
  2772 		}
  2773 	TestMultiSem.Close();
  2774 
  2775 	DBGD_PRINT((_L("%S : about to close the libraries\n"), &TestNameBuffer));
  2776 
  2777 	if (TestLoadDllHow == TEST_DLL_GLOBAL)
  2778 		{
  2779 		CloseTheLibs(theGlobalLibs, maxDlls);
  2780 		}
  2781 
  2782 	TestThreadsExit = EFalse;
  2783 
  2784 	DBGD_PRINT((_L("%S : cleaning up\n"), &TestNameBuffer));
  2785 
  2786 	// cleanup the resources and exit.
  2787 	if (TestLoading & TEST_EXE_SELF)
  2788 		{
  2789 		User::Free(pTheProcesses);
  2790 		User::Free(pProcessInUse);
  2791 		}
  2792 
  2793 	// cleanup the resources and exit.
  2794 	if (TestLoading & TEST_DLL)
  2795 		{
  2796 		User::Free(pTheThreads);
  2797 		User::Free(pThreadInUse);
  2798 		}
  2799 
  2800 	if (!TestSilent)
  2801 		{
  2802 		end = User::TickCount();
  2803 		time = TUint((TUint64)(end-start)*(TUint64)TickPeriod/(TUint64)1000000);
  2804 		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));
  2805 		}
  2806 
  2807 	thisThread.SetPriority(savedThreadPriority);
  2808 
  2809 	return (threadPanic | processPanic) ? KErrGeneral : KErrNone;
  2810 	}
  2811 
  2812 //
  2813 // DoChunkTests
  2814 //
  2815 // Allocate a chunk and assign some pages to it...
  2816 // Then do a multiple test.
  2817 //
  2818 
  2819 void DoChunkTests()
  2820 	{
  2821 	SVMCacheInfo  tempPages;
  2822 	memset(&tempPages, 0, sizeof(tempPages));
  2823 	if (TestIsDemandPaged)
  2824 		{
  2825 		// Shrink the page cache down to the minimum.
  2826 		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
  2827 
  2828 		DBGS_PRINT((_L("Start : min %d max %d current %d maxFree %d freeRam %d\n"),
  2829 					 tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize ,tempPages.iMaxFreeSize, FreeRam()));
  2830 
  2831 		// set the cache small 
  2832 		TInt minSize = 16 * TestPageSize;
  2833 		TInt maxSize = TEST_NUM_PAGES * TestPageSize;
  2834 		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
  2835 		}
  2836 
  2837 	if (KErrNone != TestChunk.CreateDisconnectedLocal(0,0,TEST_NUM_CHUNK_PAGES *TestPageSize))
  2838 		{
  2839 		DBGS_PRINT((_L("DoChunkTests - create failed.\n")));
  2840 		return;
  2841 		}
  2842 	TestChunkBase = TestChunk.Base();
  2843 	if (TestChunkBase == NULL)
  2844 		{
  2845 		RDebug::Printf("DoChunkTests - TestChunkBase was NULL");
  2846 		TestChunk.Close();
  2847 		return;
  2848 		}
  2849 	TInt retVal = KErrNone;
  2850 	TUint index = 0;
  2851 	TestCommitEnd = 0;
  2852 	memset(TestChunkPageState, 0, sizeof(TestChunkPageState));
  2853 	memset(TestChunkStats,0,sizeof(TestChunkStats));
  2854 	while(index < TEST_NUM_CHUNK_PAGES)
  2855 		{
  2856 		retVal = TestChunk.Commit(TestCommitEnd,TestPageSize);
  2857 		if (KErrNone != retVal)
  2858 			{
  2859 			DBGS_PRINT((_L("%S : TestChunk.Commit returned %d for 0x%08x...\n"), &TestNameBuffer, retVal, TestCommitEnd));	
  2860 			break;
  2861 			}
  2862 		TestChunkPageState[index] = ETrue;
  2863 		FillPage(TestCommitEnd);
  2864 		TestCommitEnd += TestPageSize;
  2865 		index ++;
  2866 		}
  2867 	RUNTEST1(retVal == KErrNone);
  2868 	
  2869 	// now do some testing....
  2870 	TestingChunks = ETrue;
  2871 	TestInterleave = EFalse;
  2872 	TestPrioChange = ETrue;
  2873 	TestMediaAccess = KTestMediaAccessNone;
  2874 	// temp
  2875 	TestWhichMedia = TEST_MEDIA_ROM_BASE;
  2876 
  2877 	if (TestChunksPlus)
  2878 		{
  2879 		TestMaxLoops = 1;
  2880 		TestMultipleThreadCount	= 40;
  2881 		}
  2882 	else if (TestExtremeChunks)
  2883 		{
  2884 		TestMaxLoops = 10;
  2885 		TestMultipleThreadCount	= 12;
  2886 		}
  2887 	else
  2888 		{
  2889 		TestMaxLoops = 3;
  2890 		TestMultipleThreadCount	= 20;
  2891 		}
  2892 	TestWhichTests = TEST_RANDOM;
  2893 
  2894 	TestLoading = TEST_EXE_SELF_DLL;
  2895 	TestLoadDllHow = TEST_DLL_FUNC;
  2896 	TestChunkingIndexFails = 0;
  2897 
  2898 	TEST_NEXT((_L("Multiple threads random with chunks.")));
  2899 	RUNTEST(DoMultipleTest(), KErrNone);
  2900 	
  2901 	TestingChunks = EFalse;
  2902 
  2903 	// clean up.
  2904 	UserSvr::HalFunction(EHalGroupVM,EVMHalFlushCache,0,0);
  2905 	TestChunk.Close();
  2906 
  2907 	if (TestIsDemandPaged)
  2908 		{
  2909 		// put the cache back to the the original values.
  2910 		TInt minSize = tempPages.iMinSize;
  2911 		TInt maxSize = tempPages.iMaxSize;
  2912 
  2913 		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
  2914 
  2915 		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
  2916 
  2917 		DBGS_PRINT((_L("Finish : min %d max %d current %d maxFree %d freeRam %d\n"),
  2918 					 tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize ,tempPages.iMaxFreeSize, FreeRam()));
  2919 		}
  2920 	TChunkTestStats  stats;
  2921 
  2922 	memset(&stats, 0, sizeof(stats));
  2923 	DBGS_PRINT((_L("Stats : (pass/fail) \nindex\t\tlock\t\tunlock\t\tcommit\t\tdecommit\t\tcheck\n")));
  2924 	for (index = 0; index < TEST_NUM_CHUNK_PAGES; index ++)
  2925 		{
  2926 		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"), 
  2927 					index,
  2928 					TestChunkStats[index].lock.ok, TestChunkStats[index].lock.fail,
  2929 					TestChunkStats[index].unlock.ok, TestChunkStats[index].unlock.fail,
  2930 					TestChunkStats[index].commit.ok, TestChunkStats[index].commit.fail,
  2931 					TestChunkStats[index].decommit.ok, TestChunkStats[index].decommit.fail,
  2932 					TestChunkStats[index].check.ok, TestChunkStats[index].check.fail));
  2933 
  2934 		stats.lock.ok += TestChunkStats[index].lock.ok;
  2935 		stats.lock.fail += TestChunkStats[index].lock.fail;
  2936 		stats.unlock.ok += TestChunkStats[index].unlock.ok;
  2937 		stats.unlock.fail += TestChunkStats[index].unlock.fail;
  2938 		stats.decommit.ok += TestChunkStats[index].decommit.ok;
  2939 		stats.decommit.fail += TestChunkStats[index].decommit.fail;
  2940 		stats.commit.ok += TestChunkStats[index].commit.ok;
  2941 		stats.commit.fail += TestChunkStats[index].commit.fail;
  2942 		stats.check.ok += TestChunkStats[index].check.ok;
  2943 		stats.check.fail += TestChunkStats[index].check.fail;
  2944 		}
  2945 
  2946 	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"), 
  2947 				stats.lock.ok, stats.lock.fail,
  2948 				stats.unlock.ok, stats.unlock.fail,
  2949 				stats.commit.ok, stats.commit.fail,
  2950 				stats.decommit.ok, stats.decommit.fail,
  2951 				stats.check.ok, stats.check.fail));
  2952 	DBGS_PRINT((_L("TestChunkingIndexFails %d\n"), TestChunkingIndexFails));
  2953 
  2954 	}
  2955 
  2956 //
  2957 // DoReaperTests
  2958 //
  2959 // Test the reaper by deleting the transient files and re-creating them.
  2960 //
  2961 
  2962 void DoReaperTests(void)
  2963 	{
  2964 	// make sure we have the full complement of files.
  2965 	CheckFilePresence(ETrue);
  2966 	
  2967 	// now do some testing....
  2968 	TestInterleave = EFalse;
  2969 	TestPrioChange = EFalse;
  2970 	TestMediaAccess = KTestMediaAccessNone;
  2971 	// temp
  2972 	TestWhichMedia = TEST_MEDIA_ALL;
  2973 	TestMaxLoops = 3;
  2974 	TestMultipleThreadCount	= 12;
  2975 	TestWhichTests = TEST_RANDOM;
  2976 
  2977 	TestLoading = TEST_EXE_SELF_DLL;
  2978 	TestLoadDllHow = TEST_DLL_FUNC;
  2979 	
  2980 	TestingReaper = ETrue;
  2981 
  2982 	TEST_NEXT((_L("Reaper tests.")));
  2983 	RUNTEST(DoMultipleTest(), KErrNone);
  2984 	TestInterleave = ETrue;
  2985 	TestPrioChange = ETrue;
  2986 	TEST_NEXT((_L("Reaper tests 2.")));
  2987 	RUNTEST(DoMultipleTest(), KErrNone);
  2988 	
  2989 	TestingReaper = EFalse;
  2990 	}
  2991 
  2992 //
  2993 // DoBtraceTest
  2994 //
  2995 // Test the paging BTrace function.
  2996 //
  2997 
  2998 void DoBtraceTest(void)
  2999 	{
  3000 #define LE4(a) ((*((a) + 3) << 24) + (*((a) + 2) << 16) + (*((a) + 1) << 8) + *(a))
  3001 
  3002 	RBTrace bTraceHandle;
  3003 	
  3004 	TInt r = bTraceHandle.Open();
  3005 	test(r == KErrNone);
  3006 	
  3007 	r = bTraceHandle.ResizeBuffer(0x200000); 
  3008 	test(r == KErrNone);
  3009 	bTraceHandle.SetFilter(BTrace::EPaging, ETrue);
  3010 
  3011 	// Enable trace
  3012 	bTraceHandle.Empty();
  3013 	bTraceHandle.SetMode(RBTrace::EEnable);
  3014 	
  3015 	TestLoading             = TEST_EXE_SELF_DLL;
  3016 	TestWhichMedia          = TEST_MEDIA_ROM_BASE;
  3017 	TestMaxLoops            = 2;
  3018 	TestMultipleThreadCount = 10;
  3019 	TestLoadDllHow          = TEST_DLL_FUNC;
  3020 	TestInterleave          = ETrue;
  3021 	TestPrioChange          = ETrue;
  3022 	TestMediaAccess         = KTestMediaAccessNone;
  3023 	TestWhichTests          = TEST_RANDOM;		
  3024 	TestingLowMem			= EFalse;
  3025 
  3026 	RUNTEST(DoMultipleTest(TestingLowMem), KErrNone);
  3027 
  3028 	bTraceHandle.SetMode(0);
  3029 
  3030 	// analyse the btrace logs and display on the serial port.
  3031 	TUint8* pDataStart;
  3032 	TInt	dataSize;
  3033 	TUint8* pTemp;
  3034 	TUint8* pThis;
  3035 	TUint8* pEnd;
  3036 	TBuf<128>	data;
  3037 	while (1)
  3038 		{
  3039 		dataSize = bTraceHandle.GetData(pDataStart);
  3040 		if (dataSize <= 0)
  3041 			{
  3042 			break;
  3043 			}
  3044 		pEnd = pDataStart + dataSize;
  3045 		pTemp = pDataStart;
  3046 		while (pTemp < pEnd)
  3047 			{
  3048 			TUint8	recSize		= pTemp[BTrace::ESizeIndex];
  3049 			TUint8	recFlags	= pTemp[BTrace::EFlagsIndex];
  3050 			TUint8	recCat		= pTemp[BTrace::ECategoryIndex];
  3051 			TUint8	recSub		= pTemp[BTrace::ESubCategoryIndex];
  3052 			TUint32 addr[4];
  3053 			pThis = pTemp;
  3054 
  3055 			data.Zero();
  3056 			// step over the header.
  3057 			data.Format(_L("size %d cat %d sub %d flg 0x%02x "), recSize, recCat, recSub, recFlags);
  3058 			pTemp += 4; 
  3059 					
  3060 			if (recFlags & BTrace::EHeader2Present)
  3061 				{
  3062 				data.AppendFormat(_L("h2 0x%08x "), LE4(pTemp));
  3063 				pTemp += 4;
  3064 				}
  3065 			if (recFlags & BTrace::ETimestampPresent)
  3066 				{
  3067 				data.AppendFormat(_L("ts 0x%08x "), LE4(pTemp));
  3068 				pTemp += 4;
  3069 				}
  3070 			if (recFlags & BTrace::ETimestamp2Present)
  3071 				{
  3072 				data.AppendFormat(_L("ts2 0x%08x "), LE4(pTemp));
  3073 				pTemp += 4;
  3074 				}
  3075 			if (recFlags & BTrace::EContextIdPresent)
  3076 				{
  3077 				data.AppendFormat(_L("cId 0x%08x "), LE4(pTemp));
  3078 				pTemp += 4;
  3079 				}
  3080 			TInt index;
  3081 			for (index = 0; index < 4; index ++)
  3082 				{
  3083 				if (recSize > pTemp - pThis)
  3084 					{
  3085 					addr[index] = LE4(pTemp);
  3086 					pTemp += 4;
  3087 					}
  3088 				else
  3089 					addr[index] = 0;
  3090 				}
  3091 
  3092 			switch(recCat)
  3093 				{
  3094 				case BTrace::EPaging:
  3095 					{
  3096 					switch (recSub)
  3097 						{
  3098 						case BTrace::EPagingPageInBegin:
  3099 						/**
  3100 						- 4 bytes containing the virtual address which was accessed, causing this paging event.
  3101 						- 4 bytes containing the virtual address of the instuction which caused this paging event.
  3102 						  (The PC value.)
  3103 						**/
  3104 						test.Printf(_L("PageInBegin    : %S addr 0x%08x inst 0x%08x\n"), &data, addr[0], addr[1]);
  3105 						break;
  3106 
  3107 						/**
  3108 						- 0 bytes. (No extra data.)
  3109 						*/
  3110 						case BTrace::EPagingPageInUnneeded:
  3111 						test.Printf(_L("PageInUnneeded : %S\n"), &data);
  3112 						break;
  3113 
  3114 						/**
  3115 						- 4 bytes containing the physical address of the page 'paged in'.
  3116 						- 4 bytes containing the virtual address of the page 'paged in'.
  3117 						*/
  3118 						case BTrace::EPagingPageInROM:
  3119 						test.Printf(_L("PageInROM      : %S phys 0x%08x virt 0x%08x\n"), &data, addr[0], addr[1]);
  3120 						break;
  3121 
  3122 						/**
  3123 						- 4 bytes containing the physical address of the page being 'paged out'.
  3124 						- 4 bytes containing the virtual address of the page being 'paged out'.
  3125 						*/
  3126 						case BTrace::EPagingPageOutROM:
  3127 						test.Printf(_L("PageOutROM     : %S phys 0x%08x virt 0x%08x\n"), &data, addr[0], addr[1]);
  3128 						break;
  3129 
  3130 						/**
  3131 						- 4 bytes containing the physical address of the page being 'paged in'.
  3132 						*/
  3133 						case BTrace::EPagingPageInFree:
  3134 						test.Printf(_L("PageInFree     : %S phys 0x%08x\n"), &data, addr[0]);
  3135 						break;
  3136 
  3137 						/**
  3138 						- 4 bytes containing the physical address of the page being 'paged out'.
  3139 						*/
  3140 						case BTrace::EPagingPageOutFree:
  3141 						test.Printf(_L("PageOutFree    : %S phys 0x%08x\n"), &data, addr[0]);
  3142 						break;
  3143 
  3144 						/**
  3145 						- 4 bytes containing the physical address of the page being rejuvenated, (made young).
  3146 						- 4 bytes containing the virtual address which was accessed, causing this paging event.
  3147 						- 4 bytes containing the virtual address of the instuction which caused this paging event.
  3148 						  (The PC value.)
  3149 						*/
  3150 						case BTrace::EPagingRejuvenate:
  3151 						test.Printf(_L("Rejuvenate     : %S phys 0x%08x virt 0x%08x inst 0x%08x\n"), &data, addr[0], addr[1], addr[2]);
  3152 						break;
  3153 
  3154 						/**
  3155 						- 4 bytes containing the physical address of the page accessed.
  3156 						- 4 bytes containing the virtual address which was accessed, causing this paging event.
  3157 						- 4 bytes containing the virtual address of the instuction which caused this paging event.
  3158 						  (The PC value.)
  3159 						*/
  3160 						case BTrace::EPagingPageNop:
  3161 						test.Printf(_L("PageNop        : %S phys 0x%08x virt 0x%08x inst 0x%08x\n"), &data, addr[0], addr[1], addr[2]);
  3162 						break;
  3163 
  3164 						/**
  3165 						- 4 bytes containing the physical address of the page being locked.
  3166 						- 4 bytes containing the value of the lock count after the paged was locked.
  3167 						*/
  3168 						case BTrace::EPagingPageLock:
  3169 						test.Printf(_L("PageLock       : %S phys 0x%08x lock 0x%08x\n"), &data, addr[0], addr[1]);
  3170 						break;
  3171 
  3172 						/**
  3173 						- 4 bytes containing the physical address of the page being unlocked.
  3174 						- 4 bytes containing the value of the lock count before the paged was unlocked.
  3175 						*/
  3176 						case BTrace::EPagingPageUnlock:
  3177 						test.Printf(_L("PageUnlock     : %S phys 0x%08x lock 0x%08x\n"), &data, addr[0], addr[1]);
  3178 						break;
  3179 		
  3180 						/**
  3181 						- 4 bytes containing the physical address of the page being 'paged out'.
  3182 						- 4 bytes containing the virtual address of the page being 'paged out'.
  3183 						*/
  3184 						case BTrace::EPagingPageOutCache:
  3185 						test.Printf(_L("PageOutCache   : %S phys 0x%08x virt 0x%08x\n"), &data, addr[0], addr[1]);
  3186 						break;
  3187 		
  3188 						/**
  3189 						- 4 bytes containing the physical address of the page 'paged in'.
  3190 						- 4 bytes containing the virtual address of the page 'paged in'.
  3191 						*/
  3192 						case BTrace::EPagingPageInCode:
  3193 						test.Printf(_L("PageInCode     : %S phys 0x%08x virt 0x%08x\n"), &data, addr[0], addr[1]);
  3194 						break;
  3195 
  3196 						/**
  3197 						- 4 bytes containing the physical address of the page being 'paged out'.
  3198 						- 4 bytes containing the virtual address of the page being 'paged out'.
  3199 						*/
  3200 						case BTrace::EPagingPageOutCode:
  3201 						test.Printf(_L("PageOutCode    : %S phys 0x%08x virt 0x%08x\n"), &data, addr[0], addr[1]);
  3202 						break;
  3203 		
  3204 						/**
  3205 						- 4 bytes containing the physical address of the page 'paged in'.
  3206 						- 4 bytes containing the virtual address of the page 'paged in'.
  3207 						*/
  3208 						case BTrace::EPagingMapCode:
  3209 						test.Printf(_L("MapCode        : %S phys 0x%08x virt 0x%08x\n"), &data, addr[0], addr[1]);
  3210 						break;
  3211 						
  3212 						/**
  3213 						- 4 bytes containing the physical address of the page being aged, (made old).
  3214 						*/
  3215 						case BTrace::EPagingAged:
  3216 						test.Printf(_L("Aged           : %S phys 0x%08x\n"), &data, addr[0]);
  3217 						break;
  3218 						}
  3219 					}
  3220 				break;
  3221 
  3222 				default:
  3223 				
  3224 				break;
  3225 				}
  3226 			pTemp = BTrace::NextRecord(pThis);
  3227 			}
  3228 		bTraceHandle.DataUsed();
  3229 		}
  3230 	bTraceHandle.Close();
  3231 	}
  3232 
  3233 //
  3234 // ParseCommandLine 
  3235 //
  3236 // read the arguments passed from the command line and set global variables to 
  3237 // control the tests.
  3238 //
  3239 
  3240 TBool ParseCommandLine()
  3241 	{
  3242 	TBuf<256> args;
  3243 	User::CommandLine(args);
  3244 	TLex	lex(args);
  3245 	TBool	retVal = ETrue;
  3246 	
  3247 	// initially test for arguments, the parse them, if not apply some sensible defaults.
  3248 	TBool	foundArgs = EFalse;	
  3249 		
  3250 	FOREVER
  3251 		{
  3252 		TPtrC  token=lex.NextToken();
  3253 		if(token.Length()!=0)
  3254 			{
  3255 			if ((token == _L("help")) || (token == _L("-h")) || (token == _L("-?")))
  3256 				{
  3257 				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")));
  3258 				test.Getch();
  3259 				}
  3260 			else  if (token == _L("mmc"))
  3261 				{
  3262 				TestOnlyFromMmc = ETrue;
  3263 				}
  3264 			else  if (token == _L("min"))
  3265 				{
  3266 				TPtrC val=lex.NextToken();
  3267 				TLex lexv(val);
  3268 				TInt value;
  3269 				lexv.Val(value);
  3270 				TestMinCacheSize = value * 4096;
  3271 				}
  3272 			else  if (token == _L("max"))
  3273 				{
  3274 				TPtrC val=lex.NextToken();
  3275 				TLex lexv(val);
  3276 				TInt value;
  3277 				lexv.Val(value);
  3278 				TestMaxCacheSize = value * 4096;
  3279 				}
  3280 			else  if (token == _L("interleave"))
  3281 				{
  3282 				TestInterleave = ETrue;
  3283 				}
  3284 			else if (token == _L("auto"))
  3285 				{
  3286 				TestFullAutoTest = EFalse;
  3287 				retVal = EFalse;
  3288 				}
  3289 			else if (token == _L("stressfree"))
  3290 				{
  3291 				TestStressFree = !TestStressFree;
  3292 				retVal = EFalse;
  3293 				}
  3294 			else if (token == _L("fullauto"))
  3295 				{
  3296 				TestFullAutoTest = ETrue;
  3297 				retVal = EFalse;
  3298 				}
  3299 			else if (token == _L("prio"))
  3300 				{
  3301 				TestPrioChange = !TestPrioChange;
  3302 				}
  3303 			else if (token == _L("media"))
  3304 				{
  3305 				TestMediaAccess = KTestMediaAccessBasic;
  3306 				}
  3307 			else if (token == _L("reaper"))
  3308 				{
  3309 				TestReaper = ETrue;
  3310 				}
  3311 			else if (token == _L("btrace"))
  3312 				{
  3313 				TestBtrace = ETrue;
  3314 				}
  3315 			else if (token == _L("defrag"))
  3316 				{
  3317 				TestDefrag = ETrue;
  3318 				}
  3319 			else if (token == _L("echunks"))
  3320 				{
  3321 				TestChunks = ETrue;
  3322 				TestExtremeChunks = ETrue;
  3323 				}
  3324 			else if (token == _L("chunks+"))
  3325 				{
  3326 				TestChunks = ETrue;
  3327 				TestChunksPlus = ETrue;
  3328 				}
  3329 			else if (token == _L("chunks"))
  3330 				{
  3331 				TestChunks = ETrue;
  3332 				}
  3333 			else if (token == _L("nochunkdata"))
  3334 				{
  3335 				TestChunkData = EFalse;
  3336 				}
  3337 			else if (token == _L("lowmem"))
  3338 				{
  3339 				TestLowMem = ETrue;
  3340 				}
  3341 			else if (token == _L("dll"))
  3342 				{
  3343 				TestLoading = TEST_DLL;
  3344 				}
  3345 			else if (token == _L("exe"))
  3346 				{
  3347 				TestLoading = TEST_EXE;
  3348 				}
  3349 			else if (token == _L("self"))
  3350 				{
  3351 				TestLoading = TEST_SELF;
  3352 				}
  3353 			else if (token == _L("complete"))
  3354 				{
  3355 				TestLoading |= TEST_EXE_SELF_DLL;
  3356 				}
  3357 			else if (token == _L("rom"))
  3358 				{
  3359 				TestWhichMedia = TEST_MEDIA_ROM;
  3360 				}
  3361 			else if (token == _L("base"))
  3362 				{
  3363 				TestWhichMedia = TEST_MEDIA_BASE;
  3364 				}
  3365 			else if (token == _L("mixed"))
  3366 				{
  3367 				TestWhichMedia |= TEST_MEDIA_ROM_BASE;
  3368 				}
  3369 			else if (token == _L("all_media"))
  3370 				{
  3371 				TestWhichMedia |= TEST_MEDIA_ALL;
  3372 				}
  3373 			else if (token == _L("debug"))
  3374 				{
  3375 				if (!TestSilent)
  3376 					{
  3377 					TestDebug = ETrue;
  3378 					TestPrioChange = ETrue;
  3379 					}
  3380 				}
  3381 			else if (token == _L("silent"))
  3382 				{
  3383 				TestSilent = ETrue;
  3384 				TestDebug = EFalse;
  3385 				}
  3386 			else if (token == _L("noclean"))
  3387 				{
  3388 				TestNoClean = ETrue;
  3389 				}
  3390 			else if (token == _L("d_exc"))
  3391 				{
  3392 				TestD_Exc = ETrue;
  3393 				}
  3394 			else if (token == _L("global"))
  3395 				{
  3396 				TestLoadDllHow = TEST_DLL_GLOBAL;
  3397 				}	
  3398 			else if (token == _L("thread"))
  3399 				{
  3400 				TestLoadDllHow = TEST_DLL_THREAD;
  3401 				}	
  3402 			else if (token == _L("func"))
  3403 				{
  3404 				TestLoadDllHow = TEST_DLL_FUNC;
  3405 				}	
  3406 			else if (token == _L("single"))
  3407 				{
  3408 				TestSingle = ETrue;
  3409 				}
  3410 			else if (token == _L("multiple"))
  3411 				{
  3412 				TPtrC val=lex.NextToken();
  3413 				TLex lexv(val);
  3414 				TInt value;
  3415 
  3416 				if (lexv.Val(value)==KErrNone)
  3417 					{
  3418 					if ((value <= 0) || (value > 100))
  3419 						{
  3420 						TestMultipleThreadCount = 10;
  3421 						}
  3422 					else
  3423 						{
  3424 						TestMultipleThreadCount = value;
  3425 						}
  3426 					}
  3427 				else
  3428 					{
  3429 					DBGS_PRINT((_L("Bad value for thread count '%S' was ignored.\n"), &val));
  3430 					retVal = EFalse;
  3431 					break;
  3432 					}
  3433 				TestMultiple = ETrue;
  3434 				}
  3435 			else if (token == _L("forward"))
  3436 				{
  3437 				TestWhichTests = TEST_FORWARD;
  3438 				}
  3439 			else if (token == _L("backward"))
  3440 				{
  3441 				TestWhichTests = TEST_BACKWARD;
  3442 				}
  3443 			else if (token == _L("random"))
  3444 				{
  3445 				TestWhichTests = TEST_RANDOM;
  3446 				}
  3447 			else if (token == _L("all"))
  3448 				{
  3449 				TestWhichTests = TEST_ALL;
  3450 				}
  3451 			else  if (token == _L("inst"))
  3452 				{
  3453 				TPtrC val=lex.NextToken();
  3454 				TLex lexv(val);
  3455 				TInt value;
  3456 
  3457 				if (lexv.Val(value)==KErrNone)
  3458 					{
  3459 					TestInstanceId = value;
  3460 					}
  3461 				}
  3462 			else  if (token == _L("iters"))
  3463 				{
  3464 				TPtrC val=lex.NextToken();
  3465 				TLex lexv(val);
  3466 				TInt value;
  3467 
  3468 				if (val==_L("-"))
  3469 					{
  3470 					TestMaxLoops = KMaxTInt;
  3471 					}
  3472 				else
  3473 					{
  3474 					if (lexv.Val(value)==KErrNone)
  3475 						{
  3476 						TestMaxLoops = value;
  3477 						}
  3478 					else
  3479 						{
  3480 						DBGS_PRINT((_L("Bad value for thread count '%S' was ignored.\n"), &val));
  3481 						retVal = EFalse;
  3482 						break;
  3483 						}
  3484 					}
  3485 				}
  3486 			else
  3487 				{
  3488 				if ((foundArgs == EFalse) && (token.Length() == 1))
  3489 					{
  3490 					// Single letter argument...only run on 'd'
  3491 					if (token.CompareF(_L("d")) == 0)
  3492 						{
  3493 
  3494 						TestFullAutoTest = EFalse;
  3495 						TestIsAutomated = ETrue;
  3496 						break;
  3497 						}
  3498 					else
  3499 						{
  3500 						if (!TestSilent)
  3501 							{
  3502 							test.Title();
  3503 							test.Start(_L("Skipping non drive 'd' - Test Exiting."));
  3504 							test.End();
  3505 							}
  3506 						foundArgs = ETrue;
  3507 						TestExit = ETrue;
  3508 						break;
  3509 						}
  3510 					}
  3511 				DBGS_PRINT((_L("Unknown argument '%S' was ignored.\n"), &token));
  3512 				break;
  3513 				}
  3514 			foundArgs = ETrue;
  3515 			}
  3516 		else
  3517 			{
  3518 			break;
  3519 			}
  3520 		}
  3521 	if (!foundArgs)
  3522 		{
  3523 		retVal = EFalse;
  3524 		}
  3525 	return retVal;
  3526 	}
  3527 
  3528 //
  3529 // AreWeTheTestBase
  3530 //
  3531 // Test whether we are the root of the tests.
  3532 //
  3533 void AreWeTheTestBase()
  3534 	{
  3535 	if (!TestSilent)
  3536 		{
  3537 		TFileName  filename(RProcess().FileName());
  3538 
  3539 		TParse	myParse;
  3540 		myParse.Set(filename, NULL, NULL);
  3541 		TestNameBuffer.Zero();
  3542 		TestNameBuffer.Append(myParse.Name());
  3543 		TestNameBuffer.Append(_L(".exe"));
  3544 
  3545 		TestWeAreTheTestBase = !TestNameBuffer.Compare(TestPlExeNames[KTestMediaBase]);
  3546 
  3547 		RFs fs;
  3548 		if (KErrNone == fs.Connect())
  3549 			{
  3550 			TEntry  anEntry;
  3551 			TInt retVal = fs.Entry(_L("z:\\test\\mmcdemandpaginge32tests.bat"), anEntry);
  3552 			if (retVal == KErrNone)
  3553 				{
  3554 				TestBootedFromMmc = ETrue;
  3555 				}
  3556 			else
  3557 				{
  3558 				TestBootedFromMmc = EFalse;
  3559 				}
  3560 			fs.Close();
  3561 			}
  3562 		}
  3563 	else
  3564 		{
  3565 		TestNameBuffer.Zero();
  3566 		TestNameBuffer.Append(_L("t_pageldrtst.exe"));
  3567 		}
  3568 	}
  3569 #define  MEDNONE	KTestMediaAccessNone
  3570 #define MEDBASIC	KTestMediaAccessBasic
  3571 #define MEDMTHRE	KTestMediaAccessMultipleThreads
  3572 #define MEDMPATT	KTestMediaAccessMultiplePattern
  3573 #define MEDMIX		KTestMediaAccessMixed
  3574 
  3575 TTheTests TheAutoTests[] =
  3576 	{// fullOnly,           loading,               media,  multi, loops, threads,         loadHow,  inter,   prio,    media,  whichTests, lowmem, free, testName
  3577 #ifdef TEST_SHORT_TEST
  3578 		{ 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."), },
  3579 #else
  3580 		{ 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."), },
  3581 		{  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."), },
  3582 		{  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."), },
  3583 		{  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."), },
  3584 		{  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."), },
  3585 		{ 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."), },
  3586 		{  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."), },
  3587 		{ 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."), },
  3588 		{ 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."), },
  3589 		{ 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."), },
  3590 		{  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."), },
  3591 		{ 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."), },
  3592 		{  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."), },
  3593 		{  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."), },
  3594 		{ 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."), },
  3595 		{  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."), },
  3596 		{ 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."), },
  3597 		{  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."), },
  3598 
  3599 		{  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."), },
  3600 		{  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."), },
  3601 		{  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."), },
  3602 		{  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."), },
  3603 		{ 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."), },
  3604 #endif // TEST_SHORT_TEST
  3605 	};
  3606 #define NUM_AUTO_TESTS (TInt)(sizeof(TheAutoTests) / sizeof(TTheTests))
  3607 
  3608 //
  3609 // PerformAutoTest
  3610 //
  3611 // The autotest.
  3612 //
  3613 
  3614 void PerformAutoTest(TBool aReduceTime = EFalse)
  3615 	{
  3616 	TInt        testIndex;
  3617 	TTheTests  *pTest = &TheAutoTests[0];
  3618 	
  3619 	DoStats();
  3620 
  3621 	for (testIndex = 0; testIndex < NUM_AUTO_TESTS; testIndex ++, pTest++)
  3622 		{
  3623 		if (   (   !TestWeAreTheTestBase 
  3624 			    && (   (pTest->testLoadDllHow != TEST_DLL_FUNC)
  3625 				    || !pTest->testMultiple))
  3626 			|| ((TestFullAutoTest == EFalse) && (pTest->testFullAutoOnly)))
  3627 			{
  3628 			continue;
  3629 			}
  3630 		
  3631 		TestLoading             = pTest->testLoading;
  3632 		TestWhichMedia          = pTest->testWhichMedia;
  3633 		TestMaxLoops            = aReduceTime ? 1 : pTest->testMaxLoops;
  3634 		TestMultipleThreadCount = aReduceTime ? 10 : pTest->testMultipleThreadCount;
  3635 		TestLoadDllHow          = pTest->testLoadDllHow;
  3636 		TestInterleave          = pTest->testInterleave;
  3637 		TestPrioChange          = pTest->testPrioChange;
  3638 		TestMediaAccess         = pTest->testMediaAccess;
  3639 		if (aReduceTime && (TestMediaAccess != MEDBASIC) && (TestMediaAccess != MEDNONE))
  3640 			{
  3641 			continue;
  3642 			}
  3643 		TestWhichTests          = pTest->testWhichTests;		
  3644 		TestingLowMem			= pTest->testLowMem;
  3645 		if (!TestSilent)
  3646 			{
  3647 			test.Next(_L("Auto Test"));
  3648 			}
  3649 		if (pTest->testMultiple)
  3650 			{
  3651 			RUNTEST(DoMultipleTest(ETrue), KErrNone);
  3652 			}
  3653 		else
  3654 			{
  3655 			RUNTEST(DoSingleTest(ETrue), KErrNone);
  3656 			}
  3657 
  3658 		DoStats();
  3659 
  3660 #ifdef TEST_KERN_HEAP
  3661 		__KHEAP_MARK;
  3662 		__KHEAP_CHECK(0);
  3663 		__KHEAP_MARKEND;
  3664 #endif
  3665 		}
  3666 #ifdef TEST_KERN_HEAP
  3667 	__KHEAP_MARK;
  3668 	__KHEAP_CHECK(0);
  3669 	__KHEAP_MARKEND;
  3670 #endif
  3671 	}
  3672 
  3673 TTheTests TheLowMemTests[] =
  3674 	{// fullOnly,           loading,               media,  multi, loops, threads,       loadHow,  inter,   prio,    media,  whichTests, lowmem, free, testName
  3675 #ifndef TEST_SHORT_TEST
  3676 		{  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)."), },
  3677 		{  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."), },
  3678 		{  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)."), },
  3679 		{  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 ."), },
  3680 		{ 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)."), },
  3681 		{ 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."), },
  3682 		{  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)."), },
  3683 		{  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."), },
  3684 		{  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)."), },
  3685 		{  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."), },
  3686 		{  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)."), },
  3687 		{  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."), },
  3688 		{  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)."), },
  3689 		{  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."), },
  3690 		{ 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)."), },
  3691 		{ 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."), },
  3692 #endif //TEST_SHORT_TEST
  3693 		{ 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)."), },
  3694 		{ 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."), },
  3695 		{ 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)."), },
  3696 		{ 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."), },
  3697 		{  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)."), },
  3698 		{  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."), },
  3699 		{  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)."), },
  3700 		{  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."), },
  3701 
  3702 	};
  3703 #define NUM_LOWMEM_TESTS (TInt)(sizeof(TheLowMemTests) / sizeof(TTheTests))
  3704 
  3705 //
  3706 // DoLowMemTest
  3707 //
  3708 // Low Memory Test
  3709 //
  3710 void DoLowMemTest(TBool aEnableAllMedia = EFalse)
  3711 	{
  3712 	TInt r = User::LoadLogicalDevice(KPageStressTestLddName);
  3713 	RUNTEST1(r==KErrNone || r==KErrAlreadyExists);
  3714 	RUNTEST(PagestressLdd.Open(),KErrNone);
  3715 	RUNTEST(PagestressLdd.DoSetDebugFlag((TInt)TestDebug),KErrNone);
  3716 	
  3717 	SVMCacheInfo  tempPages;
  3718 	memset(&tempPages, 0, sizeof(tempPages));
  3719 	if (TestIsDemandPaged)
  3720 		{
  3721 		// get the old cache info
  3722 		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
  3723 		TInt minSize = 8 * 4096;
  3724 		TInt maxSize = 256 * 4096;
  3725 		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
  3726 		}
  3727 
  3728 	TInt		testIndex;
  3729 	TTheTests  *pTest = &TheLowMemTests[0];
  3730 	for (testIndex = 0; testIndex < NUM_LOWMEM_TESTS; testIndex ++, pTest++)
  3731 		{
  3732 		if (   (!aEnableAllMedia && (pTest->testWhichMedia == TEST_MEDIA_ALL))
  3733 		    || ((TestFullAutoTest == EFalse) && (pTest->testFullAutoOnly)))
  3734 			{
  3735 			continue;
  3736 			}
  3737 
  3738 		TestLoading             = pTest->testLoading;
  3739 		TestWhichMedia          = pTest->testWhichMedia;
  3740 		TestMaxLoops            = pTest->testMaxLoops;
  3741 		TestMultipleThreadCount = pTest->testMultipleThreadCount;
  3742 		TestLoadDllHow          = pTest->testLoadDllHow;
  3743 		TestInterleave          = pTest->testInterleave;
  3744 		TestPrioChange          = pTest->testPrioChange;
  3745 		TestMediaAccess         = pTest->testMediaAccess;
  3746 		TestWhichTests          = pTest->testWhichTests;		
  3747 		TestingLowMem			= pTest->testLowMem;
  3748 		if (!TestSilent)
  3749 			{
  3750 			test.Next(_L("Low Memory"));
  3751 			}
  3752 		if (pTest->testLowMem)
  3753 			{
  3754 			PagestressLdd.DoConsumeRamSetup(pTest->testFreeRam, TEST_LM_BLOCKSIZE);
  3755 			}
  3756 
  3757 		if (pTest->testMultiple)
  3758 			{
  3759 			RUNTEST(DoMultipleTest(pTest->testLowMem), KErrNone);
  3760 			}
  3761 		else
  3762 			{
  3763 			RUNTEST(DoSingleTest(pTest->testLowMem), KErrNone);
  3764 			}
  3765 
  3766 		if (pTest->testLowMem)
  3767 			{
  3768 			PagestressLdd.DoConsumeRamFinish();
  3769 			}
  3770 
  3771 		DoStats();
  3772 #ifdef TEST_KERN_HEAP
  3773 		__KHEAP_MARK;
  3774 		__KHEAP_CHECK(0);
  3775 		__KHEAP_MARKEND;
  3776 #endif
  3777 		}
  3778 
  3779 	if (!TestSilent)
  3780 		{
  3781 		test.Next(_L("Close test driver"));
  3782 		}
  3783 	PagestressLdd.Close();
  3784 	RUNTEST(User::FreeLogicalDevice(KPageStressTestLddName), KErrNone);
  3785 
  3786 	if (TestIsDemandPaged)
  3787 		{
  3788 		TInt minSize = tempPages.iMinSize;
  3789 		TInt maxSize = tempPages.iMaxSize;
  3790 		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
  3791 		}
  3792 
  3793 #ifdef TEST_KERN_HEAP
  3794 	__KHEAP_MARK;
  3795 	__KHEAP_CHECK(0);
  3796 	__KHEAP_MARKEND;
  3797 #endif
  3798 	TestingLowMem = EFalse;
  3799 
  3800 	}
  3801 
  3802 //
  3803 // MultipleDefragThread
  3804 //
  3805 // Thread function, one created for each zone in a multiple thread test.
  3806 //
  3807 
  3808 LOCAL_C TInt MultipleDefragThread(TAny* aUseTb)
  3809 	{
  3810 	TInt numZones = 1;
  3811 	TInt zoneId = (TInt)aUseTb;
  3812 
  3813 	if (TestZoneCount > TEST_MAX_ZONE_THREADS)
  3814 		{
  3815 		numZones = TestZoneCount / TEST_MAX_ZONE_THREADS;
  3816 		}
  3817 
  3818 	while (1)
  3819 		{
  3820 		TInt index = 0;
  3821 		TInt tempy = 0;
  3822 		for (; index < numZones; index ++)
  3823 			{
  3824 			User::AfterHighRes(TEST_MAX_ZONE_THREADS*TickPeriod/4);
  3825 			tempy = zoneId + (TEST_MAX_ZONE_THREADS * index);
  3826 			if (tempy < (TInt)TestZoneCount)
  3827 				{
  3828 				RamstressLdd.DoMovePagesInZone(tempy);
  3829 				}
  3830 			if (TestDefragTestEnd)
  3831 				break;
  3832 			}
  3833 		if (TestDefragTestEnd)
  3834 			break;
  3835 		}	
  3836 	return KErrNone;
  3837 	}
  3838 
  3839 //
  3840 // DoDefragAutoTest
  3841 //
  3842 // Call the auto tests whilst defraging in the background.
  3843 //
  3844 
  3845 void DoDefragAutoTest()
  3846 	{
  3847 	TUint	localZoneCount = TestZoneCount;
  3848 	if (TestZoneCount > TEST_MAX_ZONE_THREADS)
  3849 		{
  3850 		localZoneCount = TEST_MAX_ZONE_THREADS;
  3851 		}
  3852 	TInt			size =    (sizeof(RThread) * localZoneCount) 
  3853 							+ (sizeof(TInt) * localZoneCount);
  3854 	TUint8*			pBuf = (TUint8*)User::AllocZ(size);
  3855 
  3856 	test(pBuf != NULL);
  3857 	RThread			*pTheThreads = (RThread*)pBuf;
  3858 	TInt			*pThreadInUse = (TInt*)(pTheThreads + localZoneCount);
  3859 	TInt			 ret;
  3860 	TUint			 index;
  3861 	for (index = 0; index < localZoneCount; index ++)
  3862 		{
  3863 		DBGS_PRINT((_L("%S : Starting Defrag Thread %d\n"), &TestNameBuffer, index));
  3864 		ret = pTheThreads[index].Create(KTestBlank,MultipleDefragThread,KDefaultStackSize,NULL,(TAny*) index);
  3865 		if (ret == KErrNone)
  3866 			{
  3867 			pTheThreads[index].Resume();
  3868 			pThreadInUse[index] = 1;
  3869 			}
  3870 		else
  3871 			{
  3872 			DBGS_PRINT((_L("%S : Starting Defrag Thread Failed %d\n"), &TestNameBuffer, index));
  3873 			}
  3874 		}
  3875 
  3876 	// Do the full auto tests...
  3877 	PerformAutoTest(TestIsDemandPaged);
  3878 
  3879 	TestDefragTestEnd = ETrue;
  3880 	RamstressLdd.DoSetEndFlag(1);
  3881 	TBool	anyUsed = ETrue;
  3882 
  3883 	DBGS_PRINT((_L("%S : Waiting for Defrag Threads to exit...\n"), &TestNameBuffer));	
  3884 	TUint killNext = User::TickCount();
  3885 	while(anyUsed)
  3886 		{
  3887 		anyUsed = EFalse;
  3888 		
  3889 		// walk through the thread list to check which are still alive.
  3890 		for (index = 0; index < localZoneCount; index++)
  3891 			{
  3892 			if (pThreadInUse[index])
  3893 				{
  3894 				if (pTheThreads[index].ExitType() != EExitPending)
  3895 					{
  3896 					if (pTheThreads[index].ExitType() == EExitPanic)
  3897 						{
  3898 						DBGS_PRINT((_L("%S : Defrag Thread %d Panic'd\n"), &TestNameBuffer, index));	
  3899 						}
  3900 					else
  3901 						{
  3902 						DBGS_PRINT((_L("%S : Defrag Thread %d Exited\n"), &TestNameBuffer, index));	
  3903 						}
  3904 					pTheThreads[index].Close();
  3905 					pThreadInUse[index] = EFalse;
  3906 					}
  3907 				else
  3908 					{
  3909 					anyUsed = ETrue;
  3910 					TUint now = User::TickCount();
  3911 					TUint time = TUint((TUint64)(now-killNext)*(TUint64)TickPeriod/(TUint64)1000000);
  3912 					const TUint killTimeStep = (TEST_DOT_PERIOD+9)/10; // 1/10th of a dot
  3913 					if(time>TEST_DOT_PERIOD+killTimeStep)
  3914 						{
  3915 						killNext += killTimeStep*1000000/TickPeriod;
  3916 						DBGS_PRINT((_L("%S : killing Defrag Thread %d\n"), &TestNameBuffer, index));	
  3917 						pTheThreads[index].Kill(KErrNone);
  3918 						pTheThreads[index].Close();
  3919 						pThreadInUse[index] = EFalse;
  3920 						}
  3921 					}
  3922 				}
  3923 			}
  3924 		User::After(500000);
  3925 		}
  3926 	DBGS_PRINT((_L("%S : Defrag Threads exited...\n"), &TestNameBuffer));	
  3927 	RamstressLdd.DoSetEndFlag(0);
  3928 	User::Free(pBuf);
  3929 	}
  3930 
  3931 //
  3932 // DoDefragTest
  3933 //
  3934 // Test the ram defrag code.
  3935 //
  3936 
  3937 void DoDefragTest(void)
  3938 	{
  3939 	SVMCacheInfo  tempPages;
  3940 	memset(&tempPages, 0, sizeof(tempPages));
  3941 
  3942 	test.Next(_L("Ram Defrag : Get the number of zones"));
  3943 	// first get the number of zones
  3944 	TInt ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneCount,&TestZoneCount,0);
  3945 	if(ret==KErrNotSupported)
  3946 		{
  3947 		test.Next(_L("TESTS NOT RUN - Ram Defrag appears to not be supported.\n"));
  3948 		return;
  3949 		}
  3950 	test(ret == KErrNone);
  3951 	test(TestZoneCount != 0);
  3952 	test.Printf(_L("RAM Zones (count=%u)\n"),TestZoneCount);
  3953 
  3954 	// now get the config of each of the zones.
  3955 	TUint						index;
  3956 	struct SRamZoneConfig		config;
  3957 	struct SRamZoneUtilisation	util;
  3958 	test.Next(_L("Ram Defrag : Get info about the zones"));
  3959 	for (index = 0; index < TestZoneCount; index ++)
  3960 		{
  3961 		ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneConfig,(TAny*)index, (TAny*)&config);
  3962 		test(ret == KErrNone);
  3963 		test.Printf(_L("config : id=%d index=%d base=0x%08x end=0x%08x pages=%d pref=%d flags=0x%x\n"),
  3964 					config.iZoneId,config.iZoneIndex,config.iPhysBase,config.iPhysEnd,config.iPhysPages, 
  3965 					config.iPref,config.iFlags);
  3966 
  3967 		ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation,(TAny*)index, (TAny*)&util);
  3968 		test(ret == KErrNone);
  3969 		test.Printf(_L("usage  : id=%d index=%d pages=%d free=%d unknown=%d fixed=%d move=%d discard=%d other=%d\n"),
  3970 					util.iZoneId,util.iZoneIndex,util.iPhysPages,util.iFreePages,
  3971 					util.iAllocUnknown,util.iAllocFixed,util.iAllocMovable,util.iAllocDiscardable,util.iAllocOther);
  3972 		}
  3973 	// Now test for zones out of range.
  3974 	test.Next(_L("Ram Defrag : test out of range indexes"));
  3975 	ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneConfig,(TAny*)(TestZoneCount + 1), (TAny*)&config);
  3976 	test(ret != KErrNone);
  3977 	ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation,(TAny*)(TestZoneCount + 1), (TAny*)&util);
  3978 	test(ret != KErrNone);
  3979 
  3980 	ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneConfig,(TAny*)-1, (TAny*)&config);
  3981 	test(ret != KErrNone);
  3982 	ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation,(TAny*)-1, (TAny*)&util);
  3983 	test(ret != KErrNone);
  3984 	test.Next(_L("Ram Defrag : test out of range enums"));
  3985 	ret = UserSvr::HalFunction(EHalGroupRam,-1, 0, 0);
  3986 	test(ret != KErrNone);
  3987 	ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation + 1,0, 0);
  3988 	test(ret != KErrNone);
  3989 
  3990 	TInt r = User::LoadLogicalDevice(KRamStressTestLddName);
  3991 	RUNTEST1(r==KErrNone || r==KErrAlreadyExists);
  3992 	RUNTEST(RamstressLdd.Open(),KErrNone);
  3993 	//TestDebug = ETrue;
  3994 	RUNTEST(RamstressLdd.DoSetDebugFlag((TInt)TestDebug),KErrNone);
  3995 
  3996 	test.Next(_L("Ram Defrag : set VM cache to stress free..."));
  3997 
  3998 	if (TestIsDemandPaged)
  3999 		{
  4000 		// get the old cache info
  4001 		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
  4002 
  4003 		TInt minSize = 512 * 4096;
  4004 		TInt maxSize = 32767 * 4096;
  4005 		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
  4006 		}
  4007 
  4008 	test.Next(_L("Ram Defrag : move all pages in all zone in 1 thread..."));
  4009 
  4010 	for (index = 0; index < TestZoneCount; index ++)
  4011 		{
  4012 		test.Printf(_L("Ram Defrag : moving pages in zone %u\n"),index);
  4013 		ret = RamstressLdd.DoMovePagesInZone(index);
  4014 		if (ret != KErrNone)
  4015 			{
  4016 			test.Printf(_L("Ram Defrag : moving pages in zone failed %u err=%d\n"), index, ret);
  4017 			}
  4018 		}
  4019 
  4020 
  4021 	test.Next(_L("Ram Defrag : Get info after test"));
  4022 	for (index = 0; index < TestZoneCount; index ++)
  4023 		{
  4024 		ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation,(TAny*)index, (TAny*)&util);
  4025 		test(ret == KErrNone);
  4026 		test.Printf(_L("usage  : id=%d index=%d pages=%d free=%d unknown=%d fixed=%d move=%d discard=%d other=%d\n"),
  4027 					util.iZoneId,util.iZoneIndex,util.iPhysPages,util.iFreePages,
  4028 					util.iAllocUnknown,util.iAllocFixed,util.iAllocMovable,util.iAllocDiscardable,util.iAllocOther);
  4029 		}
  4030 
  4031 	test.Next(_L("Ram Defrag : Page moving on multiple threads with auto test running."));
  4032 
  4033 	TestingDefrag = ETrue;
  4034 	TestDefragTestEnd = EFalse;
  4035 
  4036 	DoDefragAutoTest();
  4037 	TestingDefrag = EFalse;
  4038 	/*
  4039 	 * End of test cleanup.
  4040 	 */
  4041 
  4042 	test.Next(_L("Ram Defrag : reset VM cache back to stressed."));
  4043 	if (TestIsDemandPaged)
  4044 		{
  4045 		TInt minSize = tempPages.iMinSize;
  4046 		TInt maxSize = tempPages.iMaxSize;
  4047 		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
  4048 		}
  4049 	RamstressLdd.Close();
  4050 	test.Next(_L("Ram Defrag : Done"));
  4051 	}
  4052 
  4053 //
  4054 // PerformExceptionThread
  4055 //
  4056 // Generate a Panic
  4057 //
  4058 
  4059 LOCAL_C TInt PerformExceptionThread(TAny* )
  4060 	{
  4061 	User::AfterHighRes(1000000);
  4062 	// this line will cause a Kern::Exec 0 !!!
  4063 	test.Printf(_L("Hello World\n"));
  4064 
  4065 	return KErrNone;
  4066 	}
  4067 
  4068 //
  4069 // DoExceptionInAnotherThread
  4070 //
  4071 // Test the d_exc and minkda functionality with faulting processes.
  4072 //
  4073 
  4074 void DoExceptionInAnotherThread(void)
  4075 	{
  4076 	TRequestStatus	theStatus;
  4077 	RThread			theThread;
  4078 	
  4079 	TInt ret = theThread.Create(KTestBlank,PerformExceptionThread,KDefaultStackSize,NULL,NULL);
  4080 	test(ret == KErrNone);
  4081 	theThread.Logon(theStatus);
  4082 	RUNTEST1(theStatus == KRequestPending);	
  4083 	theThread.Resume();
  4084 	theThread.Close();
  4085 	User::WaitForRequest(theStatus);
  4086 	}
  4087 
  4088 //
  4089 // DoTestD_Exc
  4090 //
  4091 // Test the d_exc and minkda functionality with faulting processes.
  4092 //
  4093 
  4094 TInt DoTestD_Exc()
  4095 	{
  4096 	if (!TestSilent)
  4097 		{
  4098 		test.Next(_L("DoTestD_Exc : d_exc check test."));
  4099 		}
  4100 	DBGS_PRINT((_L("%S : DoTestD_Exc start...\n"), &TestNameBuffer));	
  4101 	// first we need to spawn d_exc.exe
  4102 	RProcess dexcProcess;
  4103 	TInt ret = dexcProcess.Create(_L("d_exc.exe"),_L("-b"));
  4104 	RUNTEST1(KErrNone == ret);
  4105 	TRequestStatus dexcStatus;
  4106 	dexcProcess.Logon(dexcStatus);
  4107 	RUNTEST1(dexcStatus == KRequestPending);	
  4108 	dexcProcess.Resume();
  4109 
  4110 	DBGS_PRINT((_L("%S : DoTestD_Exc started d_exc.exe\n"), &TestNameBuffer));	
  4111 
  4112 	DoExceptionInAnotherThread();
  4113 
  4114 	DBGS_PRINT((_L("%S : DoTestD_Exc test completed\n"), &TestNameBuffer));	
  4115 	// check that d_exc and minkda don't die!
  4116 	RUNTEST1(dexcProcess.ExitType() == EExitPending);
  4117 
  4118 	DBGS_PRINT((_L("%S : DoTestD_Exc d_exc still running\n"), &TestNameBuffer));	
  4119 	
  4120 	// kill off d_exc!
  4121 	dexcProcess.Kill(KErrNone);
  4122 	dexcProcess.Close();
  4123 	User::WaitForRequest(dexcStatus);
  4124 	DBGS_PRINT((_L("%S : DoTestD_Exc d_exc killed and exiting\n"), &TestNameBuffer));	
  4125 	return KErrNone;
  4126 	}
  4127 
  4128 /**
  4129 	Get name of the hash file used for an EXE or DLL which has been
  4130 	copied to writable media.
  4131 
  4132 	@param	aOrigName		Name of EXE or DLL which has been copied to
  4133 							writable media.  This does not have to be
  4134 							qualified because only the name and extension
  4135 							are used.
  4136 	@param	aHashName		On return this is set to the absolute filename
  4137 							which should contain the file's hash.  This
  4138 							function does not create the file, or its containing
  4139 							directory.
  4140  */
  4141 
  4142 static void GetHashFileName(const TDesC& aOrigName, TDes& aHashName)
  4143 	{
  4144 	aHashName.Copy(KSysHash);
  4145 	aHashName[0] = (TUint8) RFs::GetSystemDriveChar();
  4146 	const TParsePtrC ppc(aOrigName);
  4147 	aHashName.Append(ppc.NameAndExt());
  4148 	}
  4149 
  4150 //
  4151 // HashFile
  4152 // take hash of files require full drive:/path/name.ext
  4153 //
  4154 
  4155 void HashFile(const TDesC& aFileName, RFs& aFs)
  4156 	{
  4157 	CSHA1* sha1 = CSHA1::NewL();
  4158 	CleanupStack::PushL(sha1);
  4159 	
  4160 	TBuf<50> hashfile;
  4161 	hashfile = KSysHash;
  4162 	hashfile[0] = (TUint8) RFs::GetSystemDriveChar();
  4163 	
  4164 	TInt r = aFs.MkDirAll(hashfile);
  4165 	RUNTEST1(r==KErrNone || r==KErrAlreadyExists);
  4166 
  4167 	RFile fDest;
  4168 	r = fDest.Open(aFs, aFileName, EFileRead | EFileStream);
  4169 	if (r != KErrNone)
  4170 		{
  4171 		if (TestingReaper && (r == KErrInUse))
  4172 			{
  4173 			TBool whinged = EFalse;
  4174 			while (r == KErrInUse)
  4175 				{
  4176 				User::After(2000000);
  4177 				if (!whinged)
  4178 					{
  4179 					DBGS_PRINT((_L("HashFile() retrying Open for %S (%d)\n"), &aFileName, r));
  4180 					whinged = ETrue;
  4181 					}
  4182 				r = fDest.Open(aFs, aFileName, EFileRead | EFileStream);
  4183 				}
  4184 
  4185 			}
  4186 		else
  4187 			{
  4188 			DBGS_PRINT((_L("fDest.Open returned %d\n"), r));
  4189 			}
  4190 		}
  4191 	User::LeaveIfError(r);
  4192 	CleanupClosePushL(fDest);
  4193 
  4194 	TBool done;
  4195 	TBuf8<512> content;
  4196 	do
  4197 		{
  4198 		r = fDest.Read(content);
  4199 		if (r!=KErrNone)
  4200 			DBGS_PRINT((_L("fDest.Read returned %d\n"), r));	
  4201 		User::LeaveIfError(r);
  4202 		done = (content.Length() == 0);
  4203 		if (! done)
  4204 			sha1->Update(content);
  4205 		} while (! done);
  4206 	CleanupStack::PopAndDestroy(&fDest);
  4207 
  4208 	// write hash to \sys\hash
  4209 	TBuf8<SHA1_HASH> hashVal = sha1->Final();
  4210 
  4211 	TFileName fnSrc(aFileName);
  4212 	GetHashFileName(aFileName, fnSrc);
  4213 	RFile fHash;
  4214 	r = fHash.Replace(aFs, fnSrc, EFileWrite | EFileStream);
  4215 	if (r != KErrNone)
  4216 		DBGS_PRINT((_L("fHash.Replace returned %d\n"), r));
  4217 	User::LeaveIfError(r);
  4218 	CleanupClosePushL(fHash);
  4219 	r = fHash.Write(hashVal);
  4220 	if (r != KErrNone)
  4221 		DBGS_PRINT((_L("fHash.Write returned %d\n"), r));
  4222 	User::LeaveIfError(r);
  4223 
  4224 	CleanupStack::PopAndDestroy(2, sha1);
  4225 	}
  4226 
  4227 //
  4228 // CopyFileToMMc
  4229 //
  4230 // Copy a file to the MMC card and create a hash of it.
  4231 //
  4232 
  4233 TInt CopyFileToMMc(RFs& aFs,CFileMan* aFileMan, TPtrC aPath, TPtrC  aOldFilename, TPtrC  aNewFilename)
  4234 	{
  4235 	TInt retVal = aFs.MkDirAll(aPath);
  4236 	RUNTEST1(retVal==KErrNone || retVal==KErrAlreadyExists);
  4237 
  4238 	TFileName newPath;
  4239 	TFileName oldPath;
  4240 
  4241 	oldPath.Format(_L("%S%S"),&KRomPath, &aOldFilename);
  4242 	newPath.Format(_L("%S%S"),&aPath, &aNewFilename);
  4243 	DBGD_PRINT((_L("Copying %S to %S\n"), &oldPath, &newPath));
  4244 	retVal = aFileMan->Copy(oldPath, newPath, CFileMan::EOverWrite);
  4245 	if (retVal == KErrNone)
  4246 		{
  4247 		retVal = aFileMan->Attribs(newPath, KEntryAttNormal, KEntryAttReadOnly, 0);
  4248 		if (retVal != KErrNone)
  4249 			{
  4250 			DBGS_PRINT((_L("%S :   Attribs failed (%d)\n"), &newPath, retVal));
  4251 			}
  4252 		TEntry  anEntry;
  4253 		retVal = aFs.Entry(newPath, anEntry);
  4254 		if (retVal != KErrNone)
  4255 			{
  4256 			DBGS_PRINT((_L("%S : aFs.Entry failed (%d)\n"), &newPath, retVal));
  4257 			}
  4258 		TRAPD(r, HashFile(newPath, aFs));
  4259 		RUNTEST1(r == KErrNone);
  4260 		}
  4261 	else
  4262 		DBGS_PRINT((_L("Failed to copy file %d\n"), retVal));
  4263 	DBGD_PRINT((_L("%S : now %S (%d)\n"), &newPath, EXISTS(retVal), retVal));
  4264 	return retVal;
  4265 	}
  4266 
  4267 //
  4268 // CopyAndFragmentFiles
  4269 //
  4270 // Copy the test files to a specified location edeavouring to fragment as much as possible.
  4271 //
  4272 
  4273 TBool CopyAndFragmentFiles(RFs& aFs,CFileMan* aFileMan, TPtrC aPath, ETestMediaType aMediaType)
  4274 	{
  4275 	TInt retVal = aFs.MkDirAll(aPath);
  4276 	RUNTEST1(retVal==KErrNone || retVal==KErrAlreadyExists);
  4277 #define FILECOUNTMAX (PAGELDRTST_MAX_DLLS + 2)
  4278 	RFile	theInFiles[FILECOUNTMAX];
  4279 	RFile	theOutFiles[FILECOUNTMAX];
  4280 	TInt	inFileSize[FILECOUNTMAX];
  4281 	TInt	inFilePos[FILECOUNTMAX];
  4282 	TBool	fileOk[FILECOUNTMAX];
  4283 
  4284 	TInt	  index;
  4285 	TFileName newPath;
  4286 	TFileName oldPath;
  4287 
  4288 	for (index = 0; index < FILECOUNTMAX; index ++)
  4289 		{
  4290 		inFileSize[index] = 0;
  4291 		inFilePos[index] = 0;
  4292 		fileOk[index] = EFalse;
  4293 
  4294 		if (index < PAGELDRTST_MAX_DLLS)
  4295 			{
  4296 			oldPath.Format(_L("%S%S%d%S"), &KRomPath, &KDllBaseName, index, &TestPlExtNames[KTestMediaBase]);
  4297 			newPath.Format(_L("%S%S%d%S"), &aPath, &KDllBaseName, index, &TestPlExtNames[aMediaType]);
  4298 			}
  4299 		else if (index < (PAGELDRTST_MAX_DLLS + 1))
  4300 			{
  4301 			oldPath.Format(_L("%S%S"), &KRomPath, &TestPsExeNames[KTestMediaBase]);
  4302 			newPath.Format(_L("%S%S"), &aPath, &TestPsExeNames[aMediaType]);
  4303 			}
  4304 		else
  4305 			{
  4306 			oldPath.Format(_L("%S%S"), &KRomPath, &TestPlExeNames[KTestMediaBase]);
  4307 			newPath.Format(_L("%S%S"), &aPath, &TestPlExeNames[aMediaType]);
  4308 			}
  4309 
  4310 		retVal = theInFiles[index].Open(aFs, oldPath, EFileRead);
  4311 		if (retVal != KErrNone)
  4312 			{
  4313 			DBGS_PRINT((_L("%S : Failed to open for read (%d)\n"), &oldPath, retVal));
  4314 			break;
  4315 			}
  4316 		retVal = theInFiles[index].Size(inFileSize[index]);
  4317 		if (retVal != KErrNone)
  4318 			{
  4319 			theInFiles[index].Close();
  4320 			DBGS_PRINT((_L("%S : Failed to get file size (%d)\n"), &newPath, retVal));
  4321 			break;
  4322 			}
  4323 		retVal = theOutFiles[index].Replace(aFs, newPath, EFileWrite);
  4324 		if (retVal != KErrNone)
  4325 			{
  4326 			theInFiles[index].Close();
  4327 			DBGS_PRINT((_L("%S : Failed to open for write (%d)\n"), &newPath, retVal));
  4328 			break;
  4329 			}
  4330 
  4331 		fileOk[index] = ETrue;
  4332 		}
  4333 
  4334 	const TInt KBufferSize = 3333;
  4335 	TBuf8<KBufferSize> buffer;
  4336 	TBool stillGoing;
  4337 
  4338 	do
  4339 		{
  4340 		stillGoing = EFalse;
  4341 		for (index = 0; index < FILECOUNTMAX; index ++)
  4342 			{
  4343 			if (!fileOk[index])
  4344 				break;
  4345 			if (inFilePos[index] < inFileSize[index])
  4346 				{
  4347 				retVal = theInFiles[index].Read(buffer);
  4348 				if (retVal != KErrNone)
  4349 					{
  4350 					DBGS_PRINT((_L("theInFiles[%d] read failed (%d)\n"), index, retVal));
  4351 					break;
  4352 					}
  4353 				retVal = theOutFiles[index].Write(buffer);
  4354 				if (retVal != KErrNone)
  4355 					{
  4356 					DBGS_PRINT((_L("theOutFiles[%d] Write failed (%d)\n"), index, retVal));
  4357 					break;
  4358 					}
  4359 				retVal = theOutFiles[index].Flush();
  4360 				if (retVal != KErrNone)
  4361 					{
  4362 					DBGS_PRINT((_L("theOutFiles[%d] flush failed (%d)\n"), index, retVal));
  4363 					break;
  4364 					}
  4365 				inFilePos[index] += buffer.Length();
  4366 				if (inFilePos[index] < inFileSize[index])
  4367 					stillGoing = ETrue;
  4368 				}
  4369 			}
  4370 		}
  4371 	while (stillGoing);
  4372 
  4373 	TBool allOk = retVal == KErrNone;
  4374 	for (index = 0; index < FILECOUNTMAX; index ++)
  4375 		{
  4376 		if (!fileOk[index])
  4377 			{
  4378 			allOk = EFalse;
  4379 			break;
  4380 			}
  4381 		theInFiles[index].Close();
  4382 		theOutFiles[index].Close();
  4383 		if (index < PAGELDRTST_MAX_DLLS)
  4384 			{
  4385 			newPath.Format(_L("%S%S%d%S"), &aPath, &KDllBaseName, index, &TestPlExtNames[aMediaType]);
  4386 			}
  4387 		else if (index < (PAGELDRTST_MAX_DLLS + 1))
  4388 			{
  4389 			newPath.Format(_L("%S%S"), &aPath, &TestPsExeNames[aMediaType]);
  4390 			}
  4391 		else
  4392 			{
  4393 			newPath.Format(_L("%S%S"), &aPath, &TestPlExeNames[aMediaType]);
  4394 			}
  4395 
  4396 		retVal = aFileMan->Attribs(newPath, KEntryAttNormal, KEntryAttReadOnly, 0);
  4397 		if (retVal != KErrNone)
  4398 			{
  4399 			DBGS_PRINT((_L("%S : Attribs failed (%d)\n"), &newPath, retVal));
  4400 			allOk = EFalse;
  4401 			}
  4402 		TEntry  anEntry;
  4403 		retVal = aFs.Entry(newPath, anEntry);
  4404 		if (retVal != KErrNone)
  4405 			{
  4406 			DBGS_PRINT((_L("%S : aFs.Entry failed (%d)\n"), &newPath, retVal));
  4407 			allOk = EFalse;
  4408 			}
  4409 		TRAPD(r, HashFile(newPath, aFs));
  4410 		if (r != KErrNone)
  4411 			{
  4412 			allOk = EFalse;
  4413 			}
  4414 		DBGD_PRINT((_L("%S : %S!\n"), &newPath, EXISTS(!allOk)));
  4415 		}
  4416 	return allOk;
  4417 	}
  4418 
  4419 //
  4420 // CheckFilePresence
  4421 //
  4422 // Checks all the files required for the test are present and copies some tests to the MMC card
  4423 //
  4424 
  4425 void CheckFilePresence(TBool aDoFileCopy)
  4426 	{
  4427 	TUint start = User::TickCount();
  4428 
  4429 	RFs fs;
  4430 	if (KErrNone != fs.Connect())
  4431 		{
  4432 		DBGS_PRINT(_L("CheckFilePresence : Can't connect to the FS\n"));
  4433 		return ;
  4434 		}
  4435 
  4436 	TFileName filename;
  4437 	TFileName newFilename;
  4438 	TEntry anEntry;
  4439 	TInt   index;
  4440 	TInt   retVal;
  4441 	TInt   dllIndex;
  4442 
  4443 	// now we need to add the MMC files
  4444 	TInt drvNum = FindMMCDriveNumber(fs);
  4445 	TBuf<32>	mmcPath;
  4446 	mmcPath.Format(_L("%S"),&KMmcDefaultPath);
  4447 	if (drvNum >= 0)
  4448 		mmcPath[0] = 'a' + drvNum;
  4449 
  4450 	TBool	allOk;
  4451 	//TInt  indexMax = aDoFileCopy ? KTestMediaMmc : KTestMediaCOUNT; 
  4452 	for (index = 0; index < TEST_MEDIA_COUNT_HACK; index ++)
  4453 		{
  4454 		allOk = ETrue;	
  4455 		filename.Format(_L("%S%S"),(index == KTestMediaMmc) ? & mmcPath : &KRomPath, &TestPsExeNames[index]);
  4456 		if (KErrNone != fs.Entry(filename, anEntry))
  4457 			allOk = EFalse;
  4458 
  4459 		filename.Format(_L("%S%S"),(index == KTestMediaMmc) ? & mmcPath : &KRomPath, &TestPlExeNames[index]);
  4460 		if (KErrNone != fs.Entry(filename, anEntry))
  4461 			allOk = EFalse;
  4462 
  4463 		for (dllIndex = 0; dllIndex < PAGELDRTST_MAX_DLLS; dllIndex ++)
  4464 			{
  4465 			filename.Format(_L("%S%S%d%S"), (index == KTestMediaMmc) ? & mmcPath : &KRomPath, &KDllBaseName, dllIndex, &TestPlExtNames[index]);
  4466 			if (KErrNone != fs.Entry(filename, anEntry))
  4467 				allOk = EFalse;
  4468 			}
  4469 		TestDllExesExist[index] = allOk;
  4470 		DBGS_PRINT((_L("%S : %S!\n"), &TestPsExeNames[index], EXISTS(!TestDllExesExist[index])));
  4471 		}
  4472 	TInt nandDrvNum = FindFsNANDDrive(fs);
  4473 	if (aDoFileCopy && (drvNum >= 0) && (nandDrvNum >= 0))
  4474 		{
  4475 		CTrapCleanup* cleanupStack = CTrapCleanup::New();
  4476 		if(!cleanupStack)
  4477 			DBGS_PRINT((_L("Cleanup stack failed\n")));	
  4478 		CFileMan* pFileMan = NULL;
  4479 		TRAP(retVal, pFileMan = CFileMan::NewL(fs));
  4480 	
  4481 		// First make a clean copy of the DLLs to the MMC card.
  4482 		allOk = ETrue;			
  4483 		if (KErrNone != CopyFileToMMc(fs, pFileMan, mmcPath, TestPsExeNames[KTestMediaBase], TestPsExeNames[KTestMediaMmc]))
  4484 			allOk = EFalse;
  4485 		if (KErrNone != CopyFileToMMc(fs, pFileMan, mmcPath, TestPlExeNames[KTestMediaBase], TestPlExeNames[KTestMediaMmc]))
  4486 			allOk = EFalse;
  4487 		for (dllIndex = 0; dllIndex < PAGELDRTST_MAX_DLLS; dllIndex ++)
  4488 			{
  4489 			filename.Format(_L("%S%d%S"), &KDllBaseName, dllIndex, &TestPlExtNames[KTestMediaBase]);
  4490 			newFilename.Format(_L("%S%d%S"), &KDllBaseName, dllIndex, &TestPlExtNames[KTestMediaMmc]);
  4491 			if (KErrNone != CopyFileToMMc(fs, pFileMan, mmcPath, filename, newFilename))
  4492 				allOk = EFalse;
  4493 			}
  4494 		TestDllExesExist[KTestMediaMmc] = allOk;
  4495 		DBGS_PRINT((_L("%S : %S! (Drive %c)\n"), &TestPsExeNames[index], EXISTS(!TestDllExesExist[index]), mmcPath[0]));
  4496 #ifdef TEST_ADD_FRAGD_MEDIA
  4497 		//now make some fragmented files on the MMC card.
  4498 		TestDllExesExist[KTestMediaMmcFrag] = CopyAndFragmentFiles(fs, pFileMan, mmcPath, KTestMediaMmcFrag);
  4499 		DBGS_PRINT((_L("%S : %S! (Drive %c)\n"), &TestPsExeNames[KTestMediaMmcFrag], EXISTS(!TestDllExesExist[KTestMediaMmcFrag]), mmcPath[0]));
  4500 
  4501 		//now make some fragmented files on the NAND card.
  4502 		if (nandDrvNum >= 0)
  4503 			{
  4504 			mmcPath[0] = 'a' + nandDrvNum;
  4505 			TestDllExesExist[KTestMediaNandFrag] = CopyAndFragmentFiles(fs, pFileMan, mmcPath, KTestMediaNandFrag);
  4506 			DBGS_PRINT((_L("%S : %S! (Drive %c)\n"), &TestPsExeNames[KTestMediaNandFrag], EXISTS(!TestDllExesExist[KTestMediaNandFrag]), mmcPath[0]));
  4507 			}
  4508 		else
  4509 			DBGS_PRINT((_L("CheckFilePresence : Failed to get NAND drive number\n")));
  4510 #endif // TEST_ADD_FRAGD_MEDIA
  4511 		delete pFileMan; pFileMan = NULL;
  4512 		delete cleanupStack; cleanupStack = NULL;
  4513 		}
  4514 
  4515 	fs.Close();
  4516 
  4517 	TUint end = User::TickCount();
  4518 	TUint time = TUint((TUint64)(end-start)*(TUint64)TickPeriod/(TUint64)1000000);
  4519 	DBGS_PRINT((_L("CheckFilePresence : %d secs elapsed\n"), time));
  4520 	}
  4521 
  4522 //
  4523 // DoDeleteFile
  4524 //
  4525 // Delete a file and remove the hash
  4526 //
  4527 
  4528 void DoDeleteFile(CFileMan* aFileMan, TBool aSilent,TFileName& aFileName )
  4529 	{
  4530 	TFileName hashName;
  4531 	RLoader l;
  4532 	test(l.Connect() == KErrNone);
  4533 
  4534 	DBGD_PRINT((_L("Deleting %S ...\n"), &aFileName));
  4535 	if (!aSilent)
  4536 		DBGD_PRINT((_L("Deleting %S\n"), &aFileName));
  4537 	TInt retVal = aFileMan->Delete(aFileName);
  4538 	if (retVal != KErrNone)
  4539 		{
  4540 		if (TestingReaper)
  4541 			{
  4542 			aFileMan->Attribs(aFileName, KEntryAttNormal, KEntryAttReadOnly, 0);
  4543 			retVal = l.Delete(aFileName);
  4544 			if (retVal != KErrNone)
  4545 				{
  4546 				DBGS_PRINT((_L("RLoader::Delete %S Failed %d\n"), &aFileName, retVal));
  4547 				}
  4548 			}
  4549 		else
  4550 			{
  4551 			if (!aSilent)
  4552 				DBGS_PRINT((_L("Deleting %S Failed %d\n"), &aFileName, retVal));
  4553 			}
  4554 		}
  4555 	GetHashFileName(aFileName, hashName);
  4556 	retVal = aFileMan->Delete(hashName);
  4557 	if (retVal != KErrNone)
  4558 		{
  4559 		if (TestingReaper && (retVal == KErrInUse))
  4560 			{
  4561 			retVal = l.Delete(hashName);
  4562 			if (retVal != KErrNone)
  4563 				{
  4564 				DBGS_PRINT((_L("RLoader::Delete %S Failed %d\n"), &hashName, retVal));
  4565 				}
  4566 			}
  4567 		else
  4568 			{
  4569 			if (!aSilent)
  4570 				DBGS_PRINT((_L("Deleting %S Failed %d\n"), &hashName, retVal));
  4571 			}
  4572 		}
  4573 	l.Close();
  4574 	}
  4575 
  4576 //
  4577 // CleanupFiles
  4578 //
  4579 // Remove any copied files and created directories.
  4580 //
  4581 
  4582 void CleanupFiles(TBool silent)
  4583 	{
  4584 	TUint start = User::TickCount();
  4585 
  4586 	RFs fs;
  4587 	if (KErrNone != fs.Connect())
  4588 		{
  4589 		DBGS_PRINT(_L("CleanupFiles : Can't connect to the FS\n"));
  4590 		return ;
  4591 		}
  4592 
  4593 	CTrapCleanup* cleanupStack = CTrapCleanup::New();
  4594 	if(!cleanupStack)
  4595 		if (!silent)
  4596 			DBGS_PRINT((_L("Cleanup stack failed\n")));	
  4597 	
  4598 	CFileMan* pFileMan = NULL;
  4599 	TInt retVal;
  4600 	TRAP(retVal, pFileMan = CFileMan::NewL(fs));
  4601 	
  4602 	TFileName newPath;
  4603 	TInt index;
  4604 	TInt dllIndex;
  4605 
  4606 	TBuf<32>	path;
  4607 	path.Format(_L("%S"),&KMmcDefaultPath);
  4608 	TInt mmcDrvNum = FindMMCDriveNumber(fs);
  4609 	TInt nandDrvNum = FindFsNANDDrive(fs);
  4610 	for (index = KTestMediaMmc; index < KTestMediaCOUNT; index ++)
  4611 		{
  4612 #ifdef TEST_ADD_FRAGD_MEDIA
  4613 		if (index == KTestMediaNandFrag)
  4614 			{
  4615 			if (nandDrvNum < 0)
  4616 				continue;
  4617 			path[0] = 'a' + nandDrvNum;
  4618 			}
  4619 		else
  4620 			{
  4621 			if (mmcDrvNum < 0)
  4622 				continue;
  4623 			path[0] = 'a' + mmcDrvNum;
  4624 			}
  4625 #else
  4626 		path[0] = 'a' + mmcDrvNum;
  4627 #endif
  4628 		newPath.Format(_L("%S%S"),&path, &TestPsExeNames[index]);
  4629 		DoDeleteFile(pFileMan, silent,  newPath);
  4630 
  4631 		newPath.Format(_L("%S%S"),&path, &TestPlExeNames[index]);
  4632 		DoDeleteFile(pFileMan, silent,  newPath);
  4633 		
  4634 		for (dllIndex = 0; dllIndex < PAGELDRTST_MAX_DLLS; dllIndex ++)
  4635 			{
  4636 			newPath.Format(_L("%S%S%d%S"), &path, &KDllBaseName, dllIndex, &TestPlExtNames[index]);
  4637 			DoDeleteFile(pFileMan, silent,  newPath);
  4638 			}
  4639 		}
  4640 	if (nandDrvNum >= 0)
  4641 		{
  4642 		path[0] = 'a' + nandDrvNum;
  4643 		fs.RmDir(path);
  4644 		}
  4645 	if (mmcDrvNum >= 0)
  4646 		{
  4647 		path[0] = 'a' + mmcDrvNum;
  4648 		fs.RmDir(path);
  4649 		}
  4650 
  4651 	delete pFileMan; pFileMan = NULL;
  4652 	delete cleanupStack; cleanupStack = NULL;
  4653 	fs.Close();
  4654 	TUint end = User::TickCount();
  4655 	TUint time = TUint((TUint64)(end-start)*(TUint64)TickPeriod/(TUint64)1000000);
  4656 	DBGS_PRINT((_L("CleanupFiles : %d secs elapsed\n"), time));
  4657 	}
  4658 
  4659 #ifdef _DEBUG
  4660 
  4661 //
  4662 // FindLocalDriveNumber
  4663 //
  4664 // Find the local drive
  4665 //
  4666 
  4667 TInt FindLocalDriveNumber(RFs &aFs, TInt aFsDrvNum)
  4668 	{
  4669 	RFile file;
  4670 	TBuf<256> fileName;	
  4671 	fileName.Append((TChar)('A' + aFsDrvNum));
  4672 	fileName+=_L(":\\f32-tst\\");
  4673 	TInt r=aFs.MkDirAll(fileName);
  4674 	TInt locDriveNumber = -1;
  4675 	if (r==KErrNone || r== KErrAlreadyExists)
  4676 		{
  4677 		fileName += _L("tempy.txt");
  4678 		r=file.Replace(aFs,fileName,EFileWrite);
  4679 		if (r!=KErrNone)
  4680 			DBGS_PRINT((_L("FindLocalDriveNumber : Error %d: file '%S' could not be created\n"),r,&fileName));
  4681 		RUNTEST1(r==KErrNone);
  4682 		r=file.Write(_L8("Flies as big as sparrows indoletly buzzing in the warm air, heavy with the stench of rotting carcasses"));
  4683 		if (r!=KErrNone)
  4684 			{
  4685 			DBGS_PRINT((_L("FindLocalDriveNumber : Error %d: could not write to file %d (%S)\n"),r,aFsDrvNum, &fileName));
  4686 			}
  4687 		else
  4688 			{
  4689 			// write caching may be enabled to flush the cache...
  4690 			TRequestStatus flushStatus;
  4691 			file.Flush(flushStatus);
  4692 			User::WaitForRequest(flushStatus);
  4693 			// get the block map
  4694 			SBlockMapInfo info;
  4695 			TInt64 start=0;
  4696 			r=file.BlockMap(info, start, -1,ETestDebug);
  4697 			if (r==KErrNone || r==KErrCompletion)
  4698 				{
  4699 				locDriveNumber=info.iLocalDriveNumber;
  4700 				DBGD_PRINT((_L("FindLocalDriveNumber : locDriveNumber  %d\n"), locDriveNumber));
  4701 				}
  4702 			else
  4703 				DBGS_PRINT((_L("FindLocalDriveNumber : Error %d: error getting blockmap for drive %d (%S)\n"),r,aFsDrvNum, &fileName));
  4704 			}
  4705 		aFs.Delete(fileName);
  4706 		file.Close();
  4707 		}
  4708 	else
  4709 		DBGS_PRINT((_L("FindLocalDriveNumber : Error %d: error creating dir	\n"),r));
  4710 	return locDriveNumber;
  4711 	}
  4712 
  4713 //
  4714 // ResetConcurrencyStats
  4715 //
  4716 // Reset the stats
  4717 //
  4718 
  4719 void ResetConcurrencyStats(RFs& aFs)
  4720 	{
  4721 	if(TestBootedFromMmc)
  4722 		{
  4723 		TInt fsDriveNum = FindMMCDriveNumber(aFs);
  4724 		if (fsDriveNum >= 0)
  4725 			{
  4726 			TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum);
  4727 			if (locDriveNumber >= 0)
  4728 				{
  4729 				RUNTEST(PagingInfo::ResetConcurrency(locDriveNumber,EMediaPagingStatsRomAndCode),KErrNone);
  4730 				}
  4731 			else
  4732 				DBGS_PRINT((_L("ResetConcurrencyStats MMC : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum));
  4733 			}
  4734 		else
  4735 			DBGS_PRINT((_L("ResetConcurrencyStats MMC : Failed to get fsDriveNum %d\n"), fsDriveNum));
  4736 		}
  4737 	else
  4738 		{
  4739 		TInt fsDriveNum = FindFsNANDDrive(aFs);
  4740 		if (fsDriveNum >= 0)
  4741 			{
  4742 			TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum);
  4743 			if (locDriveNumber >= 0)
  4744 				{
  4745 				RUNTEST(PagingInfo::ResetConcurrency(locDriveNumber,EMediaPagingStatsRomAndCode),KErrNone);
  4746 				}
  4747 			else
  4748 				DBGS_PRINT((_L("ResetConcurrencyStats NAND : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum));
  4749 			}
  4750 		else
  4751 			DBGS_PRINT((_L("ResetConcurrencyStats NAND : Failed to get fsDriveNum %d\n"), fsDriveNum));
  4752 		}
  4753 	}
  4754 
  4755 //
  4756 // ResetBenchmarks
  4757 //
  4758 // Reset the stats
  4759 //
  4760 
  4761 void ResetBenchmarks(RFs& aFs)
  4762 	{
  4763 	if(TestBootedFromMmc)
  4764 		{
  4765 		TInt fsDriveNum = FindMMCDriveNumber(aFs);
  4766 		if (fsDriveNum >= 0)
  4767 			{
  4768 			TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum);
  4769 			if (locDriveNumber >= 0)
  4770 				{
  4771 				RUNTEST(PagingInfo::ResetBenchmarks(locDriveNumber,EMediaPagingStatsRomAndCode),KErrNone);
  4772 				}
  4773 			else
  4774 				DBGS_PRINT((_L("ResetBenchmarks MMC : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum));
  4775 			}
  4776 		else
  4777 			DBGS_PRINT((_L("ResetBenchmarks MMC : Failed to get fsDriveNum %d\n"), fsDriveNum));
  4778 		}
  4779 	else
  4780 		{
  4781 		TInt fsDriveNum = FindFsNANDDrive(aFs);
  4782 		if (fsDriveNum >= 0)
  4783 			{
  4784 			TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum);
  4785 			if (locDriveNumber >= 0)
  4786 				{
  4787 				RUNTEST(PagingInfo::ResetBenchmarks(locDriveNumber,EMediaPagingStatsRomAndCode),KErrNone);
  4788 				}
  4789 			else
  4790 				DBGS_PRINT((_L("ResetBenchmarks NAND : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum));
  4791 			}
  4792 		else
  4793 			DBGS_PRINT((_L("ResetBenchmarks NAND : Failed to get fsDriveNum %d\n"), fsDriveNum));
  4794 		}
  4795 	}
  4796 
  4797 //
  4798 // DisplayConcurrencyStats
  4799 //
  4800 // Display the stats
  4801 //
  4802 
  4803 void DisplayConcurrencyStats(RFs& aFs)
  4804 	{
  4805 	if(TestBootedFromMmc)
  4806 		{
  4807 		TInt fsDriveNum = FindMMCDriveNumber(aFs);
  4808 		if (fsDriveNum >= 0)
  4809 			{
  4810 			TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum);
  4811 			if (locDriveNumber >= 0)
  4812 				{
  4813 				DBGS_PRINT((_L("MMC stats\n")));
  4814 				RUNTEST1(PagingInfo::PrintConcurrency(locDriveNumber,EMediaPagingStatsRomAndCode)==KErrNone);
  4815 				}
  4816 			else
  4817 				DBGS_PRINT((_L("DisplayConcurrencyStats MMC : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum));
  4818 			}
  4819 		else
  4820 			DBGS_PRINT((_L("DisplayConcurrencyStats MMC : Failed to get fsDriveNum %d\n"), fsDriveNum));
  4821 		}
  4822 	else
  4823 		{
  4824 		TInt fsDriveNum = FindFsNANDDrive(aFs);
  4825 		if (fsDriveNum >= 0)
  4826 			{
  4827 			TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum);
  4828 
  4829 			if (locDriveNumber >= 0)
  4830 				{
  4831 				DBGS_PRINT((_L("NAND stats\n")));
  4832 				RUNTEST1(PagingInfo::PrintConcurrency(locDriveNumber,EMediaPagingStatsRomAndCode)==KErrNone);
  4833 				}
  4834 			else
  4835 				DBGS_PRINT((_L("DisplayConcurrencyStats NAND : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum));
  4836 			}
  4837 		else
  4838 			DBGS_PRINT((_L("DisplayConcurrencyStats NAND : Failed to get fsDriveNum %d\n"), fsDriveNum));
  4839 		}
  4840 	}
  4841 
  4842 void DisplayBenchmarks(RFs& aFs)
  4843 	{
  4844 	if(TestBootedFromMmc)
  4845 		{
  4846 		TInt fsDriveNum = FindMMCDriveNumber(aFs);
  4847 		if (fsDriveNum >= 0)
  4848 			{
  4849 			TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum);
  4850 			if(locDriveNumber>=0)
  4851 				{
  4852 				DBGS_PRINT((_L("MMC benchmarks\n")));
  4853 				RUNTEST1(PagingInfo::PrintBenchmarks(locDriveNumber,EMediaPagingStatsRomAndCode)==KErrNone);
  4854 				}
  4855 			else
  4856 				DBGS_PRINT((_L("DisplayBenchmarks MMC : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum));
  4857 			}
  4858 		else
  4859 			DBGS_PRINT((_L("DisplayBenchmarks MMC : Failed to get fsDriveNum %d\n"), fsDriveNum));
  4860 		}
  4861 	else
  4862 		{
  4863 		TInt fsDriveNum = FindFsNANDDrive(aFs);
  4864 		if (fsDriveNum >= 0)
  4865 			{
  4866 			TInt locDriveNumber = FindLocalDriveNumber(aFs, fsDriveNum);
  4867 			if(locDriveNumber>=0)
  4868 				{
  4869 				DBGS_PRINT((_L("NAND benchmarks\n")));
  4870 				RUNTEST1(PagingInfo::PrintBenchmarks(locDriveNumber,EMediaPagingStatsRomAndCode)==KErrNone);
  4871 				}
  4872 			else
  4873 				DBGS_PRINT((_L("DisplayBenchmarks NAND : Failed to get locDriveNumber %d (%d)\n"), locDriveNumber, fsDriveNum));
  4874 			}
  4875 		else
  4876 			DBGS_PRINT((_L("DisplayBenchmarks NAND : Failed to get fsDriveNum %d\n"), fsDriveNum));
  4877 		}
  4878 	}
  4879 
  4880 #endif
  4881 
  4882 void DoStats()
  4883 	{
  4884 	if (TestIsDemandPaged)
  4885 		{
  4886 		SVMCacheInfo  tempPages;
  4887 		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
  4888 		DBGS_PRINT((_L("DPC : min %d max %d curr %d\n"), 
  4889 					tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize));
  4890 		DBGS_PRINT((_L("    : maxFree %d freeRam %d\n"),
  4891 					tempPages.iMaxFreeSize, FreeRam()));
  4892 		}
  4893 
  4894 #ifdef _DEBUG
  4895 	if (TestWeAreTheTestBase && !TestSilent)
  4896 		{
  4897 		RFs fs;
  4898 		if (KErrNone != fs.Connect())
  4899 			{
  4900 			DBGS_PRINT(_L("ResetConcurrencyStats : Can't connect to the FS\n"));
  4901 			return;
  4902 			}
  4903 
  4904 #ifndef TEST_MINIMAL_STATS
  4905 		DisplayConcurrencyStats(fs);
  4906 		DisplayBenchmarks(fs);
  4907 #endif
  4908 #ifndef TEST_DONT_RESET_STATS
  4909 		ResetConcurrencyStats(fs);
  4910 		ResetBenchmarks(fs);
  4911 #endif
  4912 		fs.Close();
  4913 		}
  4914 #endif
  4915 	}
  4916 
  4917 
  4918 //
  4919 // E32Main
  4920 //
  4921 // Main entry point.
  4922 //
  4923 
  4924 TInt E32Main()
  4925 	{
  4926 #ifndef TEST_ON_UNPAGED
  4927 	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
  4928 	if(!romHeader->iPageableRomStart)
  4929 		{
  4930 		TestIsDemandPaged = EFalse;
  4931 		}
  4932 #endif
  4933 	// Turn off lazy dll unloading
  4934 	RLoader l;
  4935 	if (l.Connect() == KErrNone)
  4936 		{
  4937 		l.CancelLazyDllUnload();
  4938 		l.Close();
  4939 		}
  4940 	
  4941 	HAL::Get(HAL::ESystemTickPeriod, TickPeriod);
  4942 
  4943 	SVMCacheInfo  tempPages;
  4944 	memset(&tempPages, 0, sizeof(tempPages));
  4945 
  4946 	TBool parseResult = ParseCommandLine();
  4947 
  4948 	if (TestExit)
  4949 		{
  4950 		return KErrNone;
  4951 		}
  4952 
  4953 	TUint start = User::TickCount();
  4954 	
  4955 	AreWeTheTestBase();	
  4956 
  4957 	if (TestIsDemandPaged)
  4958 		{
  4959 		TInt  minSize = TestMinCacheSize;
  4960 		TInt  maxSize = TestMaxCacheSize;
  4961 
  4962 		SVMCacheInfo  tempPages;
  4963 
  4964 		// get the old cache info
  4965 		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
  4966 		// set the cache to our test value
  4967 		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
  4968 		}
  4969 	if (!TestSilent)
  4970 		{
  4971 		test.Title();
  4972 		test.Start(_L("Demand Paging loader stress tests..."));
  4973 		test.Printf(_L("%S (%d)\n"), &TestNameBuffer, TestWeAreTheTestBase);
  4974 		test.Printf(_L("TestBootedFromMmc %d\n"), TestBootedFromMmc);
  4975 
  4976 		if (TestWeAreTheTestBase)
  4977 			CleanupFiles(ETrue);
  4978 
  4979 		CheckFilePresence(TestWeAreTheTestBase);
  4980 		}
  4981 
  4982 	if (parseResult)
  4983 		{
  4984 		if (TestLowMem)
  4985 			{
  4986 			DoLowMemTest(ETrue);
  4987 			}
  4988 		if (TestSingle)
  4989 			{
  4990 			RUNTEST(DoSingleTest(),KErrNone);
  4991 			}
  4992 		if (TestMultiple)
  4993 			{
  4994 			RUNTEST(DoMultipleTest(),KErrNone);
  4995 			}
  4996 		if (TestD_Exc)
  4997 			{
  4998 			RUNTEST(DoTestD_Exc(),KErrNone);
  4999 			}
  5000 		if (TestChunks)
  5001 			{
  5002 			DoChunkTests();
  5003 			}
  5004 		if (TestReaper)
  5005 			{
  5006 			DoReaperTests();
  5007 			}
  5008 		if (TestBtrace)
  5009 			{
  5010 			DoBtraceTest();
  5011 			}
  5012 		if (TestDefrag)
  5013 			{
  5014 			DoDefragTest();
  5015 			}
  5016 		}
  5017 	else
  5018 		{
  5019 #ifdef _DEBUG
  5020 		if (TestWeAreTheTestBase)
  5021 			{
  5022 			RFs fs;
  5023 			if (KErrNone == fs.Connect())
  5024 				{
  5025 				//fs.SetDebugRegister(KCACHE);
  5026 				ResetConcurrencyStats(fs);
  5027 				ResetBenchmarks(fs);
  5028 				fs.Close();
  5029 				}
  5030 			}
  5031 #endif
  5032 
  5033 		while (1)
  5034 			{
  5035 			if (TestIsDemandPaged)
  5036 				{
  5037 #ifdef TEST_RUN_AUTOTEST
  5038 				PerformAutoTest();
  5039 #endif //TEST_RUN_AUTOTEST
  5040 
  5041 #ifndef	TEST_SHORT_TEST
  5042 #ifdef TEST_RUN_LOWMEMTEST
  5043 				DoLowMemTest(ETrue);
  5044 #endif //TEST_RUN_LOWMEMTEST
  5045 #ifdef TEST_RUN_CHUNKTEST
  5046 				DoChunkTests();
  5047 #endif //TEST_RUN_CHUNKTEST
  5048 #ifdef TEST_RUN_REAPERTEST
  5049 				DoReaperTests();
  5050 #endif //TEST_RUN_REAPERTEST
  5051 #endif //TEST_SHORT_TEST
  5052 				}
  5053 
  5054 #ifdef TEST_RUN_DEFRAGTEST
  5055 			DoDefragTest();
  5056 #endif //TEST_RUN_DEFRAGTEST
  5057 
  5058 			if (TestStressFree)
  5059 				{
  5060 				TInt minSize = 512 * 4096;
  5061 				TInt maxSize = 32767 * 4096;
  5062 				UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
  5063 
  5064 				test.Printf(_L("%S Stress Free!!\n"), &TestNameBuffer, TestWeAreTheTestBase);
  5065 				TestStressFree = EFalse;
  5066 				}
  5067 			else
  5068 				{
  5069 				break;
  5070 				}
  5071 			}
  5072 
  5073 #ifndef TEST_SHORT_TEST
  5074 #ifndef TEST_NO_DEXC_IN_AUTO
  5075 #ifdef TEST_RUN_D_EXCTEST
  5076 		RUNTEST(DoTestD_Exc(),KErrNone);
  5077 #endif //TEST_RUN_D_EXCTEST
  5078 #endif //TEST_NO_DEXC_IN_AUTO
  5079 		if (TestWeAreTheTestBase && TestFullAutoTest && TestIsDemandPaged)
  5080 			{
  5081 			RProcess		theProcess;
  5082 			TRequestStatus	status;
  5083 
  5084 			TInt retVal = theProcess.Create(_L("t_pageldrtst_rom.exe"),_L("fullauto"));
  5085 			if (retVal != KErrNotFound)
  5086 				{
  5087 				RUNTEST1(KErrNone == retVal);
  5088 				theProcess.Logon(status);
  5089 				RUNTEST1(status == KRequestPending);	
  5090 				theProcess.Resume();
  5091 #ifdef TEST_THRASHING_TEST
  5092 				while (1)
  5093 					{
  5094 					if (theProcess.ExitType() != EExitPending)
  5095 						{
  5096 						RUNTEST1(theProcess.ExitType() != EExitPanic);
  5097 						break;
  5098 						}
  5099 					User::AfterHighRes(1);
  5100 					}
  5101 				User::WaitForRequest(status);
  5102 #else
  5103 				User::WaitForRequest(status);
  5104 				if (theProcess.ExitType() != EExitPending)
  5105 					{
  5106 					RUNTEST1(theProcess.ExitType() != EExitPanic);
  5107 					}
  5108 #endif //TEST_THRASHING_TEST
  5109 				theProcess.Close();
  5110 				}
  5111 			}
  5112 #endif //TEST_SHORT_TEST
  5113 #ifdef _DEBUG
  5114 		if (TestWeAreTheTestBase && !TestSilent)
  5115 			{
  5116 			RFs fs;
  5117 			if (KErrNone == fs.Connect())
  5118 				{
  5119 				DisplayConcurrencyStats(fs);
  5120 				DisplayBenchmarks(fs);
  5121 				fs.Close();
  5122 				}
  5123 			}
  5124 #endif
  5125 		}
  5126 
  5127 	if (TestWeAreTheTestBase && !TestNoClean)
  5128 		CleanupFiles(EFalse);
  5129 
  5130 	if (TestIsDemandPaged)
  5131 		{
  5132 		TInt minSize = tempPages.iMinSize;
  5133 		TInt maxSize = tempPages.iMaxSize;
  5134 		// put the cache back to the the original values.
  5135 		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
  5136 		}
  5137 	if (!TestSilent)
  5138 		{
  5139 		TUint end = User::TickCount();
  5140 		TUint time = TUint((TUint64)(end-start)*(TUint64)TickPeriod/(TUint64)1000000);
  5141 		test.Printf(_L("%S : Complete (%u seconds)\n"), &TestNameBuffer, time);	
  5142 		test.End();
  5143 		}
  5144 	return KErrNone;
  5145 	}