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