kerneltest/f32test/demandpaging/t_pagestress.cpp
changeset 43 96e5fb8b040d
child 33 0173bcd7697c
equal deleted inserted replaced
-1:000000000000 43:96e5fb8b040d
       
     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\t_pagestress.cpp
       
    15 // Demand Paging Stress Tests
       
    16 // t_pagestress.exe basically attempts to cause large ammounts of paging by calling
       
    17 // functions (256) which are alligned on a page boundary from multiple threads.
       
    18 // There are mulitple versions of t_pagestress installed on a test system to test rom
       
    19 // and code paging from various media types.
       
    20 // Usage:
       
    21 // t_pagestress and t_pagestress_rom
       
    22 // Common command lines:
       
    23 // t_pagestress lowmem
       
    24 // debug - switch on debugging information
       
    25 // silent - no output to the screen or serial port
       
    26 // check - check the allignments
       
    27 // single - run the tests in a single thread
       
    28 // multiple <numThreads> - run the tests in multiple threads where <numThreads>
       
    29 // interleave - force thread interleaving
       
    30 // prio - each thread reschedules in between each function call, causes lots of context changes
       
    31 // media - perform media access during the tests, very stressful
       
    32 // lowmem - low memory tests
       
    33 // forward - patern in which to execute function calls 
       
    34 // backward - patern in which to execute function calls 			
       
    35 // random - patern in which to execute function calls 			
       
    36 // all - patern in which to execute function calls (forward, backward and random)
       
    37 // inst - for debugging a parameter passed to a spawned exe to give it an id.
       
    38 // iters <count> - the number of times to loop (a '-' means run forever)
       
    39 // t_pagestress causes a large ammount of paging by repeatedly calling 
       
    40 // 256 functions which have been aligned on page boundaries from 
       
    41 // multiple threads.
       
    42 // 1  - a single thread calling all functions
       
    43 // 2  - Multiple threads calling all functions
       
    44 // 3  - Multiple threads calling all functions with a priority change 
       
    45 // after each function call
       
    46 // 4  - Multiple threads calling all functions with background 
       
    47 // media activity
       
    48 // 5  - Multiple threads calling all functions with media activity and 
       
    49 // a priority change after each function call
       
    50 // 6  - Multiple threads calling all functions with process interleave
       
    51 // 7  - Multiple threads calling all functions with process interleave 
       
    52 // and a priority change after each function call
       
    53 // 8  - Multiple threads calling all functions with process interleave 
       
    54 // media acess and a priority change after each function call
       
    55 // 9  - Multiple threads calling all functions with low available memory
       
    56 // 10 - Multiple threads calling all functions with low available memory,
       
    57 // starting with initial free ram.
       
    58 // 
       
    59 //
       
    60 
       
    61 //! @SYMTestCaseID			KBASE-T_PAGESTRESS-0327
       
    62 //! @SYMTestType			UT
       
    63 //! @SYMPREQ				PREQ1110
       
    64 //! @SYMTestCaseDesc		Demand Paging Stress Tests
       
    65 //! @SYMTestActions			0  - Check the alignment of all functions
       
    66 //! @SYMTestExpectedResults All tests should pass.
       
    67 //! @SYMTestPriority        High
       
    68 //! @SYMTestStatus          Implemented
       
    69 
       
    70 #include <e32test.h>
       
    71 RTest test(_L("T_PAGESTRESS"));
       
    72 
       
    73 #include <e32rom.h>
       
    74 #include <u32hal.h>
       
    75 #include <f32file.h>
       
    76 #include <f32dbg.h>
       
    77 #include <e32msgqueue.h>
       
    78 #include <e32math.h>
       
    79 
       
    80 #include "testdefs.h"
       
    81 
       
    82 #ifdef __X86__
       
    83 #define TEST_ON_UNPAGED
       
    84 #endif
       
    85 
       
    86 
       
    87 /* The following line will cause t_pagestress.h to declare an array of function
       
    88  * pointers to  page boundary aligned functions that we can use in this test...
       
    89  */
       
    90 #define TPS_DECLARE_ARRAY
       
    91 #include "t_pagestress.h"
       
    92 
       
    93 TBool   	TestDebug					= EFalse;
       
    94 TBool		TestSilent					= EFalse;
       
    95 TBool		TestExit					= EFalse;
       
    96 
       
    97 TBool   	TestCheck					= EFalse;
       
    98 TBool   	TestSingle					= EFalse;
       
    99 TBool   	TestMultiple				= EFalse;
       
   100 TBool   	TestForever					= EFalse;
       
   101 TInt		TestMaxLoops				= 20;
       
   102 TInt		TestMultipleThreadCount		= 50;
       
   103 TInt		TestInstanceId				= 0;
       
   104 
       
   105 #define TEST_INTERLEAVE_PRIO		EPriorityMore//EPriorityRealTime //23 // KNandThreadPriority - 1
       
   106 TBool		TestInterleave				= EFalse;
       
   107 TBool		TestWeAreTheTestBase		= EFalse;
       
   108 TBool		TestBootedFromMmc			= EFalse;
       
   109 TInt		DriveNumber=-1;   // Parameter - Which drive?  -1 = autodetect.
       
   110 #define TEST_NONE		0x0
       
   111 #define TEST_FORWARD	0x2
       
   112 #define TEST_BACKWARD	0x4
       
   113 #define TEST_RANDOM		0x8
       
   114 #define TEST_ALL		(TEST_RANDOM | TEST_BACKWARD | TEST_FORWARD)
       
   115 TUint32		TestWhichTests				= TEST_ALL;
       
   116 TBuf<32>	TestNameBuffer;
       
   117 TBool		TestPrioChange				= ETrue;
       
   118 TBool		TestStopMedia				= EFalse;
       
   119 TBool		TestMediaAccess				= EFalse;
       
   120 #define TEST_LM_NUM_FREE	0
       
   121 #define TEST_LM_BLOCKSIZE	1
       
   122 #define TEST_LM_BLOCKS_FREE	4
       
   123 TBool		TestLowMem					= EFalse;
       
   124 RPageStressTestLdd Ldd;
       
   125 TInt		TestPageSize				= 4096;
       
   126 RSemaphore	TestMultiSem;
       
   127 RMsgQueue<TBuf <64> >	TestMsgQueue;
       
   128 TBool		TestIsDemandPaged = ETrue;
       
   129 
       
   130 
       
   131 #define TEST_NEXT(__args) \
       
   132 	if (!TestSilent)\
       
   133 		test.Next __args;
       
   134 
       
   135 #define DBGS_PRINT(__args)\
       
   136 	if (!TestSilent)\
       
   137 		test.Printf __args ;
       
   138 
       
   139 #define DBGD_PRINT(__args)\
       
   140 	if (TestDebug)\
       
   141 		test.Printf __args ;\
       
   142 
       
   143 #define DEBUG_PRINT(__args)\
       
   144 if (!TestSilent)\
       
   145 	{\
       
   146 	if (aMsgQueue && aBuffer && aTheSem)\
       
   147 		{\
       
   148 		aBuffer->Zero();\
       
   149 		aBuffer->Format __args ;\
       
   150 		aTheSem->Wait();\
       
   151 		aMsgQueue->SendBlocking(*aBuffer);\
       
   152 		aTheSem->Signal();\
       
   153 		}\
       
   154 	else\
       
   155 		{\
       
   156 		test.Printf __args ;\
       
   157 		}\
       
   158 	}
       
   159 
       
   160 #define RUNTEST(__test, __error)\
       
   161 	if (!TestSilent)\
       
   162 		test(__test == __error);\
       
   163 	else\
       
   164 		__test;
       
   165 
       
   166 #define RUNTEST1(__test)\
       
   167 	if (!TestSilent)\
       
   168 		test(__test);
       
   169 
       
   170 #define DEBUG_PRINT1(__args)\
       
   171 if (TestDebug)\
       
   172 	{\
       
   173 	DEBUG_PRINT(__args)\
       
   174 	}
       
   175 
       
   176 //
       
   177 // CheckAlignments
       
   178 //
       
   179 // The following functions wanders through the function pointer array
       
   180 // declared in t_pagestress.h and ensures that the alignment has worked, 
       
   181 // (a good start!) and then calls each of the functions in turn to 
       
   182 // ensure that they work, simple first sanity check test.
       
   183 //
       
   184 
       
   185 TInt CheckAlignments()
       
   186 	{
       
   187 	// now it's time to play with the array of function pointers...
       
   188 	TInt  seed = 1;
       
   189 	TUint32 index = 0;
       
   190 	TInt ret = KErrNone;
       
   191 
       
   192 	while (index < (PAGESTRESS_FUNC_COUNT - 1))
       
   193 		{
       
   194 		DBGD_PRINT((_L("\nAddress (%u) 0x%x difference to next %u\n"), index, (TUint32)PagestressFuncPtrs[index], (TUint32)PagestressFuncPtrs[index + 1] - (TUint32)PagestressFuncPtrs[index]));	
       
   195 		if ((((TUint32)PagestressFuncPtrs[index + 1] - (TUint32)PagestressFuncPtrs[0]) % 4096) != 0)
       
   196 			{
       
   197 			DBGS_PRINT((_L("\nError! Allignment for %u is not offset of 4096 from index 0 0x%x 0x%x\n"), index, (TUint32)PagestressFuncPtrs[index + 1], (TUint32)PagestressFuncPtrs[0]));	
       
   198 			ret = KErrGeneral;
       
   199 			}
       
   200 		//seed = PagestressFuncPtrs[index](seed, index);
       
   201 		seed = CallTestFunc(seed, index, index);
       
   202 		index ++;
       
   203 		}
       
   204 	return ret;
       
   205 	}
       
   206 
       
   207 //
       
   208 // RunThreadForward
       
   209 //
       
   210 // Walk through the function pointer array (forwards) calling each function
       
   211 //
       
   212 
       
   213 void RunThreadForward()
       
   214 	{
       
   215 	TInt	seed = 1;
       
   216 	TUint32 index = 0;
       
   217 	RThread thisThread;
       
   218 
       
   219 	while (index < PAGESTRESS_FUNC_COUNT)
       
   220 		{
       
   221 		if (TestPrioChange)
       
   222 			{
       
   223 			TThreadPriority originalThreadPriority = thisThread.Priority();
       
   224 			thisThread.SetPriority(EPriorityLess);
       
   225 			User::AfterHighRes(0);
       
   226 			thisThread.SetPriority(originalThreadPriority);
       
   227 			}
       
   228 		//seed = PagestressFuncPtrs[index](seed, index);
       
   229 		seed = CallTestFunc(seed, index, index);
       
   230 		index ++;
       
   231 		}
       
   232 	}
       
   233 
       
   234 //
       
   235 // RunThreadBackward
       
   236 //
       
   237 // Walk through the function pointer array (backwards) calling each function
       
   238 //
       
   239 
       
   240 void RunThreadBackward()
       
   241 	{
       
   242 	TInt	seed = 1;
       
   243 	TInt	index = PAGESTRESS_FUNC_COUNT;
       
   244 	RThread thisThread;
       
   245 
       
   246 	while (index > 0)
       
   247 		{
       
   248 		if (TestPrioChange)
       
   249 			{
       
   250 			TThreadPriority originalThreadPriority = thisThread.Priority();
       
   251 			thisThread.SetPriority(EPriorityLess);
       
   252 			User::AfterHighRes(0);
       
   253 			thisThread.SetPriority(originalThreadPriority);
       
   254 			}
       
   255 		index --;
       
   256 		//seed = PagestressFuncPtrs[index](seed, index);
       
   257 		seed = CallTestFunc(seed, index, index);
       
   258 		}
       
   259 	}
       
   260 
       
   261 //
       
   262 // RunThreadRandom
       
   263 //
       
   264 // Walk through the function pointer array in a random order a number of times calling each function
       
   265 //
       
   266 
       
   267 void RunThreadRandom()
       
   268 	{
       
   269 	TInt	seed = 1;
       
   270 	TInt	index = 0;
       
   271 	TInt	randNum;
       
   272 	RThread thisThread;
       
   273 
       
   274 	while (index < (TInt)PAGESTRESS_FUNC_COUNT)
       
   275 		{
       
   276 		if (TestPrioChange)
       
   277 			{
       
   278 			TThreadPriority originalThreadPriority = thisThread.Priority();
       
   279 			thisThread.SetPriority(EPriorityLess);
       
   280 			User::AfterHighRes(0);
       
   281 			thisThread.SetPriority(originalThreadPriority);
       
   282 			}
       
   283 		randNum = Math::Random();
       
   284 		randNum %= PAGESTRESS_FUNC_COUNT;
       
   285 		//seed = PagestressFuncPtrs[randNum](seed, randNum);
       
   286 		seed = CallTestFunc(seed, randNum, randNum);
       
   287 		index ++;
       
   288 		}
       
   289 	}
       
   290 
       
   291 
       
   292 //
       
   293 // PerformTestThread
       
   294 //
       
   295 // This is the function that actually does the work.
       
   296 // It is complicated a little because test.Printf can only be called from the first thread that calls it 
       
   297 // so if we are using multiple threads we need to use a message queue to pass the debug info from the
       
   298 // child threads back to the parent for the parent to then call printf.
       
   299 //
       
   300 //
       
   301 
       
   302 LOCAL_C void PerformTestThread(TInt					  aThreadIndex, 
       
   303 							   RMsgQueue<TBuf <64> > *aMsgQueue = NULL, 
       
   304 							   TBuf<64>				 *aBuffer = NULL,
       
   305 							   RSemaphore			 *aTheSem = NULL)
       
   306 	{
       
   307 	TUint start = User::TickCount();
       
   308 
       
   309 	DEBUG_PRINT1((_L("%S : thread Starting %d\n"), &TestNameBuffer, aThreadIndex));
       
   310 	
       
   311 	// now select how we do the test...
       
   312 	TInt	iterIndex;
       
   313 
       
   314 	if (TEST_ALL == (TestWhichTests & TEST_ALL))
       
   315 		{
       
   316 		#define LOCAL_ORDER_INDEX1	6
       
   317 		#define LOCAL_ORDER_INDEX2	3
       
   318 		TInt	order[LOCAL_ORDER_INDEX1][LOCAL_ORDER_INDEX2] = {	{TEST_FORWARD, TEST_BACKWARD,TEST_RANDOM},
       
   319 																	{TEST_FORWARD, TEST_RANDOM,  TEST_BACKWARD},
       
   320 																	{TEST_BACKWARD,TEST_FORWARD, TEST_RANDOM},
       
   321 																	{TEST_BACKWARD,TEST_RANDOM,  TEST_FORWARD},
       
   322 																	{TEST_RANDOM,  TEST_FORWARD, TEST_BACKWARD},
       
   323 																	{TEST_RANDOM,  TEST_BACKWARD,TEST_FORWARD}};
       
   324 		TInt	whichOrder = 0;
       
   325 
       
   326 		for (iterIndex = 0; iterIndex < TestMaxLoops; iterIndex ++)
       
   327 			{
       
   328 			TInt    selOrder = ((aThreadIndex + 1) * (iterIndex + 1)) % LOCAL_ORDER_INDEX1;
       
   329 			for (whichOrder = 0; whichOrder < LOCAL_ORDER_INDEX2; whichOrder ++)
       
   330 				{
       
   331 				switch (order[selOrder][whichOrder])
       
   332 					{
       
   333 						case TEST_FORWARD:
       
   334 						DEBUG_PRINT1((_L("%S : %d Iter %d Forward\n"), &TestNameBuffer, aThreadIndex, iterIndex));
       
   335 						RunThreadForward();
       
   336 						break;
       
   337 
       
   338 						case TEST_BACKWARD:
       
   339 						DEBUG_PRINT1((_L("%S : %d Iter %d Backward\n"), &TestNameBuffer, aThreadIndex, iterIndex));
       
   340 						RunThreadBackward();
       
   341 						break;
       
   342 
       
   343 						case TEST_RANDOM:
       
   344 						DEBUG_PRINT1((_L("%S : %d Iter %d Random\n"), &TestNameBuffer, aThreadIndex, iterIndex));
       
   345 						RunThreadRandom();
       
   346 						break;
       
   347 						
       
   348 						default: // this is really an error.
       
   349 						break;
       
   350 					}
       
   351 				}
       
   352 			}
       
   353 		}
       
   354 	else
       
   355 		{
       
   356 		if (TestWhichTests & TEST_FORWARD)
       
   357 			{
       
   358 			for (iterIndex = 0; iterIndex < TestMaxLoops; iterIndex ++)
       
   359 				{
       
   360 				DEBUG_PRINT1((_L("%S : %d Iter %d Forward\n"), &TestNameBuffer, aThreadIndex, iterIndex));
       
   361 				RunThreadForward();
       
   362 				}
       
   363 			}
       
   364 			
       
   365 		if (TestWhichTests & TEST_BACKWARD)
       
   366 			{
       
   367 			for (iterIndex = 0; iterIndex < TestMaxLoops; iterIndex ++)
       
   368 				{
       
   369 				DEBUG_PRINT1((_L("%S : %d Iter %d Backward\n"), &TestNameBuffer, aThreadIndex, iterIndex));
       
   370 				RunThreadBackward();
       
   371 				}
       
   372 			}
       
   373 
       
   374 		if (TestWhichTests & TEST_RANDOM)
       
   375 			{
       
   376 			for (iterIndex = 0; iterIndex < TestMaxLoops; iterIndex ++)
       
   377 				{
       
   378 				DEBUG_PRINT1((_L("%S : %d Iter %d Random\n"), &TestNameBuffer, aThreadIndex, iterIndex));
       
   379 				RunThreadRandom();
       
   380 				}
       
   381 			}
       
   382 		}
       
   383 	DEBUG_PRINT1((_L("%S : thread Exiting %d (tickcount %u)\n"), &TestNameBuffer, aThreadIndex, User::TickCount() - start));
       
   384 	}
       
   385 
       
   386 
       
   387 //
       
   388 // MultipleTestThread
       
   389 //
       
   390 // Thread function, one created for each thread in a multiple thread test.
       
   391 //
       
   392 
       
   393 LOCAL_C TInt MultipleTestThread(TAny* aUseTb)
       
   394 	{
       
   395 	TBuf<64>					localBuffer;
       
   396 
       
   397 	if (TestInterleave)	
       
   398 		{
       
   399 		RThread				thisThread;
       
   400 		thisThread.SetPriority((TThreadPriority) TEST_INTERLEAVE_PRIO);
       
   401 		}
       
   402 
       
   403 	PerformTestThread((TInt) aUseTb, &TestMsgQueue, &localBuffer, &TestMultiSem);
       
   404 	
       
   405 	return KErrNone;
       
   406 	}
       
   407 
       
   408 //
       
   409 // DoSingleTest
       
   410 // 
       
   411 // Perform the single thread test, spawning a number of threads.
       
   412 //
       
   413 
       
   414 LOCAL_C void DoSingleTest()
       
   415 	{
       
   416 	PerformTestThread((TInt) TestInstanceId);
       
   417 	}
       
   418 
       
   419 //
       
   420 // FindDriveNumber
       
   421 // 
       
   422 // Find the first read write drive.
       
   423 //
       
   424 
       
   425 TInt FindDriveNumber(RFs fs)
       
   426 	{
       
   427 	TDriveInfo driveInfo;
       
   428 	for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum)
       
   429 		{
       
   430 		TInt r = fs.Drive(driveInfo, drvNum);
       
   431 		if (r >= 0)
       
   432 			{
       
   433 			if (driveInfo.iType == EMediaHardDisk)
       
   434 				return (drvNum);
       
   435 			}
       
   436 		}
       
   437 	return -1;
       
   438 	}
       
   439 
       
   440 //
       
   441 // FindFsNANDDrive
       
   442 //
       
   443 // Find the NAND drive
       
   444 //
       
   445 
       
   446 static TInt FindFsNANDDrive(RFs& aFs)
       
   447 	{
       
   448 	TDriveList driveList;
       
   449 	TDriveInfo driveInfo;
       
   450 	TInt r=aFs.DriveList(driveList);
       
   451     if (r == KErrNone)
       
   452 		{
       
   453 		for (TInt drvNum= (DriveNumber<0)?0:DriveNumber; drvNum<KMaxDrives; ++drvNum)
       
   454 			{
       
   455 			if(!driveList[drvNum])
       
   456 				continue;   //-- skip unexisting drive
       
   457 
       
   458 			if (aFs.Drive(driveInfo, drvNum) == KErrNone)
       
   459 				{
       
   460 				if(driveInfo.iMediaAtt&KMediaAttPageable)
       
   461 					{
       
   462 					TBool readOnly = driveInfo.iMediaAtt & KMediaAttWriteProtected;		// skip ROFS partitions
       
   463 					if(!readOnly)
       
   464 						{
       
   465 						if ((drvNum==DriveNumber) || (DriveNumber<0))		// only test if running on this drive
       
   466 							{
       
   467 							return (drvNum);
       
   468 							}
       
   469 						}
       
   470 					}
       
   471 				}
       
   472 			}
       
   473 		}
       
   474 	return -1;
       
   475 	}
       
   476 
       
   477 //
       
   478 // FindMMCDriveNumber
       
   479 // 
       
   480 // Find the first read write drive.
       
   481 //
       
   482 
       
   483 TInt FindMMCDriveNumber(RFs& aFs)
       
   484 	{
       
   485 	TDriveInfo driveInfo;
       
   486 	for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum)
       
   487 		{
       
   488 		TInt r = aFs.Drive(driveInfo, drvNum);
       
   489 		if (r >= 0)
       
   490 			{
       
   491 			if (driveInfo.iType == EMediaHardDisk)
       
   492 				return (drvNum);
       
   493 			}
       
   494 		}
       
   495 	return -1; 
       
   496 	}
       
   497 
       
   498 //
       
   499 // PerformRomAndFileSystemAccess
       
   500 // 
       
   501 // Access the rom and dump it out to one of the writeable partitions...
       
   502 // really just to make the media server a little busy during the test.
       
   503 //
       
   504 
       
   505 TInt PerformRomAndFileSystemAccessThread(RMsgQueue<TBuf <64> > *aMsgQueue = NULL, 
       
   506 										 TBuf<64>			   *aBuffer = NULL,
       
   507 										 RSemaphore			   *aTheSem = NULL)
       
   508 	{
       
   509 	TUint maxBytes = KMaxTUint;
       
   510 	TInt startTime = User::TickCount();
       
   511 
       
   512 	RFs fs;
       
   513 	RFile file;
       
   514 	if (KErrNone != fs.Connect())
       
   515 		{
       
   516 		DEBUG_PRINT(_L("PerformRomAndFileSystemAccessThread : Can't connect to the FS\n"));
       
   517 		return KErrGeneral;
       
   518 		}
       
   519 
       
   520 	// get info about the ROM...
       
   521 	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
       
   522 	TUint8* start;
       
   523 	TUint8* end;
       
   524 	if(romHeader->iPageableRomStart)
       
   525 		{
       
   526 		start = (TUint8*)romHeader + romHeader->iPageableRomStart;
       
   527 		end = start + romHeader->iPageableRomSize;
       
   528 		}
       
   529 	else
       
   530 		{
       
   531 		start = (TUint8*)romHeader;
       
   532 		end = start + romHeader->iUncompressedSize;
       
   533 		}
       
   534 	if (end <= start)
       
   535 		return KErrGeneral;
       
   536 
       
   537 	// read all ROM pages in a random order...and write out to file in ROFs, 
       
   538 	TUint size = end - start - TestPageSize;
       
   539 	if(size > maxBytes)
       
   540 		size = maxBytes;
       
   541 
       
   542 	TUint32 random=1;
       
   543 	TPtrC8 rom;
       
   544 	TUint8 *theAddr;
       
   545 
       
   546 	TInt		drvNum = TestBootedFromMmc ? FindMMCDriveNumber(fs) : FindFsNANDDrive(fs);
       
   547 	TBuf<32>	filename = _L("d:\\Pageldrtst.tmp");
       
   548 	if (drvNum >= 0)
       
   549 		{
       
   550 		filename[0] = 'a' + drvNum;
       
   551 		DEBUG_PRINT((_L("%S : Filename %S\n"), &TestNameBuffer, &filename));
       
   552 		}
       
   553 	else
       
   554 		DEBUG_PRINT((_L("PerformRomAndFileSystemAccessThread : error getting drive num\n")));
       
   555 
       
   556 	for(TInt i=size/(TestPageSize); i>0; --i)
       
   557 		{
       
   558 		DEBUG_PRINT1((_L("%S : Opening the file\n"), &TestNameBuffer));
       
   559 		if (KErrNone != file.Replace(fs, filename, EFileWrite))
       
   560 			{
       
   561 			DEBUG_PRINT((_L("%S : Opening the file Failed!\n"), &TestNameBuffer));
       
   562 			}
       
   563 
       
   564 		random = random*69069+1;
       
   565 		theAddr = (TUint8*)(start+((TInt64(random)*TInt64(size))>>32));
       
   566 		if (theAddr + TestPageSize > end)
       
   567 			{
       
   568 			DEBUG_PRINT((_L("%S : address is past the end 0x%x / 0x%x\n"), &TestNameBuffer, (TInt)theAddr, (TInt)end));
       
   569 			}
       
   570 		rom.Set(theAddr,TestPageSize);
       
   571 		DEBUG_PRINT1((_L("%S : Writing the file\n"), &TestNameBuffer));
       
   572 		TInt ret = file.Write(rom);
       
   573 		if (ret != KErrNone)
       
   574 			{
       
   575 			DEBUG_PRINT1((_L("%S : Write returned error %d\n"), &TestNameBuffer, ret));
       
   576 			}
       
   577 		DEBUG_PRINT1((_L("%S : Closing the file\n"), &TestNameBuffer));
       
   578 		file.Close();
       
   579 
       
   580 		DEBUG_PRINT1((_L("%S : Deleting the file\n"), &TestNameBuffer));
       
   581 		ret = fs.Delete(filename);
       
   582 		if (KErrNone != ret)
       
   583 			{
       
   584 			DEBUG_PRINT((_L("%S : Delete returned error %d\n"), &TestNameBuffer, ret));
       
   585 			}
       
   586 		if (TestStopMedia)
       
   587 			break;
       
   588 		}
       
   589 	fs.Close();
       
   590 	DEBUG_PRINT1((_L("Done in %d ticks\n"), User::TickCount() - startTime));
       
   591 	return KErrNone;
       
   592 	}
       
   593 
       
   594 
       
   595 //
       
   596 // PerformRomAndFileSystemAccess
       
   597 //
       
   598 // Thread function, kicks off the file system access.
       
   599 //
       
   600 
       
   601 LOCAL_C TInt PerformRomAndFileSystemAccess(TAny* )
       
   602 	{
       
   603 	TBuf<64>					localBuffer;
       
   604 
       
   605 	PerformRomAndFileSystemAccessThread(&TestMsgQueue, &localBuffer, &TestMultiSem);
       
   606 	
       
   607 	return KErrNone;
       
   608 	}
       
   609 
       
   610 //
       
   611 // DoMultipleTest
       
   612 // 
       
   613 // Perform the multiple thread test, spawning a number of threads.
       
   614 // It is complicated a little because test.Printf can only be called from the first thread that calls it 
       
   615 // so if we are using multiple threads we need to use a message queue to pass the debug info from the
       
   616 // child threads back to the parent for the parent to then call printf.
       
   617 //
       
   618 #define DOTEST(__operation, __condition)\
       
   619 	if (aLowMem) \
       
   620 		{\
       
   621 		__operation;\
       
   622 		while (!__condition)\
       
   623 			{\
       
   624 			Ldd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE);\
       
   625 			__operation;\
       
   626 			}\
       
   627 		RUNTEST1(__condition);\
       
   628 		}\
       
   629 	else\
       
   630 		{\
       
   631 		__operation;\
       
   632 		RUNTEST1(__condition);\
       
   633 		}
       
   634 
       
   635 void DoMultipleTest(TBool aLowMem = EFalse)
       
   636 	{
       
   637 	TInt			 index;
       
   638 
       
   639 	RThread			*pTheThreads  = (RThread *)User::AllocZ(sizeof(RThread) * TestMultipleThreadCount);
       
   640 	TInt			*pThreadInUse = (TInt *)User::AllocZ(sizeof(TInt) * TestMultipleThreadCount);
       
   641 
       
   642 	TRequestStatus	mediaStatus;
       
   643 	RThread			mediaThread;
       
   644 	
       
   645 	TInt ret;
       
   646 	DOTEST((ret = TestMsgQueue.CreateLocal(TestMultipleThreadCount * 10, EOwnerProcess)),
       
   647 	       (KErrNone == ret));
       
   648 
       
   649 	DOTEST((ret = TestMultiSem.CreateLocal(1)),
       
   650 	       (KErrNone == ret));
       
   651 
       
   652 	// make sure we have a priority higher than that of the threads we spawn...
       
   653 	RThread thisThread;
       
   654 	TThreadPriority savedThreadPriority = thisThread.Priority();
       
   655 	const TThreadPriority KMainThreadPriority = EPriorityMuchMore;
       
   656 	__ASSERT_COMPILE(KMainThreadPriority>TEST_INTERLEAVE_PRIO);
       
   657 	thisThread.SetPriority(KMainThreadPriority);
       
   658 
       
   659 	if (TestMediaAccess)
       
   660 		{
       
   661 		TestStopMedia = EFalse;
       
   662 		mediaThread.Create(_L(""),PerformRomAndFileSystemAccess,KDefaultStackSize,NULL,NULL);
       
   663 		mediaThread.Logon(mediaStatus);
       
   664 		RUNTEST1(mediaStatus == KRequestPending);
       
   665 		mediaThread.Resume();
       
   666 		}
       
   667 
       
   668 	// spawn some processes to call the functions....
       
   669 	for (index = 0; index < TestMultipleThreadCount; index++)
       
   670 		{
       
   671 		DBGD_PRINT((_L("%S : Starting thread.%d!\n"), &TestNameBuffer, index));
       
   672 		DOTEST((ret = pTheThreads[index].Create(_L(""),MultipleTestThread,KDefaultStackSize,NULL,(TAny*) index)),
       
   673 		       (ret == KErrNone));
       
   674 		pTheThreads[index].Resume();
       
   675 		pThreadInUse[index] = 1;
       
   676 		}
       
   677 	
       
   678 	// now process any messages sent from the child threads.
       
   679 	TBool		anyUsed = ETrue;
       
   680 	TBuf<64>	localBuffer;
       
   681 
       
   682 	while(anyUsed)
       
   683 		{
       
   684 		anyUsed = EFalse;
       
   685 		// check the message queue and call printf if we get a message.
       
   686 		while (KErrNone == TestMsgQueue.Receive(localBuffer))
       
   687 			{
       
   688 			DBGS_PRINT((localBuffer));
       
   689 			}
       
   690 
       
   691 		// walk through the thread list to check which are still alive.
       
   692 		for (index = 0; index < TestMultipleThreadCount; index++)
       
   693 			{
       
   694 			if (pThreadInUse[index])
       
   695 				{
       
   696 				if (pTheThreads[index].ExitType() != EExitPending)
       
   697 					{
       
   698 					if (pTheThreads[index].ExitType() == EExitPanic)
       
   699 						{
       
   700 						DBGS_PRINT((_L("%S : Thread Panic'd  %d...\n"), &TestNameBuffer, index));	
       
   701 						}
       
   702 					pThreadInUse[index] = EFalse;
       
   703 					pTheThreads[index].Close();
       
   704 					}
       
   705 				else
       
   706 					{
       
   707 					anyUsed = ETrue;
       
   708 					}
       
   709 				}
       
   710 			}
       
   711 		User::AfterHighRes(50000);
       
   712 		}
       
   713 
       
   714 	if (TestMediaAccess)
       
   715 		{
       
   716 		TestStopMedia = ETrue;
       
   717 		DBGD_PRINT((_L("%S : Waiting for media thread to exit...\n"), &TestNameBuffer));	
       
   718 		User::WaitForRequest(mediaStatus);
       
   719 		mediaThread.Close();
       
   720 		}
       
   721 
       
   722 	TestMsgQueue.Close();
       
   723 	TestMultiSem.Close();
       
   724 
       
   725 	// cleanup the resources and exit.
       
   726 	User::Free(pTheThreads);
       
   727 	User::Free(pThreadInUse);
       
   728 
       
   729 	thisThread.SetPriority(savedThreadPriority);
       
   730 	}
       
   731 
       
   732 
       
   733 //
       
   734 // ParseCommandLine 
       
   735 //
       
   736 // read the arguments passed from the command line and set global variables to 
       
   737 // control the tests.
       
   738 //
       
   739 
       
   740 TBool ParseCommandLine()
       
   741 	{
       
   742 	TBuf<256> args;
       
   743 	User::CommandLine(args);
       
   744 	TLex	lex(args);
       
   745 	TBool	retVal = ETrue;
       
   746 	
       
   747 	// initially test for arguments, the parse them, if not apply some sensible defaults.
       
   748 	TBool	foundArgs = EFalse;	
       
   749 	
       
   750 	FOREVER
       
   751 		{
       
   752 		TPtrC  token=lex.NextToken();
       
   753 		if(token.Length()!=0)
       
   754 			{
       
   755 			if ((token == _L("help")) || (token == _L("-h")) || (token == _L("-?")))
       
   756 				{
       
   757 				DBGS_PRINT((_L("\nUsage:  %S [debug] [check] [single | multiple <numThreads>]  [forward | backward | random | all] [iters <iters>] [media] [lowmem] [interleave]\n'-' indicated infinity.\n\n"), &TestNameBuffer));
       
   758 				test.Getch();
       
   759 				}
       
   760 			else if (token == _L("debug"))
       
   761 				{
       
   762 				if (!TestSilent)
       
   763 					{
       
   764 					TestDebug = ETrue;
       
   765 					TestPrioChange = ETrue;
       
   766 					}
       
   767 				}
       
   768 			else if (token == _L("silent"))
       
   769 				{
       
   770 				TestSilent = ETrue;
       
   771 				TestDebug = EFalse;
       
   772 				}
       
   773 			else if (token == _L("check"))
       
   774 				{
       
   775 				TestCheck = ETrue;
       
   776 				}
       
   777 			else if (token == _L("single"))
       
   778 				{
       
   779 				TestSingle = ETrue;
       
   780 				}
       
   781 			else if (token == _L("multiple"))
       
   782 				{
       
   783 				TPtrC val=lex.NextToken();
       
   784 				TLex lexv(val);
       
   785 				TInt value;
       
   786 
       
   787 				if (lexv.Val(value)==KErrNone)
       
   788 					{
       
   789 					if ((value <= 0) || (value > 100))
       
   790 						{
       
   791 						TestMultipleThreadCount = 10;
       
   792 						}
       
   793 					else
       
   794 						{
       
   795 						TestMultipleThreadCount = value;
       
   796 						}
       
   797 					}
       
   798 				else
       
   799 					{
       
   800 					DBGS_PRINT((_L("Bad value for thread count '%S' was ignored.\n"), &val));
       
   801 					retVal = EFalse;
       
   802 					break;
       
   803 					}
       
   804 				TestMultiple = ETrue;
       
   805 				}
       
   806 			else if (token == _L("prio"))
       
   807 				{
       
   808 				TestPrioChange = !TestPrioChange;
       
   809 				}
       
   810 			else if (token == _L("lowmem"))
       
   811 				{
       
   812 				TestLowMem = ETrue;
       
   813 				}
       
   814 			else if (token == _L("media"))
       
   815 				{
       
   816 				TestMediaAccess = ETrue;
       
   817 				}
       
   818 			else if (token == _L("forward"))
       
   819 				{
       
   820 				TestWhichTests = TEST_FORWARD;
       
   821 				}
       
   822 			else if (token == _L("backward"))
       
   823 				{
       
   824 				TestWhichTests = TEST_BACKWARD;
       
   825 				}
       
   826 			else if (token == _L("random"))
       
   827 				{
       
   828 				TestWhichTests = TEST_RANDOM;
       
   829 				}
       
   830 			else if (token == _L("all"))
       
   831 				{
       
   832 				TestWhichTests = TEST_ALL;
       
   833 				}
       
   834 			else  if (token == _L("iters"))
       
   835 				{
       
   836 				TPtrC val=lex.NextToken();
       
   837 				TLex lexv(val);
       
   838 				TInt value;
       
   839 
       
   840 				if (val==_L("-"))
       
   841 					{
       
   842 					TestForever = ETrue;
       
   843 					TestMaxLoops = KMaxTInt;
       
   844 					}
       
   845 				else
       
   846 					{
       
   847 					if (lexv.Val(value)==KErrNone)
       
   848 						{
       
   849 						TestMaxLoops = value;
       
   850 						}
       
   851 					else
       
   852 						{
       
   853 						DBGS_PRINT((_L("Bad value for thread count '%S' was ignored.\n"), &val));
       
   854 						retVal = EFalse;
       
   855 						break;
       
   856 						}
       
   857 					}
       
   858 				}
       
   859 			else  if (token == _L("interleave"))
       
   860 				{
       
   861 				TestInterleave = ETrue;
       
   862 				}
       
   863 			else  if (token == _L("inst"))
       
   864 				{
       
   865 				TPtrC val=lex.NextToken();
       
   866 				TLex lexv(val);
       
   867 				TInt value;
       
   868 
       
   869 				if (lexv.Val(value)==KErrNone)
       
   870 					{
       
   871 					TestInstanceId = value;
       
   872 					}
       
   873 				}
       
   874 			else
       
   875 				{
       
   876 				if ((foundArgs == EFalse) && (token.Length() == 1))
       
   877 					{
       
   878 					// Single letter argument...only run on MMC drive
       
   879 					if (token.CompareF(_L("d")) == 0)
       
   880 						{
       
   881 						break;
       
   882 						}
       
   883 					else
       
   884 						{
       
   885 						if (!TestSilent)
       
   886 							{
       
   887 							test.Title();
       
   888 							test.Start(_L("Skipping non drive 'd' - Test Exiting."));
       
   889 							test.End();
       
   890 							}
       
   891 						foundArgs = ETrue;
       
   892 						TestExit = ETrue;
       
   893 						break;
       
   894 						}
       
   895 					}
       
   896 				DBGS_PRINT((_L("Unknown argument '%S' was ignored.\n"), &token));
       
   897 				break;
       
   898 				}
       
   899 			foundArgs = ETrue;
       
   900 			}
       
   901 		else
       
   902 			{
       
   903 			break;
       
   904 			}
       
   905 		}
       
   906 	if (!foundArgs)
       
   907 		{
       
   908 		retVal = EFalse;
       
   909 		}
       
   910 	return retVal;
       
   911 	}
       
   912 
       
   913 //
       
   914 // AreWeTheTestBase
       
   915 //
       
   916 // Test whether we are the root of the tests.
       
   917 //
       
   918 
       
   919 void AreWeTheTestBase(void)
       
   920 	{
       
   921 	if (!TestSilent)
       
   922 		{
       
   923 		TFileName  filename(RProcess().FileName());
       
   924 
       
   925 		TParse	myParse;
       
   926 		myParse.Set(filename, NULL, NULL);
       
   927 		TestNameBuffer.Zero();
       
   928 		TestNameBuffer.Append(myParse.Name());
       
   929 		TestNameBuffer.Append(_L(".exe"));
       
   930 
       
   931 		TestWeAreTheTestBase = !TestNameBuffer.Compare(_L("t_pagestress.exe"));
       
   932 
       
   933 		RFs fs;
       
   934 		if (KErrNone != fs.Connect())
       
   935 			{
       
   936 			TEntry  anEntry;
       
   937 			TInt retVal = fs.Entry(_L("z:\\test\\mmcdemandpaginge32tests.bat"), anEntry);
       
   938 			if (retVal == KErrNone)
       
   939 				{
       
   940 				TestBootedFromMmc = ETrue;
       
   941 				}
       
   942 			else
       
   943 				{
       
   944 				TestBootedFromMmc = EFalse;
       
   945 				}
       
   946 			fs.Close();
       
   947 			}
       
   948 
       
   949 		}
       
   950 	else
       
   951 		{
       
   952 		TestNameBuffer.Zero();
       
   953 		TestNameBuffer.Append(_L("t_pagestress.exe"));
       
   954 		}
       
   955 	}
       
   956 
       
   957 //
       
   958 // PerformAutoTest
       
   959 //
       
   960 // Perform the autotest
       
   961 //
       
   962 void PerformAutoTest()
       
   963 	{
       
   964 	SVMCacheInfo  tempPages;
       
   965 
       
   966 	if (TestIsDemandPaged)
       
   967 		{
       
   968 		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
       
   969 		DBGS_PRINT((_L("PerformAutoTest : Start cache info: iMinSize %d iMaxSize %d iCurrentSize %d iMaxFreeSize %d\n"),
       
   970 					 tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize ,tempPages.iMaxFreeSize));
       
   971 		}
       
   972 	TestInterleave = EFalse;
       
   973 	TestPrioChange = EFalse;
       
   974 	TestMediaAccess = EFalse;
       
   975 
       
   976 #if defined __ARMCC__ || defined __X86__
       
   977 	// Currently we only build aligned DLLs on ARMV5 and X86 builds.
       
   978 	TEST_NEXT((_L("Alignment Check.")));
       
   979 	RUNTEST1(CheckAlignments() == KErrNone);
       
   980 #endif
       
   981 
       
   982 	TestMaxLoops = 2;
       
   983 	TestWhichTests = TEST_RANDOM;
       
   984 
       
   985 	TEST_NEXT((_L("Single thread all.")));
       
   986 	DoSingleTest();
       
   987 
       
   988 	TEST_NEXT((_L("Multiple threads all.")));
       
   989 	DoMultipleTest();
       
   990 	
       
   991 	TestPrioChange = ETrue;
       
   992 	TEST_NEXT((_L("Multiple threads all with prio.")));
       
   993 	DoMultipleTest();
       
   994 
       
   995 	TestPrioChange = EFalse;
       
   996 	TestMediaAccess = ETrue;
       
   997 	TEST_NEXT((_L("Multiple threads all with media activity.")));
       
   998 	DoMultipleTest();
       
   999 
       
  1000 	TestPrioChange = ETrue;
       
  1001 	TestMediaAccess = ETrue;
       
  1002 	TEST_NEXT((_L("Multiple threads all with media activity and prio.")));
       
  1003 	DoMultipleTest();
       
  1004 
       
  1005 	TestInterleave = ETrue;
       
  1006 	TestPrioChange = EFalse;
       
  1007 	TestMediaAccess = EFalse;
       
  1008 	
       
  1009 	TEST_NEXT((_L("Multiple threads random with interleave.")));
       
  1010 	DoMultipleTest();
       
  1011 
       
  1012 	TestPrioChange = ETrue;
       
  1013 	TEST_NEXT((_L("Multiple threads random with interleave and prio.")));
       
  1014 	DoMultipleTest();
       
  1015 
       
  1016 	TestMediaAccess = ETrue;
       
  1017 	TEST_NEXT((_L("Multiple threads random with media interleave and prio.")));
       
  1018 	DoMultipleTest();
       
  1019 
       
  1020 	if (TestIsDemandPaged)
       
  1021 		{
       
  1022 		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
       
  1023 		DBGS_PRINT((_L("PerformAutoTest : End cache info: iMinSize %d iMaxSize %d iCurrentSize %d iMaxFreeSize %d\n"),
       
  1024 					 tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize ,tempPages.iMaxFreeSize));
       
  1025 		}
       
  1026 	TestInterleave = EFalse;
       
  1027 	TestPrioChange = EFalse;
       
  1028 	TestMediaAccess = EFalse;
       
  1029 	}
       
  1030 
       
  1031 //
       
  1032 // DoLowMemTest
       
  1033 //
       
  1034 // Low Memory Test
       
  1035 //
       
  1036 
       
  1037 void DoLowMemTest()
       
  1038 	{
       
  1039 	TInt r = User::LoadLogicalDevice(KPageStressTestLddName);
       
  1040 	RUNTEST1(r==KErrNone || r==KErrAlreadyExists);
       
  1041 	RUNTEST(Ldd.Open(),KErrNone);
       
  1042 	
       
  1043 	SVMCacheInfo  tempPages;
       
  1044 	memset(&tempPages, 0, sizeof(tempPages));
       
  1045 
       
  1046 	if (TestIsDemandPaged)
       
  1047 		{
       
  1048 		// get the old cache info
       
  1049 		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
       
  1050 		TInt	minSize = 8 * 4096;
       
  1051 		TInt	maxSize = 256 * 4096;
       
  1052 		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
       
  1053 		}
       
  1054 
       
  1055 	// First load some pages onto the page cache 
       
  1056 	TestMaxLoops = 1;
       
  1057 	TestWhichTests = TEST_RANDOM;
       
  1058 	DoSingleTest();
       
  1059 
       
  1060 	Ldd.DoConsumeRamSetup(TEST_LM_NUM_FREE, TEST_LM_BLOCKSIZE);
       
  1061 	TEST_NEXT((_L("Single thread with Low memory.")));
       
  1062 	TestMultipleThreadCount	= 25;
       
  1063 	TestInterleave = EFalse;
       
  1064 	TestMaxLoops = 20;
       
  1065 	TestPrioChange = EFalse;
       
  1066 	TestMediaAccess = EFalse;
       
  1067 	TestWhichTests = TEST_ALL;
       
  1068 	
       
  1069 	DoSingleTest();
       
  1070 	
       
  1071 	Ldd.DoConsumeRamFinish();
       
  1072 
       
  1073 	TEST_NEXT((_L("Multiple thread with Low memory.")));
       
  1074 	// First load some pages onto the page cache 
       
  1075 	TestMaxLoops = 1;
       
  1076 	TestWhichTests = TEST_RANDOM;
       
  1077 	DoSingleTest();
       
  1078 
       
  1079 	Ldd.DoConsumeRamSetup(TEST_LM_NUM_FREE, TEST_LM_BLOCKSIZE);
       
  1080 	
       
  1081 	TestWhichTests = TEST_ALL;
       
  1082 	TestMaxLoops = 10;
       
  1083 	TestMultipleThreadCount	= 25;
       
  1084 	DoMultipleTest(ETrue);
       
  1085 
       
  1086 	Ldd.DoConsumeRamFinish();
       
  1087 
       
  1088 	TEST_NEXT((_L("Multiple thread with Low memory, with starting free ram.")));
       
  1089 	// First load some pages onto the page cache 
       
  1090 	TestMaxLoops = 1;
       
  1091 	TestWhichTests = TEST_RANDOM;
       
  1092 	DoSingleTest();
       
  1093 
       
  1094 	Ldd.DoConsumeRamSetup(32, TEST_LM_BLOCKSIZE);
       
  1095 	
       
  1096 	TestWhichTests = TEST_ALL;
       
  1097 	TestMaxLoops = 10;
       
  1098 	TestMultipleThreadCount	= 25;
       
  1099 	DoMultipleTest(ETrue);
       
  1100 
       
  1101 	Ldd.DoConsumeRamFinish();
       
  1102 	
       
  1103 	TEST_NEXT((_L("Close test driver")));
       
  1104 	Ldd.Close();
       
  1105 	RUNTEST(User::FreeLogicalDevice(KPageStressTestLddName), KErrNone);
       
  1106 	if (TestIsDemandPaged)
       
  1107 		{
       
  1108 		TInt minSize = tempPages.iMinSize;
       
  1109 		TInt maxSize = tempPages.iMaxSize;
       
  1110 		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
       
  1111 		}
       
  1112 	}
       
  1113 
       
  1114 //
       
  1115 // E32Main
       
  1116 //
       
  1117 // Main entry point.
       
  1118 //
       
  1119 
       
  1120 TInt E32Main()
       
  1121 	{
       
  1122 #ifndef TEST_ON_UNPAGED
       
  1123 	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
       
  1124 	if(!romHeader->iPageableRomStart)
       
  1125 		{
       
  1126 		TestIsDemandPaged = EFalse;
       
  1127 		}
       
  1128 #endif
       
  1129 	TUint start = User::TickCount();
       
  1130 
       
  1131 	TBool parseResult = ParseCommandLine();
       
  1132 
       
  1133 	if (TestExit)
       
  1134 		{
       
  1135 		return KErrNone;
       
  1136 		}
       
  1137 
       
  1138 	AreWeTheTestBase();
       
  1139 
       
  1140 	TInt  minSize = 8 * 4096;
       
  1141 	TInt  maxSize = 64 * 4096;
       
  1142 	SVMCacheInfo  tempPages;
       
  1143 	memset(&tempPages, 0, sizeof(tempPages));
       
  1144 	if (TestIsDemandPaged)
       
  1145 		{
       
  1146 		// get the old cache info
       
  1147 		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
       
  1148 		// set the cache to our test value
       
  1149 		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
       
  1150 		}
       
  1151 
       
  1152 	// get the page size.
       
  1153 	UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&TestPageSize,0);
       
  1154 
       
  1155 	if (!TestSilent)
       
  1156 		{
       
  1157 		test.Title();
       
  1158 		test.Start(_L("Demand Paging stress tests..."));
       
  1159 		test.Printf(_L("%S\n"), &TestNameBuffer);
       
  1160 		}
       
  1161 
       
  1162 	if (parseResult)
       
  1163 		{
       
  1164 		if (!TestSilent)
       
  1165 			{
       
  1166 			extern TInt *CheckLdmiaInstr(void);
       
  1167 			test.Printf(_L("%S : CheckLdmiaInstr\n"), &TestNameBuffer);
       
  1168 			TInt   *theAddr = CheckLdmiaInstr();
       
  1169 			test.Printf(_L("%S : CheckLdmiaInstr complete 0x%x...\n"), &TestNameBuffer, (TInt)theAddr);
       
  1170 			}
       
  1171 		if (TestCheck)
       
  1172 			{
       
  1173 			CheckAlignments();
       
  1174 			}
       
  1175 		if (TestLowMem)
       
  1176 			{
       
  1177 			DoLowMemTest();
       
  1178 			}
       
  1179 		if (TestSingle)
       
  1180 			{
       
  1181 			DoSingleTest();
       
  1182 			}
       
  1183 		if (TestMultiple)
       
  1184 			{
       
  1185 			DoMultipleTest();
       
  1186 			}
       
  1187 		}
       
  1188 	else
       
  1189 		{
       
  1190 		PerformAutoTest();
       
  1191 
       
  1192 		DoLowMemTest();
       
  1193 
       
  1194 		if (TestWeAreTheTestBase)
       
  1195 			{
       
  1196 			RProcess		theProcess;
       
  1197 			TRequestStatus	status;
       
  1198 
       
  1199 			TInt retVal = theProcess.Create(_L("t_pagestress_rom.exe"),_L(""));
       
  1200 			if (retVal != KErrNotFound)
       
  1201 				{
       
  1202 				RUNTEST1(retVal == KErrNone);
       
  1203 				theProcess.Logon(status);
       
  1204 				RUNTEST1(status == KRequestPending);
       
  1205 				theProcess.Resume();
       
  1206 				User::WaitForRequest(status);
       
  1207 				if (theProcess.ExitType() != EExitPending)
       
  1208 					{
       
  1209 					RUNTEST1(theProcess.ExitType() != EExitPanic);
       
  1210 					}
       
  1211 				}
       
  1212 			}
       
  1213 		}
       
  1214 
       
  1215 	if (TestIsDemandPaged)
       
  1216 		{
       
  1217 		minSize = tempPages.iMinSize;
       
  1218 		maxSize = tempPages.iMaxSize;
       
  1219 		// put the cache back to the the original values.
       
  1220 		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
       
  1221 		}
       
  1222 
       
  1223 	if (!TestSilent)
       
  1224 		{
       
  1225 		test.Printf(_L("%S : Complete (%u ticks)\n"), &TestNameBuffer, User::TickCount() - start);	
       
  1226 		test.End();
       
  1227 		}
       
  1228 	return 0;
       
  1229 	}
       
  1230 
       
  1231