os/kernelhwsrv/kerneltest/f32test/demandpaging/t_wdpstress.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) 2008-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_wdpstress.cpp
sl@0
    15
// Data Paging Stress Tests
sl@0
    16
// Common command lines:
sl@0
    17
// t_wdpstress lowmem
sl@0
    18
// debug - switch on debugging information
sl@0
    19
// silent - no output to the screen or serial port
sl@0
    20
// single - run the tests in a single thread
sl@0
    21
// multiple <numThreads> - run the tests in multiple threads where <numThreads> (max 50 simultaneous threads)
sl@0
    22
// interleave - force thread interleaving
sl@0
    23
// prio - each thread reschedules in between each function call, causes lots of context changes
sl@0
    24
// media - perform media access during the tests, very stressful
sl@0
    25
// lowmem - low memory tests
sl@0
    26
// stack - perform autotest only with stack paging tests
sl@0
    27
// chunk - perform autotest only with chunk paging tests 			
sl@0
    28
// commit - perform autotest only with committing and decommitting paging tests 
sl@0
    29
// ipc - perform autotest only with ipc pinning tests 			
sl@0
    30
// all - perform autotest with all paging tests(ipc, stack, chunk and commit)
sl@0
    31
// badserver - perform ipc pinning tests with dead server
sl@0
    32
// iters <count> - the number of times to loop 
sl@0
    33
// 
sl@0
    34
//
sl@0
    35
sl@0
    36
//! @SYMTestCaseID			KBASE-T_WDPSTRESS-xxx
sl@0
    37
//! @SYMTestType			UT
sl@0
    38
//! @SYMPREQ				PREQ1954
sl@0
    39
//! @SYMTestCaseDesc		Writable Data Paging Stress Tests
sl@0
    40
//! @SYMTestActions			
sl@0
    41
//! @SYMTestExpectedResults All tests should pass.
sl@0
    42
//! @SYMTestPriority        High
sl@0
    43
//! @SYMTestStatus          Implemented
sl@0
    44
//----------------------------------------------------------------------------------------------
sl@0
    45
//
sl@0
    46
#define __E32TEST_EXTENSION__
sl@0
    47
#include <e32test.h>
sl@0
    48
#include <e32ver.h>
sl@0
    49
RTest test(_L("T_WDPSTRESS"));
sl@0
    50
sl@0
    51
#include <e32rom.h>
sl@0
    52
#include <u32hal.h>
sl@0
    53
#include <f32file.h>
sl@0
    54
#include <e32svr.h>
sl@0
    55
#include <e32hal.h>
sl@0
    56
#include <f32dbg.h>
sl@0
    57
#include <e32msgqueue.h>
sl@0
    58
#include <e32math.h>
sl@0
    59
#include <dptest.h>
sl@0
    60
#include <hal.h>
sl@0
    61
#include "testdefs.h"
sl@0
    62
sl@0
    63
#ifdef __X86__
sl@0
    64
#define TEST_ON_UNPAGED
sl@0
    65
#endif
sl@0
    66
sl@0
    67
#include "t_pagestress.h"
sl@0
    68
sl@0
    69
TBool   	TestDebug					= EFalse;
sl@0
    70
TBool		TestSilent					= EFalse;
sl@0
    71
TBool		TestExit					= EFalse;
sl@0
    72
sl@0
    73
sl@0
    74
TInt		gPerformTestLoop			= 10;					// Number of times to perform test on a thread
sl@0
    75
const TUint KMaxTestThreads				= 20;					// The maximum number of threads allowed to run simultaniously
sl@0
    76
TInt		gNumTestThreads				= KMaxTestThreads;		// The number of threads to run simultaneously
sl@0
    77
sl@0
    78
#define TEST_INTERLEAVE_PRIO			EPriorityMore
sl@0
    79
sl@0
    80
TBool		TestWeAreTheTestBase		= EFalse;
sl@0
    81
sl@0
    82
#define TEST_NONE		0x0
sl@0
    83
#define TEST_IPC		0x1
sl@0
    84
#define TEST_STACK		0x2
sl@0
    85
#define TEST_CHUNK		0x4
sl@0
    86
#define TEST_COMMIT		0x8
sl@0
    87
#define TEST_ALL		(TEST_COMMIT | TEST_CHUNK | TEST_STACK | TEST_IPC)
sl@0
    88
sl@0
    89
TUint32		gSetTests					= TEST_ALL;
sl@0
    90
TUint32		gTestWhichTests				= gSetTests;
sl@0
    91
TBuf<32>	gTestNameBuffer;
sl@0
    92
TBool		gTestPrioChange				= EFalse;				
sl@0
    93
TBool		gTestStopMedia				= EFalse;
sl@0
    94
TBool		gTestMediaAccess			= EFalse;
sl@0
    95
TBool		gTestInterleave				= EFalse;
sl@0
    96
TBool		gTestBadServer				= EFalse;
sl@0
    97
sl@0
    98
#define TEST_LM_NUM_FREE	0
sl@0
    99
#define TEST_LM_BLOCKSIZE	1
sl@0
   100
#define TEST_LM_BLOCKS_FREE	4
sl@0
   101
sl@0
   102
RPageStressTestLdd Ldd;
sl@0
   103
RSemaphore	TestMultiSem;
sl@0
   104
RMsgQueue<TBuf <64> >	TestMsgQueue;
sl@0
   105
sl@0
   106
TBool		gIsDemandPaged			= ETrue;
sl@0
   107
TBool		gTestRunning				= EFalse;				// To control when to stop flushing
sl@0
   108
TBool		gMaxChunksReached			= EFalse;				// On moving memory model, the number of chunks per process is capped
sl@0
   109
sl@0
   110
TInt		gPageSize;											// The number of bytes per page
sl@0
   111
TUint		gPageShift;
sl@0
   112
TUint		gChunksAllocd				= 0;					// The total number of chunks that have been allocated
sl@0
   113
TUint		gMaxChunks					= 0;					// The max amount of chunks after which KErrOverflow will be returned
sl@0
   114
RHeap*		gThreadHeap					= NULL;					
sl@0
   115
RHeap*		gStackHeap					= NULL;
sl@0
   116
sl@0
   117
TInt		gTestType					= -1;					// The type of test that is to be performed
sl@0
   118
sl@0
   119
#define TEST_NEXT(__args) \
sl@0
   120
	if (!TestSilent)\
sl@0
   121
		test.Next __args;
sl@0
   122
sl@0
   123
#define RDBGD_PRINT(__args)\
sl@0
   124
	if (TestDebug)\
sl@0
   125
	RDebug::Printf __args ;\
sl@0
   126
sl@0
   127
#define RDBGS_PRINT(__args)\
sl@0
   128
	if (!TestSilent)\
sl@0
   129
	RDebug::Printf __args ;\
sl@0
   130
sl@0
   131
#define DEBUG_PRINT(__args)\
sl@0
   132
if (!TestSilent)\
sl@0
   133
	{\
sl@0
   134
	if (aTestArguments.iMsgQueue && aTestArguments.iBuffer && aTestArguments.iTheSem)\
sl@0
   135
		{\
sl@0
   136
		aTestArguments.iBuffer->Zero();\
sl@0
   137
		aTestArguments.iBuffer->Format __args ;\
sl@0
   138
		aTestArguments.iTheSem->Wait();\
sl@0
   139
		aTestArguments.iMsgQueue->SendBlocking(*aTestArguments.iBuffer);\
sl@0
   140
		aTestArguments.iTheSem->Signal();\
sl@0
   141
		}\
sl@0
   142
	else\
sl@0
   143
		{\
sl@0
   144
		test.Printf __args ;\
sl@0
   145
		}\
sl@0
   146
	}
sl@0
   147
sl@0
   148
#define RUNTEST(__test, __error)\
sl@0
   149
	if (!TestSilent)\
sl@0
   150
		test(__test == __error);\
sl@0
   151
	else\
sl@0
   152
		__test;
sl@0
   153
sl@0
   154
#define RUNTEST1(__test)\
sl@0
   155
	if (!TestSilent)\
sl@0
   156
		test(__test);
sl@0
   157
sl@0
   158
#define DEBUG_PRINT1(__args)\
sl@0
   159
if (TestDebug)\
sl@0
   160
	{\
sl@0
   161
	DEBUG_PRINT(__args)\
sl@0
   162
	}
sl@0
   163
sl@0
   164
#define DOTEST(__operation, __condition)\
sl@0
   165
	if (aLowMem) \
sl@0
   166
		{\
sl@0
   167
		__operation;\
sl@0
   168
		while (!__condition)\
sl@0
   169
			{\
sl@0
   170
			Ldd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE);\
sl@0
   171
			__operation;\
sl@0
   172
			}\
sl@0
   173
		RUNTEST1(__condition);\
sl@0
   174
		}\
sl@0
   175
	else\
sl@0
   176
		{\
sl@0
   177
		__operation;\
sl@0
   178
		RUNTEST1(__condition);\
sl@0
   179
		}
sl@0
   180
sl@0
   181
#define DOTEST1(__operation, __condition)\
sl@0
   182
	if (aTestArguments.iLowMem) \
sl@0
   183
		{\
sl@0
   184
		__operation;\
sl@0
   185
		while (!__condition)\
sl@0
   186
			{\
sl@0
   187
			Ldd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE);\
sl@0
   188
			__operation;\
sl@0
   189
			}\
sl@0
   190
		RUNTEST1(__condition);\
sl@0
   191
		}\
sl@0
   192
	else\
sl@0
   193
		{\
sl@0
   194
		__operation;\
sl@0
   195
		RUNTEST1(__condition);\
sl@0
   196
		}
sl@0
   197
sl@0
   198
struct SThreadExitResults
sl@0
   199
	{
sl@0
   200
	TInt					iExitType;
sl@0
   201
	TInt					iExitReason;
sl@0
   202
	};
sl@0
   203
SThreadExitResults* gResultsArray;
sl@0
   204
const TInt KExitTypeReset = -1;
sl@0
   205
sl@0
   206
struct SPerformTestArgs
sl@0
   207
	{
sl@0
   208
	TInt					iThreadIndex;
sl@0
   209
	RMsgQueue<TBuf <64> >	*iMsgQueue; 
sl@0
   210
	TBuf<64>				*iBuffer;
sl@0
   211
	RSemaphore				*iTheSem;
sl@0
   212
	TBool					iLowMem;
sl@0
   213
	TInt					iTestType;
sl@0
   214
	};
sl@0
   215
sl@0
   216
sl@0
   217
TInt DoTest(TInt gTestType, TBool aLowMem = EFalse);
sl@0
   218
enum
sl@0
   219
	{
sl@0
   220
	ETestSingle, 
sl@0
   221
	ETestMultiple,
sl@0
   222
	ETestMedia,
sl@0
   223
	ETestLowMem,
sl@0
   224
	ETestInterleave,
sl@0
   225
	ETestCommit, 
sl@0
   226
	ETestTypes,
sl@0
   227
	// This is at the moment manual
sl@0
   228
	ETestBadServer, 
sl@0
   229
	ETestTypeEnd, 
sl@0
   230
	};
sl@0
   231
sl@0
   232
TInt FreeRam()
sl@0
   233
	{
sl@0
   234
	// wait for any async cleanup in the supervisor to finish first...
sl@0
   235
	UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
sl@0
   236
sl@0
   237
	TMemoryInfoV1Buf meminfo;
sl@0
   238
	TInt r = UserHal::MemoryInfo(meminfo);
sl@0
   239
	test_KErrNone(r);
sl@0
   240
	return meminfo().iFreeRamInBytes;
sl@0
   241
	}
sl@0
   242
sl@0
   243
const TUint KStackSize = 20 * 4096;
sl@0
   244
TUint stackLimit = 150;//*** NEED TO WORK OUT HOW MUCH STACK WE HAVE***
sl@0
   245
sl@0
   246
/**
sl@0
   247
Recursive function
sl@0
   248
*/
sl@0
   249
void CallRecFunc(TUint aNum, TInt aThreadIndex)
sl@0
   250
	{
sl@0
   251
	RDBGD_PRINT(("ThreadId %d CallRecFunc, aNum = %d\n", aThreadIndex, aNum));
sl@0
   252
	if (aNum >= stackLimit)
sl@0
   253
		{// To avoid a stack overflow
sl@0
   254
		return;
sl@0
   255
		}
sl@0
   256
	else
sl@0
   257
		{
sl@0
   258
		CallRecFunc(++aNum, aThreadIndex);
sl@0
   259
		User::After(0);
sl@0
   260
		}
sl@0
   261
	RDBGD_PRINT(("ThreadId %d CRF(%d)Returning...", aThreadIndex, aNum));
sl@0
   262
	return;
sl@0
   263
	}
sl@0
   264
sl@0
   265
/**
sl@0
   266
Thread that calls a recursive function
sl@0
   267
*/
sl@0
   268
TInt ThreadFunc(TAny* aThreadIndex)
sl@0
   269
	{
sl@0
   270
	for (TUint i=0; i<1; i++)
sl@0
   271
		{
sl@0
   272
		CallRecFunc(0, (TInt)aThreadIndex);
sl@0
   273
		}
sl@0
   274
	RDBGD_PRINT(("ThreadId %d ThreadFunc Returning...", (TInt)aThreadIndex));
sl@0
   275
	return KErrNone;
sl@0
   276
	}
sl@0
   277
sl@0
   278
/**
sl@0
   279
Thread continuously flushes the paging cache
sl@0
   280
*/
sl@0
   281
TInt FlushFunc(TAny* /*aPtr*/)
sl@0
   282
	{
sl@0
   283
	RThread().SetPriority(EPriorityMore);
sl@0
   284
	while(gTestRunning)
sl@0
   285
		{
sl@0
   286
		DPTest::FlushCache();	
sl@0
   287
		User::After((Math::Random()&0xfff)*10);
sl@0
   288
		}
sl@0
   289
	return KErrNone;
sl@0
   290
	}
sl@0
   291
sl@0
   292
sl@0
   293
//
sl@0
   294
// TestStackPaging
sl@0
   295
//
sl@0
   296
// Create a paged thread which calls a recursive function.
sl@0
   297
// Calls to function will be placed on the stack, which is data paged
sl@0
   298
//
sl@0
   299
sl@0
   300
TInt TestStackPaging(SPerformTestArgs& aTestArguments)
sl@0
   301
	{
sl@0
   302
	RDBGD_PRINT(("Creating test thread"));
sl@0
   303
	TBuf<16> runThreadName;
sl@0
   304
	runThreadName = _L("");
sl@0
   305
	TThreadCreateInfo threadCreateInfo(runThreadName, ThreadFunc, KStackSize, (TAny*) aTestArguments.iThreadIndex);
sl@0
   306
	threadCreateInfo.SetCreateHeap(KMinHeapSize, KMinHeapSize);
sl@0
   307
	//threadCreateInfo.SetUseHeap(NULL);
sl@0
   308
	threadCreateInfo.SetPaging(TThreadCreateInfo::EPaged);
sl@0
   309
sl@0
   310
	RThread testThread;
sl@0
   311
	TInt r;
sl@0
   312
	for(;;)
sl@0
   313
		{
sl@0
   314
		r = testThread.Create(threadCreateInfo);
sl@0
   315
		if(r != KErrNoMemory)
sl@0
   316
			break;
sl@0
   317
		if(!aTestArguments.iLowMem)
sl@0
   318
			break;
sl@0
   319
		if(Ldd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE) != KErrNone)
sl@0
   320
			break;
sl@0
   321
		RDBGD_PRINT(("TestStackPaging released some RAM\n"));
sl@0
   322
		}
sl@0
   323
sl@0
   324
	RDBGD_PRINT(("TID(%d) TestStackPaging create r = %d freeRam = %d\n", aTestArguments.iThreadIndex, r, FreeRam()));
sl@0
   325
	if (r != KErrNone)
sl@0
   326
		return r;
sl@0
   327
sl@0
   328
	TRequestStatus threadStatus;
sl@0
   329
	testThread.Logon(threadStatus);
sl@0
   330
	
sl@0
   331
	RDBGD_PRINT(("resuming test thread"));
sl@0
   332
	testThread.Resume();
sl@0
   333
	
sl@0
   334
	RDBGD_PRINT(("waiting for threadstatus"));
sl@0
   335
	User::WaitForRequest(threadStatus);
sl@0
   336
	
sl@0
   337
	RDBGD_PRINT(("Killing threads\n"));
sl@0
   338
	testThread.Close();
sl@0
   339
sl@0
   340
	return KErrNone;
sl@0
   341
	}
sl@0
   342
sl@0
   343
//--------------------------Server Pinning stuff-----------------------------------------------------
sl@0
   344
_LIT(KTestServer,"CTestServer");
sl@0
   345
const TUint KSemServer = 0;
sl@0
   346
sl@0
   347
class CTestServer : public CServer2
sl@0
   348
	{
sl@0
   349
public:
sl@0
   350
	CTestServer(TInt aPriority);
sl@0
   351
protected:
sl@0
   352
	//override the pure virtual functions:
sl@0
   353
	virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
sl@0
   354
	};
sl@0
   355
sl@0
   356
sl@0
   357
class CTestSession : public CSession2
sl@0
   358
	{
sl@0
   359
public:
sl@0
   360
	enum TTestMode
sl@0
   361
		{
sl@0
   362
		EStop,
sl@0
   363
		ERead,
sl@0
   364
		EWrite,
sl@0
   365
		EReadWrite,
sl@0
   366
		};
sl@0
   367
//Override pure virtual
sl@0
   368
	IMPORT_C virtual void ServiceL(const RMessage2& aMessage);
sl@0
   369
private:
sl@0
   370
	TInt ReadWrite(const RMessage2& aMessage, TBool aRead, TBool aWrite);
sl@0
   371
	TBool iClientDied;
sl@0
   372
	};
sl@0
   373
sl@0
   374
sl@0
   375
class CMyActiveScheduler : public CActiveScheduler
sl@0
   376
	{
sl@0
   377
public:
sl@0
   378
	virtual void Error(TInt anError) const; //override pure virtual error function
sl@0
   379
	};
sl@0
   380
sl@0
   381
sl@0
   382
class RSession : public RSessionBase
sl@0
   383
	{
sl@0
   384
public:
sl@0
   385
	TInt PublicSendReceive(TInt aFunction, const TIpcArgs &aPtr)
sl@0
   386
		{
sl@0
   387
		return (SendReceive(aFunction, aPtr));
sl@0
   388
		}
sl@0
   389
	TInt PublicCreateSession(const TDesC& aServer,TInt aMessageSlots)
sl@0
   390
		{
sl@0
   391
		return (CreateSession(aServer,User::Version(),aMessageSlots));
sl@0
   392
		}
sl@0
   393
	};
sl@0
   394
sl@0
   395
struct SServerArgs
sl@0
   396
	{
sl@0
   397
	TBool iBadServer;
sl@0
   398
	RSemaphore iSemArray;
sl@0
   399
	};
sl@0
   400
sl@0
   401
SServerArgs gServerArgsArray[KMaxTestThreads];
sl@0
   402
sl@0
   403
CTestServer::CTestServer(TInt aPriority)
sl@0
   404
//
sl@0
   405
// Constructor - sets name
sl@0
   406
//
sl@0
   407
	: CServer2(aPriority)
sl@0
   408
	{}
sl@0
   409
sl@0
   410
CSession2* CTestServer::NewSessionL(const TVersion& aVersion,const RMessage2& /*aMessage*/) const
sl@0
   411
//
sl@0
   412
// Virtual fn - checks version supported and creates a CTestSession
sl@0
   413
//
sl@0
   414
	{
sl@0
   415
	TVersion version(KE32MajorVersionNumber,KE32MinorVersionNumber,KE32BuildVersionNumber);
sl@0
   416
	if (User::QueryVersionSupported(version,aVersion)==EFalse)
sl@0
   417
		User::Leave(KErrNotSupported);
sl@0
   418
	CTestSession* newCTestSession = new CTestSession;
sl@0
   419
	if (newCTestSession==NULL)
sl@0
   420
		User::Panic(_L("NewSessionL failure"), KErrNoMemory);
sl@0
   421
	return(newCTestSession);
sl@0
   422
	}
sl@0
   423
sl@0
   424
TInt CTestSession::ReadWrite(const RMessage2& aMessage, TBool aRead, TBool aWrite)
sl@0
   425
	{
sl@0
   426
	TInt r = KErrNone;
sl@0
   427
	for (TUint argIndex = 0; argIndex < 4; argIndex++)
sl@0
   428
		{
sl@0
   429
		// Get the length of the descriptor and verify it is as expected.
sl@0
   430
		TInt length = aMessage.GetDesLength(argIndex);
sl@0
   431
		if (length < KErrNone)
sl@0
   432
			{
sl@0
   433
			RDebug::Printf("  Error getting descriptor length %d", length);
sl@0
   434
			return length;
sl@0
   435
			}
sl@0
   436
sl@0
   437
		
sl@0
   438
		if (aRead)
sl@0
   439
			{
sl@0
   440
			// Now read the descriptor
sl@0
   441
			HBufC8* des = HBufC8::New(length);
sl@0
   442
			if (!des)
sl@0
   443
				return KErrNoMemory;
sl@0
   444
			TPtr8 desPtr = des->Des();
sl@0
   445
			r = aMessage.Read(argIndex, desPtr);
sl@0
   446
			if (r != KErrNone)
sl@0
   447
				{
sl@0
   448
				delete des;
sl@0
   449
				return r;
sl@0
   450
				}
sl@0
   451
			//TODO: Verify the descriptor
sl@0
   452
			delete des;
sl@0
   453
			}
sl@0
   454
sl@0
   455
		if (aWrite)
sl@0
   456
			{
sl@0
   457
			// Now write to the maximum length of the descriptor.
sl@0
   458
			TInt max = length;
sl@0
   459
			HBufC8* argTmp = HBufC8::New(max);
sl@0
   460
			if (!argTmp)
sl@0
   461
				return KErrNoMemory;
sl@0
   462
sl@0
   463
			TPtr8 argPtr = argTmp->Des();
sl@0
   464
			argPtr.SetLength(max);
sl@0
   465
			for (TInt i = 0; i < max; i++)
sl@0
   466
				argPtr[i] = (TUint8)argIndex;
sl@0
   467
			r = aMessage.Write(argIndex, argPtr);
sl@0
   468
			delete argTmp;
sl@0
   469
			if (r != KErrNone)
sl@0
   470
				return r;
sl@0
   471
			}
sl@0
   472
		}
sl@0
   473
sl@0
   474
	return KErrNone;
sl@0
   475
	}
sl@0
   476
sl@0
   477
sl@0
   478
void CTestSession::ServiceL(const RMessage2& aMessage)
sl@0
   479
//
sl@0
   480
// Virtual message-handler
sl@0
   481
//
sl@0
   482
	{
sl@0
   483
	TInt r = KErrNone;
sl@0
   484
	iClientDied = EFalse;
sl@0
   485
	switch (aMessage.Function())
sl@0
   486
		{
sl@0
   487
		case EStop:
sl@0
   488
			RDBGD_PRINT(("Stopping server"));
sl@0
   489
			CActiveScheduler::Stop();
sl@0
   490
			break;
sl@0
   491
sl@0
   492
		case ERead:
sl@0
   493
			r = ReadWrite(aMessage, ETrue, EFalse);
sl@0
   494
			break;
sl@0
   495
		case EWrite:
sl@0
   496
			r = ReadWrite(aMessage, EFalse, ETrue);
sl@0
   497
			break;
sl@0
   498
		case EReadWrite:
sl@0
   499
			r = ReadWrite(aMessage, ETrue, ETrue);
sl@0
   500
			break;
sl@0
   501
	
sl@0
   502
		default:
sl@0
   503
			r = KErrNotSupported;
sl@0
   504
sl@0
   505
		}
sl@0
   506
 	aMessage.Complete(r);
sl@0
   507
sl@0
   508
	// If descriptors aren't as expected then panic so the test will fail.
sl@0
   509
	if (r != KErrNone)
sl@0
   510
		User::Panic(_L("ServiceL failure"), r);
sl@0
   511
	}
sl@0
   512
sl@0
   513
// CTestSession funtions
sl@0
   514
sl@0
   515
void CMyActiveScheduler::Error(TInt anError) const
sl@0
   516
//
sl@0
   517
// Virtual error handler
sl@0
   518
//
sl@0
   519
	{
sl@0
   520
	User::Panic(_L("CMyActiveScheduer::Error"), anError);
sl@0
   521
	}
sl@0
   522
sl@0
   523
sl@0
   524
TInt ServerThread(TAny* aThreadIndex)
sl@0
   525
//
sl@0
   526
// Passed as the server thread in 2 tests - sets up and runs CTestServer
sl@0
   527
//
sl@0
   528
	{
sl@0
   529
	RDBGD_PRINT(("ServerThread"));
sl@0
   530
	TUint threadIndex = (TUint)aThreadIndex;
sl@0
   531
sl@0
   532
	TBuf<16> serverName;
sl@0
   533
	serverName = _L("ServerName_");
sl@0
   534
	serverName.AppendNum(threadIndex);
sl@0
   535
sl@0
   536
sl@0
   537
	CMyActiveScheduler* pScheduler = new CMyActiveScheduler;
sl@0
   538
	if (pScheduler == NULL)
sl@0
   539
		{
sl@0
   540
		gServerArgsArray[threadIndex].iBadServer = ETrue;
sl@0
   541
		gServerArgsArray[threadIndex].iSemArray.Signal();
sl@0
   542
		return KErrNoMemory;
sl@0
   543
		}
sl@0
   544
sl@0
   545
	CActiveScheduler::Install(pScheduler);
sl@0
   546
sl@0
   547
	CTestServer* pServer = new CTestServer(0);
sl@0
   548
	if (pServer == NULL)
sl@0
   549
		{
sl@0
   550
		gServerArgsArray[threadIndex].iBadServer = ETrue;
sl@0
   551
		gServerArgsArray[threadIndex].iSemArray.Signal();
sl@0
   552
		delete pScheduler;
sl@0
   553
		return KErrNoMemory;
sl@0
   554
		}
sl@0
   555
sl@0
   556
	//Starting a CServer2 also Adds it to the ActiveScheduler
sl@0
   557
	TInt r = pServer->Start(serverName);
sl@0
   558
	if (r != KErrNone)
sl@0
   559
		{
sl@0
   560
		gServerArgsArray[threadIndex].iBadServer = ETrue;
sl@0
   561
		gServerArgsArray[threadIndex].iSemArray.Signal();
sl@0
   562
		delete pScheduler;
sl@0
   563
		delete pServer;
sl@0
   564
		return r;
sl@0
   565
		}
sl@0
   566
sl@0
   567
	RDBGD_PRINT(("Start ActiveScheduler and signal to client"));
sl@0
   568
	RDBGD_PRINT(("There might be something going on beneath this window\n"));
sl@0
   569
	gServerArgsArray[threadIndex].iSemArray.Signal();
sl@0
   570
	CActiveScheduler::Start();
sl@0
   571
sl@0
   572
	delete pScheduler;
sl@0
   573
	delete pServer;
sl@0
   574
sl@0
   575
	return KErrNone;
sl@0
   576
	}
sl@0
   577
sl@0
   578
TInt BadServerThread(TAny* /*aThreadIndex*/)
sl@0
   579
//
sl@0
   580
// Passed as the server thread in 2 tests - sets up and runs CTestServer
sl@0
   581
//
sl@0
   582
	{
sl@0
   583
	RDBGD_PRINT(("BadServerThread"));
sl@0
   584
	CMyActiveScheduler* pScheduler = new CMyActiveScheduler;
sl@0
   585
	if (pScheduler == NULL)
sl@0
   586
		{
sl@0
   587
		RDBGD_PRINT(("BST:Fail1"));
sl@0
   588
		gServerArgsArray[KSemServer].iBadServer = ETrue;
sl@0
   589
		gServerArgsArray[KSemServer].iSemArray.Signal();
sl@0
   590
		return KErrNoMemory;
sl@0
   591
		}
sl@0
   592
sl@0
   593
	CActiveScheduler::Install(pScheduler);
sl@0
   594
sl@0
   595
	CTestServer* pServer = new CTestServer(0);
sl@0
   596
	if (pServer == NULL)
sl@0
   597
		{
sl@0
   598
		RDBGD_PRINT(("BST:Fail2"));
sl@0
   599
		gServerArgsArray[KSemServer].iBadServer = ETrue;
sl@0
   600
		gServerArgsArray[KSemServer].iSemArray.Signal();
sl@0
   601
		delete pScheduler;
sl@0
   602
		return KErrNoMemory;
sl@0
   603
		}
sl@0
   604
sl@0
   605
	//pServer->SetPinClientDescriptors(ETrue);
sl@0
   606
sl@0
   607
sl@0
   608
	//Starting a CServer2 also Adds it to the ActiveScheduler
sl@0
   609
	TInt r = pServer->Start(KTestServer);
sl@0
   610
	if (r != KErrNone)
sl@0
   611
		{
sl@0
   612
		RDBGD_PRINT(("BST:Fail3"));
sl@0
   613
		gServerArgsArray[KSemServer].iBadServer = ETrue;
sl@0
   614
		gServerArgsArray[KSemServer].iSemArray.Signal();
sl@0
   615
		delete pScheduler;
sl@0
   616
		delete pServer;
sl@0
   617
		return r;
sl@0
   618
		}
sl@0
   619
sl@0
   620
	RDBGD_PRINT(("Start ActiveScheduler and signal to client"));
sl@0
   621
	RDBGD_PRINT(("There might be something going on beneath this window\n"));
sl@0
   622
	gServerArgsArray[KSemServer].iSemArray.Signal();
sl@0
   623
	CActiveScheduler::Start();
sl@0
   624
sl@0
   625
	delete pScheduler;
sl@0
   626
	delete pServer;
sl@0
   627
	RDBGD_PRINT(("BST:Pass1"));
sl@0
   628
	return KErrNone;
sl@0
   629
	}
sl@0
   630
sl@0
   631
TInt SendMessages(TUint aIters, TUint aSize, TDesC& aServerName, TInt aIndex, TBool aLowMem = EFalse)
sl@0
   632
//
sl@0
   633
// Passed as the first client thread - signals the server to do several tests
sl@0
   634
//
sl@0
   635
	{
sl@0
   636
	HBufC8* argTmp1;
sl@0
   637
	HBufC8* argTmp2;
sl@0
   638
	HBufC8* argTmp3;
sl@0
   639
	HBufC8* argTmp4;
sl@0
   640
sl@0
   641
	DOTEST((argTmp1 = HBufC8::New(aSize)), (argTmp1 != NULL));
sl@0
   642
	*argTmp1 = (const TUint8*)"argTmp1";
sl@0
   643
	TPtr8 ptr1 = argTmp1->Des();
sl@0
   644
sl@0
   645
	DOTEST((argTmp2 = HBufC8::New(aSize)), (argTmp2 != NULL));
sl@0
   646
	*argTmp2 = (const TUint8*)"argTmp2";
sl@0
   647
	TPtr8 ptr2 = argTmp2->Des();
sl@0
   648
sl@0
   649
	DOTEST((argTmp3 = HBufC8::New(aSize)), (argTmp3 != NULL));
sl@0
   650
	*argTmp3 = (const TUint8*)"argTmp3";
sl@0
   651
	TPtr8 ptr3 = argTmp3->Des();
sl@0
   652
sl@0
   653
	DOTEST((argTmp4 = HBufC8::New(aSize)), (argTmp1 != NULL));
sl@0
   654
	*argTmp4 = (const TUint8*)"argTmp4";
sl@0
   655
	TPtr8 ptr4 = argTmp4->Des();
sl@0
   656
	
sl@0
   657
	RSession session;
sl@0
   658
	TInt r = KErrNone;
sl@0
   659
	if(gTestBadServer)
sl@0
   660
		{//Don't do bad server tests with lowmem
sl@0
   661
		r = session.PublicCreateSession(aServerName,5);
sl@0
   662
		}
sl@0
   663
	else
sl@0
   664
		{
sl@0
   665
		DOTEST((r = session.PublicCreateSession(aServerName,5)), (r != KErrNoMemory));
sl@0
   666
		}
sl@0
   667
	if (r != KErrNone)
sl@0
   668
		{
sl@0
   669
		RDBGD_PRINT(("SendMessages[%d] failed to create session r = %d", aIndex, r));
sl@0
   670
		return r;
sl@0
   671
		}
sl@0
   672
	
sl@0
   673
	if(gTestBadServer)
sl@0
   674
		{
sl@0
   675
		RThread::Rendezvous(KErrNone);
sl@0
   676
		RDBGD_PRINT(("Wait on sem %d", aIndex));
sl@0
   677
		//gServerArgsArray[KSemCliSessStarted].iSemArray.Wait();
sl@0
   678
		}
sl@0
   679
	
sl@0
   680
	RDBGD_PRINT(("ID (%d)ReadWrite" ,aIndex));
sl@0
   681
	for (TUint i = 0; i < aIters; i++)
sl@0
   682
		{
sl@0
   683
		TUint mode = (i&0x3) + CTestSession::ERead;
sl@0
   684
		switch(mode)
sl@0
   685
			{
sl@0
   686
			case CTestSession::ERead:
sl@0
   687
				DOTEST((r = session.PublicSendReceive(CTestSession::ERead, TIpcArgs(&ptr1, &ptr2, &ptr3, &ptr4).PinArgs())), 
sl@0
   688
						(r != KErrNoMemory));
sl@0
   689
				if (r != KErrNone)
sl@0
   690
					return r;
sl@0
   691
				break;
sl@0
   692
sl@0
   693
			case CTestSession::EWrite:
sl@0
   694
				DOTEST((r = session.PublicSendReceive(CTestSession::EWrite, TIpcArgs(&ptr1, &ptr2, &ptr3, &ptr4).PinArgs())), 
sl@0
   695
						(r != KErrNoMemory));
sl@0
   696
				if (r != KErrNone)
sl@0
   697
					return r;
sl@0
   698
				break;
sl@0
   699
			case CTestSession::EReadWrite:
sl@0
   700
				DOTEST((r = session.PublicSendReceive(CTestSession::EReadWrite, TIpcArgs(&ptr1, &ptr2, &ptr3, &ptr4).PinArgs())), 
sl@0
   701
						(r != KErrNoMemory));
sl@0
   702
				if (r != KErrNone)
sl@0
   703
					return r;
sl@0
   704
				break;
sl@0
   705
sl@0
   706
			}
sl@0
   707
		}
sl@0
   708
	RDBGD_PRINT(("ID(%d) Closing session", aIndex));
sl@0
   709
	session.Close();
sl@0
   710
	return r;
sl@0
   711
	}
sl@0
   712
sl@0
   713
TInt TestIPCPinning(SPerformTestArgs& aTestArguments)
sl@0
   714
	{
sl@0
   715
	TInt r = KErrNone;
sl@0
   716
	// Create the server thread it needs to have a unpaged stack and heap.
sl@0
   717
	TBuf<16> serverThreadName;
sl@0
   718
	serverThreadName = _L("ServerThread_");
sl@0
   719
	serverThreadName.AppendNum(aTestArguments.iThreadIndex);
sl@0
   720
	TThreadCreateInfo serverInfo(serverThreadName, ServerThread, KDefaultStackSize, (TAny *) aTestArguments.iThreadIndex);
sl@0
   721
	serverInfo.SetUseHeap(NULL);
sl@0
   722
	
sl@0
   723
	gServerArgsArray[aTestArguments.iThreadIndex].iBadServer = EFalse;
sl@0
   724
sl@0
   725
	// Create the semaphores for the IPC pinning tests
sl@0
   726
	DOTEST1((r = gServerArgsArray[aTestArguments.iThreadIndex].iSemArray.CreateLocal(0)), (r != KErrNoMemory));
sl@0
   727
	if (r != KErrNone)
sl@0
   728
		{
sl@0
   729
		RDBGD_PRINT(("Failed to create semaphonre[%d] r = %d", aTestArguments.iThreadIndex, r));
sl@0
   730
		return r;
sl@0
   731
		}
sl@0
   732
sl@0
   733
	RThread serverThread;
sl@0
   734
	TInt r1 = KErrNone;
sl@0
   735
	DOTEST1((r1 = serverThread.Create(serverInfo)), (r1 != KErrNoMemory));
sl@0
   736
	if (r1 != KErrNone)
sl@0
   737
		{
sl@0
   738
		RDBGD_PRINT(("Failed to create server thread[%d] r1 = %d", aTestArguments.iThreadIndex, r1));
sl@0
   739
		return r1;
sl@0
   740
		}
sl@0
   741
	TRequestStatus serverStat;
sl@0
   742
	serverThread.Logon(serverStat);
sl@0
   743
	serverThread.Resume();
sl@0
   744
sl@0
   745
	// Wait for the server to start and then create a session to it.
sl@0
   746
	TBuf<16> serverName;
sl@0
   747
	serverName = _L("ServerName_");
sl@0
   748
	serverName.AppendNum(aTestArguments.iThreadIndex);
sl@0
   749
sl@0
   750
	gServerArgsArray[aTestArguments.iThreadIndex].iSemArray.Wait();
sl@0
   751
	
sl@0
   752
	// First check that the server started successfully
sl@0
   753
	if (gServerArgsArray[aTestArguments.iThreadIndex].iBadServer)
sl@0
   754
		return KErrServerTerminated;
sl@0
   755
sl@0
   756
	RSession session;
sl@0
   757
	DOTEST1((r1 = session.PublicCreateSession(serverName,5)), (r1 != KErrNoMemory));
sl@0
   758
	if (r1 != KErrNone)
sl@0
   759
		{
sl@0
   760
		RDBGD_PRINT(("Failed to create session[%d] r1 = %d", aTestArguments.iThreadIndex, r1));
sl@0
   761
		return r1;
sl@0
   762
		}
sl@0
   763
	
sl@0
   764
	r1 = SendMessages(50, 10, serverName, aTestArguments.iThreadIndex, aTestArguments.iLowMem);
sl@0
   765
	if (r1 != KErrNone)
sl@0
   766
		{
sl@0
   767
		RDBGD_PRINT(("SendMessages[%d] r1 = %d", aTestArguments.iThreadIndex, r1));
sl@0
   768
		return r1;
sl@0
   769
		}
sl@0
   770
	TInt r2 = KErrNone;
sl@0
   771
	
sl@0
   772
	// Signal to stop ActiveScheduler and wait for server to stop.
sl@0
   773
	session.PublicSendReceive(CTestSession::EStop, TIpcArgs());
sl@0
   774
	session.Close();
sl@0
   775
sl@0
   776
	User::WaitForRequest(serverStat);
sl@0
   777
	if (serverThread.ExitType() == EExitKill &&
sl@0
   778
		serverThread.ExitReason() != KErrNone)	
sl@0
   779
		{
sl@0
   780
		r2 = serverThread.ExitReason();
sl@0
   781
		}
sl@0
   782
	if (serverThread.ExitType() != EExitKill)	
sl@0
   783
		{
sl@0
   784
		RDBGD_PRINT(("Server thread panic'd"));
sl@0
   785
		r2 = KErrGeneral;
sl@0
   786
		}
sl@0
   787
sl@0
   788
	serverThread.Close();
sl@0
   789
	gServerArgsArray[aTestArguments.iThreadIndex].iSemArray.Close();
sl@0
   790
		
sl@0
   791
	if (r1 != KErrNone)
sl@0
   792
		return r1;
sl@0
   793
sl@0
   794
	return r2;
sl@0
   795
	}
sl@0
   796
sl@0
   797
TInt ClientThread(TAny* aClientThread)
sl@0
   798
	{
sl@0
   799
	TInt r = KErrNone;
sl@0
   800
	
sl@0
   801
	TBuf<16> serverName;
sl@0
   802
	serverName = KTestServer;
sl@0
   803
	RDBGD_PRINT(("CT(%d):Sending Messages" ,aClientThread));
sl@0
   804
	r = SendMessages(500, 10, serverName, (TInt) aClientThread);
sl@0
   805
	if (r != KErrNone)
sl@0
   806
		{
sl@0
   807
		RDBGD_PRINT(("SendMessages[%d] r = %d", (TInt) aClientThread, r));
sl@0
   808
		return r;
sl@0
   809
		}
sl@0
   810
	return r;
sl@0
   811
	}
sl@0
   812
sl@0
   813
TInt TestIPCBadServer(SPerformTestArgs& aTestArguments)
sl@0
   814
	{
sl@0
   815
	TInt cliRet = KErrNone;
sl@0
   816
	TInt serRet = KErrNone;
sl@0
   817
sl@0
   818
	// Create the server thread it needs to have a unpaged stack and heap.
sl@0
   819
	TBuf<16> serverThreadName;
sl@0
   820
	serverThreadName = _L("BadServerThread");
sl@0
   821
	TThreadCreateInfo serverInfo(serverThreadName, BadServerThread, KDefaultStackSize, NULL);
sl@0
   822
	serverInfo.SetUseHeap(NULL);
sl@0
   823
	
sl@0
   824
	// Create the semaphores for the IPC pinning tests
sl@0
   825
	DOTEST1((serRet = gServerArgsArray[KSemServer].iSemArray.CreateLocal(0)), (serRet != KErrNoMemory));
sl@0
   826
	if (serRet != KErrNone)
sl@0
   827
		{
sl@0
   828
		RDBGD_PRINT(("Failed to create semaphonre[%d] serRet = %d", KSemServer, serRet));
sl@0
   829
		return serRet;
sl@0
   830
		}
sl@0
   831
sl@0
   832
	RThread serverThread;
sl@0
   833
	DOTEST1((serRet = serverThread.Create(serverInfo)), (serRet != KErrNoMemory));
sl@0
   834
	if (serRet != KErrNone)
sl@0
   835
		{
sl@0
   836
		RDBGD_PRINT(("Failed to create server thread serRet = %d", serRet));
sl@0
   837
		return serRet;
sl@0
   838
		}
sl@0
   839
	TRequestStatus serverStat;
sl@0
   840
	serverThread.Logon(serverStat);
sl@0
   841
	serverThread.Resume();
sl@0
   842
sl@0
   843
	// Wait for the server to start and then create a session to it.
sl@0
   844
	gServerArgsArray[KSemServer].iSemArray.Wait();
sl@0
   845
	
sl@0
   846
	// First check that the server started successfully
sl@0
   847
	if (gServerArgsArray[KSemServer].iBadServer)
sl@0
   848
		return KErrServerTerminated;
sl@0
   849
sl@0
   850
sl@0
   851
	//create client threads
sl@0
   852
	const TUint KNumClientThreads = 50;	
sl@0
   853
	RThread clientThreads[KNumClientThreads];
sl@0
   854
	TRequestStatus clientStarted[KNumClientThreads];
sl@0
   855
	TRequestStatus clientStats[KNumClientThreads];
sl@0
   856
sl@0
   857
	// Create the client threads
sl@0
   858
	TBuf<16> clientThreadName;
sl@0
   859
	TUint i;
sl@0
   860
	for (i = 0; i < KNumClientThreads; i++)
sl@0
   861
		{
sl@0
   862
		clientThreadName = _L("clientThread_");
sl@0
   863
		clientThreadName.AppendNum(i);
sl@0
   864
		TThreadCreateInfo clientInfo(clientThreadName, ClientThread, KDefaultStackSize, (TAny*)i);
sl@0
   865
		clientInfo.SetPaging(TThreadCreateInfo::EPaged);
sl@0
   866
		clientInfo.SetCreateHeap(KMinHeapSize, KMinHeapSize);
sl@0
   867
		cliRet = clientThreads[i].Create(clientInfo);
sl@0
   868
		if (cliRet != KErrNone)
sl@0
   869
			{
sl@0
   870
			RDBGD_PRINT(("Failed to create client thread [%d] cliRet = %d", i, cliRet));
sl@0
   871
			return cliRet;
sl@0
   872
			}
sl@0
   873
		clientThreads[i].Rendezvous(clientStarted[i]);	
sl@0
   874
		clientThreads[i].Logon(clientStats[i]);
sl@0
   875
		clientThreads[i].Resume();
sl@0
   876
		}
sl@0
   877
	
sl@0
   878
	// Wait for creation of the client thread sessions
sl@0
   879
	for (i = 0; i < KNumClientThreads; i++)
sl@0
   880
		{
sl@0
   881
		User::WaitForRequest(clientStarted[i]);
sl@0
   882
		if (clientStarted[i].Int() != KErrNone)
sl@0
   883
			return clientStarted[i].Int();
sl@0
   884
		}
sl@0
   885
	
sl@0
   886
sl@0
   887
	// Once the messages are being sent, create a session to the
sl@0
   888
	// same server and signal to stop ActiveScheduler
sl@0
   889
	RSession session;
sl@0
   890
	serRet = session.PublicCreateSession(KTestServer,5);
sl@0
   891
	if (serRet != KErrNone)
sl@0
   892
		{
sl@0
   893
		RDBGD_PRINT(("Failed to create session serRet = %d", serRet));
sl@0
   894
		return serRet;
sl@0
   895
		}
sl@0
   896
	session.PublicSendReceive(CTestSession::EStop, TIpcArgs());
sl@0
   897
	session.Close();
sl@0
   898
sl@0
   899
	// Wait for the client thread to end.
sl@0
   900
	cliRet = KErrNone;
sl@0
   901
	for (i = 0; i < KNumClientThreads; i++)
sl@0
   902
		{
sl@0
   903
		User::WaitForRequest(clientStats[i]);
sl@0
   904
		RDBGD_PRINT(("Thread complete clientStats[%d] = %d", i, clientStats[i].Int()));
sl@0
   905
		if (clientStats[i].Int() != KErrNone && 
sl@0
   906
			clientStats[i].Int() != KErrServerTerminated)
sl@0
   907
			{
sl@0
   908
			cliRet = clientStats[i].Int();
sl@0
   909
			}
sl@0
   910
		}
sl@0
   911
sl@0
   912
	// Check that the server ended correctly
sl@0
   913
	serRet = KErrNone;
sl@0
   914
	User::WaitForRequest(serverStat);
sl@0
   915
	if (serverThread.ExitType() == EExitKill &&
sl@0
   916
		serverThread.ExitReason() != KErrNone)	
sl@0
   917
		{
sl@0
   918
		serRet = serverThread.ExitReason();
sl@0
   919
		}
sl@0
   920
	if (serverThread.ExitType() != EExitKill)	
sl@0
   921
		{
sl@0
   922
		RDBGD_PRINT(("Server thread panic'd"));
sl@0
   923
		serRet = KErrGeneral;
sl@0
   924
		}
sl@0
   925
sl@0
   926
	// Close all the server thread and client threads
sl@0
   927
	for (i = 0; i < KNumClientThreads; i++)
sl@0
   928
		{
sl@0
   929
		clientThreads[i].Close();
sl@0
   930
		}
sl@0
   931
	serverThread.Close();
sl@0
   932
		
sl@0
   933
	if (cliRet != KErrNone)
sl@0
   934
		return cliRet;
sl@0
   935
sl@0
   936
	return serRet;
sl@0
   937
	}
sl@0
   938
sl@0
   939
sl@0
   940
//
sl@0
   941
// RemoveChunkAlloc
sl@0
   942
//
sl@0
   943
// Remove ALL chunks allocated
sl@0
   944
//
sl@0
   945
// @param aChunkArray The array that stores a reference to the chunks created.
sl@0
   946
// @param aChunkArraySize The size of aChunkArray.
sl@0
   947
//
sl@0
   948
void RemoveChunkAlloc(RChunk*& aChunkArray, TUint aChunkArraySize)
sl@0
   949
	{
sl@0
   950
	if (aChunkArray == NULL)
sl@0
   951
		{// The chunk array has already been deleted.
sl@0
   952
		return;
sl@0
   953
		}
sl@0
   954
sl@0
   955
	for (TUint i = 0; i < aChunkArraySize; i++)
sl@0
   956
		{
sl@0
   957
		if (aChunkArray[i].Handle() != NULL)
sl@0
   958
			{
sl@0
   959
			aChunkArray[i].Close();
sl@0
   960
			gChunksAllocd --;
sl@0
   961
			if (gChunksAllocd < gMaxChunks)
sl@0
   962
				gMaxChunksReached = EFalse;
sl@0
   963
			}
sl@0
   964
		}
sl@0
   965
	delete[] aChunkArray;
sl@0
   966
	aChunkArray = NULL;
sl@0
   967
	}	
sl@0
   968
sl@0
   969
TInt WriteToChunk(RChunk* aChunkArray, TUint aChunkArraySize)
sl@0
   970
	{
sl@0
   971
	for (TUint j = 0; j < aChunkArraySize; j++) 
sl@0
   972
		{
sl@0
   973
		if (aChunkArray[j].Handle() != NULL)
sl@0
   974
			{
sl@0
   975
			TUint32* base = (TUint32*)aChunkArray[j].Base();
sl@0
   976
			TUint32* end = (TUint32*)(aChunkArray[j].Base() + aChunkArray[j].Size());
sl@0
   977
			for (TUint32 k = 0; base < end; k++)
sl@0
   978
				{
sl@0
   979
				*base++ = k; // write index to the chunk
sl@0
   980
				}
sl@0
   981
			}		
sl@0
   982
		}
sl@0
   983
	return KErrNone;
sl@0
   984
	}
sl@0
   985
sl@0
   986
TUint32 ReadByte(volatile TUint32* aPtr)
sl@0
   987
	{
sl@0
   988
	return *aPtr;
sl@0
   989
	}
sl@0
   990
sl@0
   991
TInt ReadChunk(RChunk* aChunkArray, TUint aChunkArraySize)
sl@0
   992
	{
sl@0
   993
	for (TUint j=0; j < aChunkArraySize; j++) //Read all open chunks
sl@0
   994
		{
sl@0
   995
		if (aChunkArray[j].Handle() != NULL)
sl@0
   996
			{
sl@0
   997
			TUint32* base = (TUint32*)aChunkArray[j].Base();
sl@0
   998
			TUint32* end = (TUint32*)(aChunkArray[j].Base() + aChunkArray[j].Size());
sl@0
   999
			for (TUint32 k = 0; base < end; k++)
sl@0
  1000
				{
sl@0
  1001
				TUint value = ReadByte((volatile TUint32*)base++);
sl@0
  1002
				if (value != k)
sl@0
  1003
					{
sl@0
  1004
					RDBGS_PRINT(("Read value incorrect expected 0x%x got 0x%x", k, value));
sl@0
  1005
					return KErrGeneral;
sl@0
  1006
					}
sl@0
  1007
				}
sl@0
  1008
			}		
sl@0
  1009
		}
sl@0
  1010
	return KErrNone;
sl@0
  1011
	}
sl@0
  1012
sl@0
  1013
sl@0
  1014
TInt CreateChunks(SPerformTestArgs& aTestArguments, RChunk*& aChunkArray, TUint aChunkArraySize)
sl@0
  1015
	{
sl@0
  1016
	TInt r = KErrNone;
sl@0
  1017
sl@0
  1018
	TUint chunkSize = 1 << gPageShift;
sl@0
  1019
sl@0
  1020
	// Allocate as many chunks as is specified, either with the default chunk size or a specified chunk size
sl@0
  1021
	if (aChunkArray == NULL)
sl@0
  1022
		{
sl@0
  1023
		DOTEST1((aChunkArray = new RChunk[aChunkArraySize]), (aChunkArray != NULL));
sl@0
  1024
		if (aChunkArray == NULL)
sl@0
  1025
			return KErrNoMemory;
sl@0
  1026
		}
sl@0
  1027
	
sl@0
  1028
	TChunkCreateInfo createInfo;
sl@0
  1029
	createInfo.SetNormal(chunkSize, chunkSize);
sl@0
  1030
	createInfo.SetPaging(TChunkCreateInfo::EPaged);
sl@0
  1031
sl@0
  1032
sl@0
  1033
	// Create chunks for each RChunk with a NULL handle.
sl@0
  1034
	for (TUint i = 0; i < aChunkArraySize; i++)
sl@0
  1035
		{
sl@0
  1036
		DOTEST1((r = aChunkArray[i].Create(createInfo)), (r != KErrNoMemory));
sl@0
  1037
		if (r != KErrNone)
sl@0
  1038
			{
sl@0
  1039
			if (r == KErrOverflow)
sl@0
  1040
				{
sl@0
  1041
				gMaxChunks = gChunksAllocd;
sl@0
  1042
				RDBGD_PRINT(("Max Chunks Allowed = %d", gMaxChunks));
sl@0
  1043
				gMaxChunksReached = ETrue;
sl@0
  1044
				}
sl@0
  1045
			return r;
sl@0
  1046
			}
sl@0
  1047
		gChunksAllocd++;
sl@0
  1048
		RDBGD_PRINT(("TID(%d) aChunkArray[%d], r = %d", aTestArguments.iThreadIndex, i, r));
sl@0
  1049
		}
sl@0
  1050
	RDBGD_PRINT(("TID(%d) created chunks r = %d", aTestArguments.iThreadIndex, r));
sl@0
  1051
	
sl@0
  1052
	return KErrNone;
sl@0
  1053
	}
sl@0
  1054
//
sl@0
  1055
// TestChunkPaging
sl@0
  1056
//
sl@0
  1057
// Create a number of chunks and write to them
sl@0
  1058
// read the chunk back to ensure the values are correct
sl@0
  1059
//
sl@0
  1060
sl@0
  1061
TInt TestChunkPaging(SPerformTestArgs& aTestArguments)
sl@0
  1062
	{
sl@0
  1063
	TInt r = KErrNone;
sl@0
  1064
	const TUint KNumChunks = 10;
sl@0
  1065
	
sl@0
  1066
	
sl@0
  1067
	if(gMaxChunksReached)
sl@0
  1068
		{// We cant create any more chunks as the max number has been reached
sl@0
  1069
		return KErrNone;
sl@0
  1070
		}
sl@0
  1071
sl@0
  1072
	RChunk* chunkArray = NULL;	
sl@0
  1073
	r = CreateChunks(aTestArguments, chunkArray, KNumChunks);
sl@0
  1074
	if (r != KErrNone)
sl@0
  1075
		{
sl@0
  1076
		if (r == KErrOverflow)
sl@0
  1077
			{
sl@0
  1078
			RDBGD_PRINT(("Max number of chunks reached"));
sl@0
  1079
			RemoveChunkAlloc(chunkArray, KNumChunks);
sl@0
  1080
			return KErrNone;
sl@0
  1081
			}
sl@0
  1082
		RDBGD_PRINT(("TID(%d) CreateChunks r = %d", aTestArguments.iThreadIndex, r));
sl@0
  1083
		return r;
sl@0
  1084
		}
sl@0
  1085
sl@0
  1086
	r = WriteToChunk(chunkArray, KNumChunks);
sl@0
  1087
	if (r != KErrNone)
sl@0
  1088
		{
sl@0
  1089
		RemoveChunkAlloc(chunkArray, KNumChunks);
sl@0
  1090
		RDBGD_PRINT(("TID(%d) WriteToChunk r = %d", aTestArguments.iThreadIndex, r));
sl@0
  1091
		return r;
sl@0
  1092
		}
sl@0
  1093
sl@0
  1094
	r = ReadChunk(chunkArray, KNumChunks);
sl@0
  1095
	if (r != KErrNone)
sl@0
  1096
		{
sl@0
  1097
		RemoveChunkAlloc(chunkArray, KNumChunks);
sl@0
  1098
		RDBGD_PRINT(("TID(%d) ReadChunk r = %d", aTestArguments.iThreadIndex, r));
sl@0
  1099
		return r;
sl@0
  1100
		} 
sl@0
  1101
	RemoveChunkAlloc(chunkArray, KNumChunks);
sl@0
  1102
	return KErrNone;
sl@0
  1103
	}
sl@0
  1104
sl@0
  1105
sl@0
  1106
//
sl@0
  1107
// TestChunkCommit
sl@0
  1108
//
sl@0
  1109
// Create a chunk
sl@0
  1110
// commit a page at a time, write to that page and then decommit the page
sl@0
  1111
//
sl@0
  1112
sl@0
  1113
TInt TestChunkCommit(SPerformTestArgs& aTestArguments)
sl@0
  1114
	{
sl@0
  1115
	TInt r = KErrNone;
sl@0
  1116
	RChunk testChunk;
sl@0
  1117
sl@0
  1118
	TUint chunkSize = 70 << gPageShift;
sl@0
  1119
sl@0
  1120
	TChunkCreateInfo createInfo;
sl@0
  1121
	createInfo.SetDisconnected(0, 0, chunkSize);
sl@0
  1122
	createInfo.SetPaging(TChunkCreateInfo::EPaged);
sl@0
  1123
	DOTEST1((r = testChunk.Create(createInfo)), (r != KErrNoMemory));
sl@0
  1124
	if (r != KErrNone)
sl@0
  1125
		{
sl@0
  1126
		return r;
sl@0
  1127
		}
sl@0
  1128
	TUint offset = 0;
sl@0
  1129
	while(offset < chunkSize)
sl@0
  1130
		{
sl@0
  1131
		// Commit a page
sl@0
  1132
		DOTEST1((r = testChunk.Commit(offset,gPageSize)), (r != KErrNoMemory));
sl@0
  1133
		if (r != KErrNone)
sl@0
  1134
			{
sl@0
  1135
			return r;
sl@0
  1136
			}
sl@0
  1137
sl@0
  1138
		// Write to the page
sl@0
  1139
		TUint8* pageStart = testChunk.Base() + offset;
sl@0
  1140
		*pageStart = 0xed;
sl@0
  1141
sl@0
  1142
sl@0
  1143
		// Decommit the page
sl@0
  1144
		r = testChunk.Decommit(offset, gPageSize);
sl@0
  1145
		if (r != KErrNone)
sl@0
  1146
			{
sl@0
  1147
			return r;
sl@0
  1148
			}
sl@0
  1149
		
sl@0
  1150
		offset += gPageSize;
sl@0
  1151
		}
sl@0
  1152
	
sl@0
  1153
sl@0
  1154
	testChunk.Close();
sl@0
  1155
	return r;
sl@0
  1156
	}
sl@0
  1157
sl@0
  1158
//
sl@0
  1159
// PerformTestThread
sl@0
  1160
//
sl@0
  1161
// This is the function that actually does the work.
sl@0
  1162
// It is complicated a little because test.Printf can only be called from the first thread that calls it 
sl@0
  1163
// so if we are using multiple threads we need to use a message queue to pass the debug info from the
sl@0
  1164
// child threads back to the parent for the parent to then call printf.
sl@0
  1165
//
sl@0
  1166
//
sl@0
  1167
sl@0
  1168
LOCAL_C TInt PerformTestThread(SPerformTestArgs& aTestArguments)
sl@0
  1169
	{
sl@0
  1170
	TInt r = KErrNone;
sl@0
  1171
	TUint start = User::TickCount();
sl@0
  1172
sl@0
  1173
	DEBUG_PRINT1((_L("%S : thread Starting %d\n"), &gTestNameBuffer, aTestArguments.iThreadIndex));
sl@0
  1174
	// now select how we do the test...
sl@0
  1175
	TInt	iterIndex = 0;
sl@0
  1176
sl@0
  1177
sl@0
  1178
	if (TEST_ALL == (gTestWhichTests & TEST_ALL))
sl@0
  1179
		{
sl@0
  1180
		#define LOCAL_ORDER_INDEX1	6
sl@0
  1181
		#define LOCAL_ORDER_INDEX2	4
sl@0
  1182
		TInt	order[LOCAL_ORDER_INDEX1][LOCAL_ORDER_INDEX2] = {	{TEST_STACK, TEST_CHUNK,TEST_COMMIT, TEST_IPC},
sl@0
  1183
																	{TEST_STACK, TEST_COMMIT,  TEST_CHUNK, TEST_IPC},
sl@0
  1184
																	{TEST_CHUNK,TEST_STACK, TEST_COMMIT, TEST_IPC},
sl@0
  1185
																	{TEST_CHUNK,TEST_COMMIT,  TEST_STACK, TEST_IPC},
sl@0
  1186
																	{TEST_COMMIT,  TEST_STACK, TEST_CHUNK, TEST_IPC},
sl@0
  1187
																	{TEST_COMMIT,  TEST_CHUNK,TEST_STACK, TEST_IPC}};
sl@0
  1188
		TInt	whichOrder = 0;
sl@0
  1189
		iterIndex = 0;
sl@0
  1190
		for (iterIndex = 0; iterIndex < gPerformTestLoop; iterIndex ++)
sl@0
  1191
			{
sl@0
  1192
			DEBUG_PRINT1((_L("iterIndex = %d\n"), iterIndex));
sl@0
  1193
			TInt    selOrder = ((aTestArguments.iThreadIndex + 1) * (iterIndex + 1)) % LOCAL_ORDER_INDEX1;
sl@0
  1194
			for (whichOrder = 0; whichOrder < LOCAL_ORDER_INDEX2; whichOrder ++)
sl@0
  1195
				{
sl@0
  1196
				DEBUG_PRINT1((_L("whichOrder = %d\n"), whichOrder));
sl@0
  1197
				switch (order[selOrder][whichOrder])
sl@0
  1198
					{
sl@0
  1199
					case TEST_STACK:
sl@0
  1200
					DEBUG_PRINT1((_L("%S : %d Iter %d Stack\n"), &gTestNameBuffer, aTestArguments.iThreadIndex, iterIndex));
sl@0
  1201
					r = TestStackPaging(aTestArguments);
sl@0
  1202
					DEBUG_PRINT1((_L("ThreadId %d Finished TestStackPaging() r = %d\n"), aTestArguments.iThreadIndex, r));
sl@0
  1203
					if (r != KErrNone)
sl@0
  1204
						return r;
sl@0
  1205
					break;
sl@0
  1206
sl@0
  1207
					case TEST_CHUNK:
sl@0
  1208
					DEBUG_PRINT1((_L("%S : %d Iter %d Chunk\n"), &gTestNameBuffer, aTestArguments.iThreadIndex, iterIndex));
sl@0
  1209
					r = TestChunkPaging(aTestArguments);
sl@0
  1210
					DEBUG_PRINT1((_L("ThreadId %d Finished TestChunkPaging() r = %d\n"), aTestArguments.iThreadIndex, r));
sl@0
  1211
					if (r != KErrNone)
sl@0
  1212
						return r;
sl@0
  1213
					break;
sl@0
  1214
sl@0
  1215
					case TEST_COMMIT:
sl@0
  1216
					DEBUG_PRINT1((_L("%S : %d Iter %d Commit\n"), &gTestNameBuffer, aTestArguments.iThreadIndex, iterIndex));
sl@0
  1217
					r = TestChunkCommit(aTestArguments);
sl@0
  1218
					DEBUG_PRINT1((_L("ThreadId %d Finished TestChunkCommit() r = %d\n"), aTestArguments.iThreadIndex, r));
sl@0
  1219
					if (r != KErrNone)
sl@0
  1220
						return r;
sl@0
  1221
					break;
sl@0
  1222
sl@0
  1223
					case TEST_IPC:
sl@0
  1224
					
sl@0
  1225
					if (gTestBadServer)
sl@0
  1226
						{
sl@0
  1227
						DEBUG_PRINT1((_L("%S : %d Iter %d IPC-BadServer\n"), &gTestNameBuffer, aTestArguments.iThreadIndex, iterIndex));
sl@0
  1228
						r = TestIPCBadServer(aTestArguments);
sl@0
  1229
						DEBUG_PRINT1((_L("ThreadId %d Finished TestIPCBadServer() r = %d\n"), aTestArguments.iThreadIndex, r));
sl@0
  1230
						}
sl@0
  1231
					else
sl@0
  1232
						{
sl@0
  1233
						DEBUG_PRINT1((_L("%S : %d Iter %d IPC\n"), &gTestNameBuffer, aTestArguments.iThreadIndex, iterIndex));
sl@0
  1234
						// Limit the IPC pinning stuff to 2 loops else will take a long time to run
sl@0
  1235
						if (gNumTestThreads > 1 && gPerformTestLoop > 2)
sl@0
  1236
							break;
sl@0
  1237
						r = TestIPCPinning(aTestArguments);
sl@0
  1238
						DEBUG_PRINT1((_L("ThreadId %d Finished TestIPCPinning() r = %d\n"), aTestArguments.iThreadIndex, r));
sl@0
  1239
						if (r != KErrNone)
sl@0
  1240
							return r;
sl@0
  1241
						}
sl@0
  1242
					break;
sl@0
  1243
					
sl@0
  1244
					default: // this is really an error.
sl@0
  1245
					break;
sl@0
  1246
					}
sl@0
  1247
				iterIndex++;
sl@0
  1248
				}
sl@0
  1249
			}
sl@0
  1250
		}
sl@0
  1251
	else
sl@0
  1252
		{
sl@0
  1253
		if (gTestWhichTests & TEST_STACK)
sl@0
  1254
			{
sl@0
  1255
			for (iterIndex = 0; iterIndex < gPerformTestLoop; iterIndex ++)
sl@0
  1256
				{
sl@0
  1257
				DEBUG_PRINT1((_L("%S : %d Iter %d Stack\n"), &gTestNameBuffer, aTestArguments.iThreadIndex, iterIndex));
sl@0
  1258
				r = TestStackPaging(aTestArguments);
sl@0
  1259
				DEBUG_PRINT1((_L("ThreadId %d Finished TestStackPaging() r = %d\n"), aTestArguments.iThreadIndex, r));
sl@0
  1260
				if (r != KErrNone)
sl@0
  1261
						return r;
sl@0
  1262
				}
sl@0
  1263
			}
sl@0
  1264
			
sl@0
  1265
		if (gTestWhichTests & TEST_CHUNK)
sl@0
  1266
			{
sl@0
  1267
			for (iterIndex = 0; iterIndex < gPerformTestLoop; iterIndex ++)
sl@0
  1268
				{
sl@0
  1269
				DEBUG_PRINT1((_L("%S : %d Iter %d Chunk\n"), &gTestNameBuffer, aTestArguments.iThreadIndex, iterIndex));
sl@0
  1270
				r = TestChunkPaging(aTestArguments);
sl@0
  1271
				DEBUG_PRINT1((_L("ThreadId %d Finished TestChunkPaging() r = %d\n"), aTestArguments.iThreadIndex, r));
sl@0
  1272
				if (r != KErrNone)
sl@0
  1273
						return r;
sl@0
  1274
				}
sl@0
  1275
			}
sl@0
  1276
sl@0
  1277
		if (gTestWhichTests & TEST_COMMIT)
sl@0
  1278
			{
sl@0
  1279
			for (iterIndex = 0; iterIndex < gPerformTestLoop; iterIndex ++)
sl@0
  1280
				{
sl@0
  1281
				DEBUG_PRINT1((_L("%S : %d Iter %d Commit\n"), &gTestNameBuffer, aTestArguments.iThreadIndex, iterIndex));
sl@0
  1282
				r = TestChunkCommit(aTestArguments);
sl@0
  1283
				DEBUG_PRINT1((_L("ThreadId %d Finished TestChunkCommit() r = %d\n"), aTestArguments.iThreadIndex, r));
sl@0
  1284
				if (r != KErrNone)
sl@0
  1285
					return r;
sl@0
  1286
				}
sl@0
  1287
			}
sl@0
  1288
sl@0
  1289
		if (gTestWhichTests & TEST_IPC)
sl@0
  1290
			{
sl@0
  1291
			// In multiple thread case limit IPC test to 2 loops else will take a long time
sl@0
  1292
			TInt loops = (gPerformTestLoop <= 2 && gNumTestThreads) ? gPerformTestLoop : 2;
sl@0
  1293
			for (iterIndex = 0; iterIndex < loops; iterIndex ++)
sl@0
  1294
				{
sl@0
  1295
				if (gTestBadServer)
sl@0
  1296
					{
sl@0
  1297
					r = TestIPCBadServer(aTestArguments);
sl@0
  1298
					DEBUG_PRINT1((_L("ThreadId %d Finished TestIPCBadServer() r = %d\n"), aTestArguments.iThreadIndex, r));
sl@0
  1299
					}
sl@0
  1300
				else
sl@0
  1301
					{
sl@0
  1302
					DEBUG_PRINT1((_L("%S : %d Iter %d IPC\n"), &gTestNameBuffer, aTestArguments.iThreadIndex, iterIndex));
sl@0
  1303
					r = TestIPCPinning(aTestArguments);
sl@0
  1304
					DEBUG_PRINT1((_L("ThreadId %d Finished TestIPCPinning() r = %d\n"), aTestArguments.iThreadIndex, r));
sl@0
  1305
					if (r != KErrNone)
sl@0
  1306
						return r;
sl@0
  1307
					}
sl@0
  1308
				}
sl@0
  1309
			}
sl@0
  1310
		}
sl@0
  1311
	
sl@0
  1312
	DEBUG_PRINT1((_L("%S : thread Exiting %d (tickcount %u)\n"), &gTestNameBuffer, aTestArguments.iThreadIndex, (User::TickCount() - start)));
sl@0
  1313
	return r;
sl@0
  1314
	}
sl@0
  1315
sl@0
  1316
sl@0
  1317
//
sl@0
  1318
// MultipleTestThread
sl@0
  1319
//
sl@0
  1320
// Thread function, one created for each thread in a multiple thread test.
sl@0
  1321
//
sl@0
  1322
sl@0
  1323
LOCAL_C TInt MultipleTestThread(TAny* aTestArgs)
sl@0
  1324
	{
sl@0
  1325
	TInt r = KErrNone;
sl@0
  1326
	TBuf<64>					localBuffer;
sl@0
  1327
sl@0
  1328
	if (gTestInterleave)	
sl@0
  1329
		{
sl@0
  1330
		RThread				thisThread;
sl@0
  1331
		thisThread.SetPriority((TThreadPriority) TEST_INTERLEAVE_PRIO);
sl@0
  1332
		}
sl@0
  1333
	
sl@0
  1334
	SPerformTestArgs& testArgs = *(SPerformTestArgs*)aTestArgs;
sl@0
  1335
	testArgs.iBuffer = &localBuffer;
sl@0
  1336
	
sl@0
  1337
	RDBGD_PRINT(("Performing test thread ThreadID(%d)\n", testArgs.iThreadIndex));
sl@0
  1338
	r = PerformTestThread(testArgs);
sl@0
  1339
	
sl@0
  1340
	return r;
sl@0
  1341
	}
sl@0
  1342
sl@0
  1343
sl@0
  1344
sl@0
  1345
//
sl@0
  1346
// FindMMCDriveNumber
sl@0
  1347
// 
sl@0
  1348
// Find the first read write drive.
sl@0
  1349
//
sl@0
  1350
sl@0
  1351
TInt FindMMCDriveNumber(RFs& aFs)
sl@0
  1352
	{
sl@0
  1353
	TDriveInfo driveInfo;
sl@0
  1354
	for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum)
sl@0
  1355
		{
sl@0
  1356
		TInt r = aFs.Drive(driveInfo, drvNum);
sl@0
  1357
		if (r >= 0)
sl@0
  1358
			{
sl@0
  1359
			if (driveInfo.iType == EMediaHardDisk)
sl@0
  1360
				return (drvNum);
sl@0
  1361
			}
sl@0
  1362
		}
sl@0
  1363
	return -1; 
sl@0
  1364
	}
sl@0
  1365
sl@0
  1366
//
sl@0
  1367
// PerformRomAndFileSystemAccess
sl@0
  1368
// 
sl@0
  1369
// Access the rom and dump it out to one of the writeable partitions...
sl@0
  1370
// really just to make the media server a little busy during the test.
sl@0
  1371
//
sl@0
  1372
sl@0
  1373
TInt PerformRomAndFileSystemAccessThread(SPerformTestArgs& aTestArguments)
sl@0
  1374
	{
sl@0
  1375
	TUint maxBytes = KMaxTUint;
sl@0
  1376
	TInt startTime = User::TickCount();
sl@0
  1377
sl@0
  1378
	RFs fs;
sl@0
  1379
	RFile file;
sl@0
  1380
	if (KErrNone != fs.Connect())
sl@0
  1381
		{
sl@0
  1382
		DEBUG_PRINT(_L("PerformRomAndFileSystemAccessThread : Can't connect to the FS\n"));
sl@0
  1383
		return KErrGeneral;
sl@0
  1384
		}
sl@0
  1385
sl@0
  1386
	// get info about the ROM...
sl@0
  1387
	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
sl@0
  1388
	TUint8* start;
sl@0
  1389
	TUint8* end;
sl@0
  1390
	if(romHeader->iPageableRomStart)
sl@0
  1391
		{
sl@0
  1392
		start = (TUint8*)romHeader + romHeader->iPageableRomStart;
sl@0
  1393
		end = start + romHeader->iPageableRomSize;
sl@0
  1394
		}
sl@0
  1395
	else
sl@0
  1396
		{
sl@0
  1397
		start = (TUint8*)romHeader;
sl@0
  1398
		end = start + romHeader->iUncompressedSize;
sl@0
  1399
		}
sl@0
  1400
	if (end <= start)
sl@0
  1401
		return KErrGeneral;
sl@0
  1402
sl@0
  1403
	// read all ROM pages in a random order...and write out to file in ROFs, 
sl@0
  1404
	TUint size = end - start - gPageSize;
sl@0
  1405
	if(size > maxBytes)
sl@0
  1406
		size = maxBytes;
sl@0
  1407
sl@0
  1408
	TUint32 random = 1;
sl@0
  1409
	TPtrC8 rom;
sl@0
  1410
	TUint8 *theAddr;
sl@0
  1411
sl@0
  1412
	//TInt		drvNum = TestBootedFromMmc ? FindMMCDriveNumber(fs) : FindFsNANDDrive(fs);
sl@0
  1413
	TInt drvNum = FindMMCDriveNumber(fs);
sl@0
  1414
	TBuf<32>	filename = _L("d:\\Pageldrtst.tmp");
sl@0
  1415
	if (drvNum >= 0)
sl@0
  1416
		{
sl@0
  1417
		filename[0] = (TUint16)('a' + drvNum);
sl@0
  1418
		DEBUG_PRINT1((_L("%S : Filename %S\n"), &gTestNameBuffer, &filename));
sl@0
  1419
		}
sl@0
  1420
	else
sl@0
  1421
		DEBUG_PRINT((_L("PerformRomAndFileSystemAccessThread : error getting drive num\n")));
sl@0
  1422
sl@0
  1423
	for(TInt i = (size >> gPageShift); i > 0; --i)
sl@0
  1424
		{
sl@0
  1425
		DEBUG_PRINT1((_L("%S : Opening the file\n"), &gTestNameBuffer));
sl@0
  1426
		if (KErrNone != file.Replace(fs, filename, EFileWrite))
sl@0
  1427
			{
sl@0
  1428
			DEBUG_PRINT1((_L("%S : Opening the file Failed!\n"), &gTestNameBuffer));
sl@0
  1429
			}
sl@0
  1430
sl@0
  1431
		random = random * 69069 + 1;
sl@0
  1432
		theAddr = (TUint8*)(start+((TInt64(random)*TInt64(size))>>32));
sl@0
  1433
		if (theAddr + gPageSize > end)
sl@0
  1434
			{
sl@0
  1435
			DEBUG_PRINT1((_L("%S : address is past the end 0x%x / 0x%x\n"), &gTestNameBuffer, (TInt)theAddr, (TInt)end));
sl@0
  1436
			}
sl@0
  1437
		rom.Set(theAddr,gPageSize);
sl@0
  1438
		DEBUG_PRINT1((_L("%S : Writing the file\n"), &gTestNameBuffer));
sl@0
  1439
		TInt ret = file.Write(rom);
sl@0
  1440
		if (ret != KErrNone)
sl@0
  1441
			{
sl@0
  1442
			DEBUG_PRINT1((_L("%S : Write returned error %d\n"), &gTestNameBuffer, ret));
sl@0
  1443
			}
sl@0
  1444
		DEBUG_PRINT1((_L("%S : Closing the file\n"), &gTestNameBuffer));
sl@0
  1445
		file.Close();
sl@0
  1446
sl@0
  1447
		DEBUG_PRINT1((_L("%S : Deleting the file\n"), &gTestNameBuffer));
sl@0
  1448
		ret = fs.Delete(filename);
sl@0
  1449
		if (KErrNone != ret)
sl@0
  1450
			{
sl@0
  1451
			DEBUG_PRINT1((_L("%S : Delete returned error %d\n"), &gTestNameBuffer, ret));
sl@0
  1452
			}
sl@0
  1453
		if (gTestStopMedia)
sl@0
  1454
			break;
sl@0
  1455
		}
sl@0
  1456
	fs.Close();
sl@0
  1457
	DEBUG_PRINT1((_L("Done in %d ticks\n"), User::TickCount() - startTime));
sl@0
  1458
	return KErrNone;
sl@0
  1459
	}
sl@0
  1460
sl@0
  1461
sl@0
  1462
//
sl@0
  1463
// PerformRomAndFileSystemAccess
sl@0
  1464
//
sl@0
  1465
// Thread function, kicks off the file system access.
sl@0
  1466
//
sl@0
  1467
sl@0
  1468
LOCAL_C TInt PerformRomAndFileSystemAccess(TAny* aTestArgs)
sl@0
  1469
	{
sl@0
  1470
	TBuf<64>					localBuffer;
sl@0
  1471
	
sl@0
  1472
	SPerformTestArgs& testArgs = *(SPerformTestArgs*)aTestArgs;
sl@0
  1473
	testArgs.iBuffer = &localBuffer;
sl@0
  1474
	
sl@0
  1475
	PerformRomAndFileSystemAccessThread(testArgs);
sl@0
  1476
	
sl@0
  1477
	return KErrNone;
sl@0
  1478
	}
sl@0
  1479
sl@0
  1480
sl@0
  1481
sl@0
  1482
sl@0
  1483
//
sl@0
  1484
// StartFlushing
sl@0
  1485
//
sl@0
  1486
// Create a thread that will continuously flush the paging cache
sl@0
  1487
//
sl@0
  1488
void StartFlushing(TRequestStatus &aStatus, RThread &aFlushThread, TBool aLowMem = EFalse)
sl@0
  1489
	{
sl@0
  1490
	TInt ret;
sl@0
  1491
	gTestRunning = ETrue;
sl@0
  1492
sl@0
  1493
	TThreadCreateInfo flushThreadInfo(_L("FlushThread"), FlushFunc, KDefaultStackSize,NULL);
sl@0
  1494
	flushThreadInfo.SetCreateHeap(KMinHeapSize, KMinHeapSize);
sl@0
  1495
	
sl@0
  1496
	if (!aLowMem)
sl@0
  1497
		{
sl@0
  1498
		test_KErrNone(aFlushThread.Create(flushThreadInfo));
sl@0
  1499
		}
sl@0
  1500
	else
sl@0
  1501
		{
sl@0
  1502
		DOTEST((ret = aFlushThread.Create(flushThreadInfo)), (ret != KErrNoMemory));
sl@0
  1503
		test_KErrNone(ret);
sl@0
  1504
		}
sl@0
  1505
	
sl@0
  1506
	
sl@0
  1507
	aFlushThread.Logon(aStatus);
sl@0
  1508
	
sl@0
  1509
	aFlushThread.Resume();
sl@0
  1510
	}
sl@0
  1511
sl@0
  1512
//
sl@0
  1513
// FinishFlushing
sl@0
  1514
//
sl@0
  1515
// Close the thread flushing the paging cache
sl@0
  1516
//
sl@0
  1517
void FinishFlushing(TRequestStatus &aStatus, RThread &aFlushThread)
sl@0
  1518
	{
sl@0
  1519
	gTestRunning = EFalse;
sl@0
  1520
	User::WaitForRequest(aStatus);
sl@0
  1521
	// TO DO: Check Exit tyoe
sl@0
  1522
	CLOSE_AND_WAIT(aFlushThread);
sl@0
  1523
	}
sl@0
  1524
sl@0
  1525
sl@0
  1526
//
sl@0
  1527
// ResetResults
sl@0
  1528
// 
sl@0
  1529
// Clear the previous results from the results array
sl@0
  1530
//
sl@0
  1531
TInt ResetResults()
sl@0
  1532
	{
sl@0
  1533
	for (TUint i = 0; i < KMaxTestThreads; i++)
sl@0
  1534
		{
sl@0
  1535
		gResultsArray[i].iExitType = KExitTypeReset;
sl@0
  1536
		gResultsArray[i].iExitReason = KErrNone;
sl@0
  1537
		}
sl@0
  1538
	return KErrNone;
sl@0
  1539
	}
sl@0
  1540
sl@0
  1541
sl@0
  1542
//
sl@0
  1543
// CheckResults
sl@0
  1544
//
sl@0
  1545
// Check that the results are as expected
sl@0
  1546
//
sl@0
  1547
TInt CheckResults()
sl@0
  1548
	{
sl@0
  1549
	TUint i;
sl@0
  1550
	for (i = 0; i < KMaxTestThreads; i++)
sl@0
  1551
		{
sl@0
  1552
		if (gResultsArray[i].iExitType == KExitTypeReset)
sl@0
  1553
			continue;
sl@0
  1554
		RDBGD_PRINT(("%S : Thread %d ExitType(%d) ExitReason(%d)...\n", 
sl@0
  1555
					&gTestNameBuffer, i, gResultsArray[i].iExitType, gResultsArray[i].iExitReason));
sl@0
  1556
		}
sl@0
  1557
	
sl@0
  1558
	for (i = 0; i < KMaxTestThreads; i++)
sl@0
  1559
		{
sl@0
  1560
		if (gResultsArray[i].iExitType == KExitTypeReset)
sl@0
  1561
			continue;
sl@0
  1562
		
sl@0
  1563
		if (gResultsArray[i].iExitType != EExitKill)
sl@0
  1564
			{
sl@0
  1565
			RDBGS_PRINT(("Thread %d ExitType(%d) Expected(%d)\n", i, gResultsArray[i].iExitType, EExitKill));
sl@0
  1566
			return KErrGeneral;
sl@0
  1567
			}
sl@0
  1568
		
sl@0
  1569
		// Allow for No Memory as we can run out of memory due to high number of threads and
sl@0
  1570
		// Overflow as the number of chunks that can be created on moving memory model is capped
sl@0
  1571
		if (gResultsArray[i].iExitReason != KErrNone &&
sl@0
  1572
			gResultsArray[i].iExitReason != KErrNoMemory &&
sl@0
  1573
			gResultsArray[i].iExitReason != KErrOverflow)
sl@0
  1574
			{
sl@0
  1575
			RDBGS_PRINT(("Thread %d ExitReason(%d) Expected either %d, %d or %d\n", 
sl@0
  1576
							i, gResultsArray[i].iExitReason, KErrNone, KErrNoMemory, KErrOverflow));
sl@0
  1577
			return KErrGeneral;
sl@0
  1578
			}
sl@0
  1579
		}
sl@0
  1580
	return KErrNone;
sl@0
  1581
	}
sl@0
  1582
sl@0
  1583
sl@0
  1584
//
sl@0
  1585
// PrintOptions
sl@0
  1586
//
sl@0
  1587
// Print out the options of the test
sl@0
  1588
//
sl@0
  1589
void PrintOptions()
sl@0
  1590
	{
sl@0
  1591
	SVMCacheInfo  tempPages;
sl@0
  1592
	if (gIsDemandPaged)
sl@0
  1593
		{
sl@0
  1594
		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
sl@0
  1595
		test.Printf(_L("PerformAutoTest : Start cache info: iMinSize 0x%x iMaxSize 0x%x iCurrentSize 0x%x iMaxFreeSize 0x%x\n"),
sl@0
  1596
					 tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize ,tempPages.iMaxFreeSize);
sl@0
  1597
		}
sl@0
  1598
	
sl@0
  1599
	test.Printf(_L("Loops (%d), Threads (%d), Tests: "), gPerformTestLoop, gNumTestThreads);
sl@0
  1600
	if (TEST_ALL == (gTestWhichTests & TEST_ALL))
sl@0
  1601
		{
sl@0
  1602
		test.Printf(_L("All, "));
sl@0
  1603
		}
sl@0
  1604
	else if (gTestWhichTests & TEST_STACK)
sl@0
  1605
		{
sl@0
  1606
		test.Printf(_L("Stack, "));
sl@0
  1607
		}
sl@0
  1608
	else if (gTestWhichTests & TEST_CHUNK)
sl@0
  1609
		{
sl@0
  1610
		test.Printf(_L("Chunk, "));
sl@0
  1611
		}
sl@0
  1612
	else if (gTestWhichTests & TEST_COMMIT)
sl@0
  1613
		{
sl@0
  1614
		test.Printf(_L("Commit, "));
sl@0
  1615
		}
sl@0
  1616
	else if (gTestWhichTests & TEST_IPC)
sl@0
  1617
		{
sl@0
  1618
		test.Printf(_L("IPC Pinning, "));
sl@0
  1619
		}
sl@0
  1620
	else
sl@0
  1621
		{
sl@0
  1622
		test.Printf(_L("?, "));
sl@0
  1623
		}
sl@0
  1624
	test.Printf(_L("\nOptions: "));
sl@0
  1625
sl@0
  1626
	if(gTestInterleave)
sl@0
  1627
		test.Printf(_L("Interleave "));
sl@0
  1628
	if(gTestPrioChange)
sl@0
  1629
		test.Printf(_L("Priority "));
sl@0
  1630
	if(gTestMediaAccess)
sl@0
  1631
		test.Printf(_L("Media"));
sl@0
  1632
	if(gTestBadServer)
sl@0
  1633
		test.Printf(_L("BadServer"));
sl@0
  1634
	test.Printf(_L("\n"));
sl@0
  1635
	}
sl@0
  1636
sl@0
  1637
// DoMultipleTest
sl@0
  1638
// 
sl@0
  1639
// Perform the multiple thread test, spawning a number of threads.
sl@0
  1640
// It is complicated a little because test.Printf can only be called from the first thread that calls it 
sl@0
  1641
// so if we are using multiple threads we need to use a message queue to pass the debug info from the
sl@0
  1642
// child threads back to the parent for the parent to then call printf.
sl@0
  1643
//
sl@0
  1644
TInt DoMultipleTest(TBool aLowMem = EFalse)
sl@0
  1645
	{
sl@0
  1646
	SVMCacheInfo  tempPages;
sl@0
  1647
	memset(&tempPages, 0, sizeof(tempPages));
sl@0
  1648
sl@0
  1649
	if (gIsDemandPaged)
sl@0
  1650
		{
sl@0
  1651
		// get the old cache info
sl@0
  1652
		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
sl@0
  1653
		// set the cache to our test value
sl@0
  1654
		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)tempPages.iMinSize,(TAny*)(tempPages.iMaxSize * gNumTestThreads));
sl@0
  1655
		}
sl@0
  1656
	
sl@0
  1657
	if (!TestSilent)
sl@0
  1658
		PrintOptions();
sl@0
  1659
sl@0
  1660
	TUint startTime = User::TickCount();
sl@0
  1661
	TInt			 index;
sl@0
  1662
	TInt ret = KErrNone;
sl@0
  1663
	TBuf<16> multiThreadName;
sl@0
  1664
	TBuf<16> rerunThreadName;
sl@0
  1665
	
sl@0
  1666
	ResetResults();
sl@0
  1667
	
sl@0
  1668
	TRequestStatus flushStatus;
sl@0
  1669
	RThread flushThread;
sl@0
  1670
	StartFlushing(flushStatus, flushThread, aLowMem);
sl@0
  1671
sl@0
  1672
	DOTEST((gThreadHeap = User::ChunkHeap(NULL, 0x1000, 0x1000)), (gThreadHeap != NULL));
sl@0
  1673
	test_NotNull(gThreadHeap);
sl@0
  1674
	
sl@0
  1675
	DOTEST((gStackHeap = User::ChunkHeap(NULL, 0x1000, 0x1000)), (gStackHeap != NULL));
sl@0
  1676
	test_NotNull(gStackHeap);
sl@0
  1677
sl@0
  1678
	TThreadCreateInfo	*pThreadCreateInfo = (TThreadCreateInfo *)User::AllocZ(sizeof(TThreadCreateInfo) * gNumTestThreads);
sl@0
  1679
	RThread				*pTheThreads  = (RThread *)User::AllocZ(sizeof(RThread) * gNumTestThreads);
sl@0
  1680
	TInt				*pThreadInUse = (TInt *)User::AllocZ(sizeof(TInt) * gNumTestThreads);
sl@0
  1681
sl@0
  1682
	TRequestStatus	mediaStatus;
sl@0
  1683
	RThread			mediaThread;
sl@0
  1684
	
sl@0
  1685
	
sl@0
  1686
	DOTEST((ret = TestMsgQueue.CreateLocal(gNumTestThreads * 10, EOwnerProcess)),
sl@0
  1687
	       (KErrNone == ret));
sl@0
  1688
sl@0
  1689
	DOTEST((ret = TestMultiSem.CreateLocal(1)),
sl@0
  1690
	       (KErrNone == ret));
sl@0
  1691
sl@0
  1692
	// make sure we have a priority higher than that of the threads we spawn...
sl@0
  1693
	RThread thisThread;
sl@0
  1694
	TThreadPriority savedThreadPriority = thisThread.Priority();
sl@0
  1695
	const TThreadPriority KMainThreadPriority = EPriorityMuchMore;
sl@0
  1696
	__ASSERT_COMPILE(KMainThreadPriority>TEST_INTERLEAVE_PRIO);
sl@0
  1697
	thisThread.SetPriority(KMainThreadPriority);
sl@0
  1698
sl@0
  1699
	SPerformTestArgs mediaArgs;
sl@0
  1700
	mediaArgs.iMsgQueue = &TestMsgQueue; 
sl@0
  1701
	mediaArgs.iTheSem = &TestMultiSem;
sl@0
  1702
	mediaArgs.iLowMem = aLowMem;
sl@0
  1703
	
sl@0
  1704
	if (gTestMediaAccess)
sl@0
  1705
		{
sl@0
  1706
		TThreadCreateInfo mediaInfo(_L(""),PerformRomAndFileSystemAccess,KDefaultStackSize,(TAny*)&mediaArgs);
sl@0
  1707
		mediaInfo.SetUseHeap(NULL);
sl@0
  1708
		mediaInfo.SetPaging(TThreadCreateInfo::EPaged);
sl@0
  1709
		gTestStopMedia = EFalse;
sl@0
  1710
		ret = mediaThread.Create(mediaInfo);
sl@0
  1711
		if (ret != KErrNone)
sl@0
  1712
			return ret;
sl@0
  1713
		mediaThread.Logon(mediaStatus);
sl@0
  1714
		RUNTEST1(mediaStatus == KRequestPending);
sl@0
  1715
		mediaThread.Resume();
sl@0
  1716
		}
sl@0
  1717
sl@0
  1718
	TThreadCreateInfo** infoPtrs = new TThreadCreateInfo*[gNumTestThreads]; 
sl@0
  1719
	if (infoPtrs == NULL)
sl@0
  1720
		return KErrNoMemory;
sl@0
  1721
	
sl@0
  1722
	SPerformTestArgs *testArgs = new SPerformTestArgs[gNumTestThreads];
sl@0
  1723
	if (testArgs == NULL)
sl@0
  1724
		return KErrNoMemory;
sl@0
  1725
sl@0
  1726
	Mem::FillZ(testArgs, gNumTestThreads * sizeof(SPerformTestArgs));
sl@0
  1727
sl@0
  1728
	for (index = 0; index < gNumTestThreads; index++)
sl@0
  1729
		{
sl@0
  1730
		RDBGD_PRINT(("%S : Starting thread.%d!\n", &gTestNameBuffer, index));
sl@0
  1731
		multiThreadName = _L("TestThread_");
sl@0
  1732
		multiThreadName.AppendNum(index);
sl@0
  1733
sl@0
  1734
		testArgs[index].iThreadIndex = index;
sl@0
  1735
		testArgs[index].iMsgQueue = &TestMsgQueue; 
sl@0
  1736
		testArgs[index].iTheSem = &TestMultiSem;
sl@0
  1737
		testArgs[index].iLowMem = aLowMem;
sl@0
  1738
sl@0
  1739
		RDBGD_PRINT(("Creating thread.%d!\n", index));
sl@0
  1740
		infoPtrs[index] = new TThreadCreateInfo(multiThreadName, MultipleTestThread, KDefaultStackSize, (TAny*)&testArgs[index]);
sl@0
  1741
		if (infoPtrs[index] == NULL)
sl@0
  1742
			continue;
sl@0
  1743
		infoPtrs[index]->SetCreateHeap(KMinHeapSize, KMinHeapSize);
sl@0
  1744
		infoPtrs[index]->SetPaging(TThreadCreateInfo::EPaged);
sl@0
  1745
		//infoPtrs[index]->SetUseHeap(gThreadHeap);
sl@0
  1746
		DOTEST((ret = pTheThreads[index].Create(*infoPtrs[index])), (ret != KErrNoMemory));
sl@0
  1747
		if (ret != KErrNone)
sl@0
  1748
			continue;
sl@0
  1749
		pTheThreads[index].Resume();
sl@0
  1750
		pThreadInUse[index] = 1;
sl@0
  1751
		}
sl@0
  1752
	
sl@0
  1753
	// now process any messages sent from the child threads.
sl@0
  1754
	TBool		anyUsed = ETrue;
sl@0
  1755
	TBuf<64>	localBuffer;
sl@0
  1756
	while(anyUsed)
sl@0
  1757
		{
sl@0
  1758
		anyUsed = EFalse;
sl@0
  1759
		// check the message queue and call printf if we get a message.
sl@0
  1760
		while (KErrNone == TestMsgQueue.Receive(localBuffer))
sl@0
  1761
			{
sl@0
  1762
			if (!TestSilent)
sl@0
  1763
				test.Printf(localBuffer);
sl@0
  1764
			}
sl@0
  1765
sl@0
  1766
		// walk through the thread list to check which are still alive.
sl@0
  1767
		for (index = 0; index < gNumTestThreads; index++)
sl@0
  1768
			{
sl@0
  1769
			if (pThreadInUse[index])
sl@0
  1770
				{
sl@0
  1771
				if (pTheThreads[index].ExitType() != EExitPending)
sl@0
  1772
					{
sl@0
  1773
					if (aLowMem &&
sl@0
  1774
						pTheThreads[index].ExitType() == EExitKill &&
sl@0
  1775
						pTheThreads[index].ExitReason() == KErrNoMemory &&
sl@0
  1776
						Ldd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE) == KErrNone)
sl@0
  1777
						{// If thread was killed with no memory in a low mem scenario
sl@0
  1778
						// then release some RAM and restart the thread again
sl@0
  1779
						anyUsed = ETrue;
sl@0
  1780
						RDBGD_PRINT(("Thread index %d EExitKill KErrNoMemory\n", index));
sl@0
  1781
						CLOSE_AND_WAIT(pTheThreads[index]);
sl@0
  1782
sl@0
  1783
						RDBGD_PRINT(("Re-running Thread index %d\n", index));
sl@0
  1784
						rerunThreadName = _L("RRTestThread_");
sl@0
  1785
						rerunThreadName.AppendNum(index);
sl@0
  1786
						
sl@0
  1787
						delete infoPtrs[index];				
sl@0
  1788
						infoPtrs[index] = new TThreadCreateInfo(rerunThreadName, MultipleTestThread, KDefaultStackSize, (TAny*)&testArgs[index]);
sl@0
  1789
						if (infoPtrs[index] == NULL)
sl@0
  1790
							continue;
sl@0
  1791
						infoPtrs[index]->SetCreateHeap(KMinHeapSize, KMinHeapSize);
sl@0
  1792
						infoPtrs[index]->SetPaging(TThreadCreateInfo::EPaged);
sl@0
  1793
						//infoPtrs[index]->SetUseHeap(gThreadHeap);
sl@0
  1794
						ret = pTheThreads[index].Create(*infoPtrs[index]);
sl@0
  1795
						if (ret != KErrNone)
sl@0
  1796
							continue;
sl@0
  1797
						pTheThreads[index].Resume();
sl@0
  1798
						pThreadInUse[index] = 1;
sl@0
  1799
						continue;
sl@0
  1800
						}
sl@0
  1801
					if (pTheThreads[index].ExitType() == EExitPanic)
sl@0
  1802
						{
sl@0
  1803
						RDBGD_PRINT(("%S : Thread Panic'd  %d...\n", &gTestNameBuffer, index));	
sl@0
  1804
						}
sl@0
  1805
					
sl@0
  1806
					//Store the results but let all the threads finish
sl@0
  1807
					gResultsArray[index].iExitType = pTheThreads[index].ExitType();
sl@0
  1808
					gResultsArray[index].iExitReason = pTheThreads[index].ExitReason();
sl@0
  1809
					
sl@0
  1810
					pThreadInUse[index] = EFalse;
sl@0
  1811
					pTheThreads[index].Close();
sl@0
  1812
					}
sl@0
  1813
				else
sl@0
  1814
					{
sl@0
  1815
					anyUsed = ETrue;
sl@0
  1816
					}
sl@0
  1817
				}
sl@0
  1818
			}
sl@0
  1819
sl@0
  1820
		User::AfterHighRes(50000);
sl@0
  1821
		}
sl@0
  1822
sl@0
  1823
	if (gTestMediaAccess)
sl@0
  1824
		{
sl@0
  1825
		gTestStopMedia = ETrue;
sl@0
  1826
		RDBGD_PRINT(("%S : Waiting for media thread to exit...\n", &gTestNameBuffer));	
sl@0
  1827
		User::WaitForRequest(mediaStatus);
sl@0
  1828
		mediaThread.Close();
sl@0
  1829
		}
sl@0
  1830
sl@0
  1831
	TestMsgQueue.Close();
sl@0
  1832
	TestMultiSem.Close();
sl@0
  1833
sl@0
  1834
	// cleanup the resources and exit.
sl@0
  1835
	User::Free(pTheThreads);
sl@0
  1836
	User::Free(pThreadInUse);
sl@0
  1837
	User::Free(pThreadCreateInfo);
sl@0
  1838
	delete infoPtrs;
sl@0
  1839
	delete testArgs;
sl@0
  1840
sl@0
  1841
sl@0
  1842
	FinishFlushing(flushStatus, flushThread);
sl@0
  1843
	gThreadHeap->Close();
sl@0
  1844
	gStackHeap->Close();
sl@0
  1845
	thisThread.SetPriority(savedThreadPriority);
sl@0
  1846
	ret = CheckResults();
sl@0
  1847
	RDBGS_PRINT(("Test Complete (%u ticks)\n", User::TickCount() - startTime));
sl@0
  1848
	
sl@0
  1849
	if (gIsDemandPaged)
sl@0
  1850
		{
sl@0
  1851
		// put the cache back to the the original values.
sl@0
  1852
		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)tempPages.iMinSize,(TAny*)tempPages.iMaxSize);
sl@0
  1853
		}
sl@0
  1854
	return ret;
sl@0
  1855
	}
sl@0
  1856
sl@0
  1857
sl@0
  1858
//
sl@0
  1859
// DoSingleTest
sl@0
  1860
// 
sl@0
  1861
// Perform the single thread test,.
sl@0
  1862
//
sl@0
  1863
sl@0
  1864
LOCAL_C TInt DoSingleTest(TBool aLowMem = EFalse)
sl@0
  1865
	{
sl@0
  1866
	TUint origThreadCount = gNumTestThreads;
sl@0
  1867
	gNumTestThreads = 1;
sl@0
  1868
	TInt r = DoMultipleTest(aLowMem);
sl@0
  1869
	gNumTestThreads = origThreadCount;
sl@0
  1870
	return r;
sl@0
  1871
	}
sl@0
  1872
sl@0
  1873
sl@0
  1874
sl@0
  1875
//
sl@0
  1876
// ParseCommandLine 
sl@0
  1877
//
sl@0
  1878
// read the arguments passed from the command line and set global variables to 
sl@0
  1879
// control the tests.
sl@0
  1880
//
sl@0
  1881
sl@0
  1882
TBool ParseCommandLine()
sl@0
  1883
	{
sl@0
  1884
	TBuf<256> args;
sl@0
  1885
	User::CommandLine(args);
sl@0
  1886
	TLex	lex(args);
sl@0
  1887
	TBool	retVal = ETrue;
sl@0
  1888
	
sl@0
  1889
	// initially test for arguments, the parse them, if not apply some sensible defaults.
sl@0
  1890
	TBool	foundArgs = EFalse;	
sl@0
  1891
	
sl@0
  1892
	FOREVER
sl@0
  1893
		{
sl@0
  1894
		TPtrC  token=lex.NextToken();
sl@0
  1895
		if(token.Length()!=0)
sl@0
  1896
			{
sl@0
  1897
			if ((token == _L("help")) || (token == _L("-h")) || (token == _L("-?")))
sl@0
  1898
				{
sl@0
  1899
				RDBGS_PRINT(("\nUsage:  %S n", &gTestNameBuffer));
sl@0
  1900
				RDBGS_PRINT(("\ndebug: Prints out tracing in the test"));
sl@0
  1901
				RDBGS_PRINT(("\n[single | multiple <numThreads>] : Specify to run in a single thread or multiple threads and how many"));
sl@0
  1902
				RDBGS_PRINT(("\n[ipc | stack | chunk| commit| all | badserver] : which type of test to run "));
sl@0
  1903
				RDBGS_PRINT(("\n-> ipc: IPC Pinning tests"));
sl@0
  1904
				RDBGS_PRINT(("\n-> stack: Stack paging tests"));
sl@0
  1905
				RDBGS_PRINT(("\n-> chunk: Chunk paging tests"));
sl@0
  1906
				RDBGS_PRINT(("\n-> commit: Chunk committing tests"));
sl@0
  1907
				RDBGS_PRINT(("\n-> all: All the above tests"));
sl@0
  1908
				RDBGS_PRINT(("\n-> badserver: IPC Pinning tests with a dead server"));
sl@0
  1909
				RDBGS_PRINT(("\n[iters <iters>] : Number of loops each test should perform"));
sl@0
  1910
				RDBGS_PRINT(("\n[media] : Perform multiple test with media activity in the background"));
sl@0
  1911
				RDBGS_PRINT(("\n[lowmem] : Perform testing in low memory situations "));
sl@0
  1912
				RDBGS_PRINT(("\n[interleave]: Perform test with thread interleaving\n\n"));
sl@0
  1913
				test.Getch();
sl@0
  1914
				TestExit = ETrue;
sl@0
  1915
				break;
sl@0
  1916
				}
sl@0
  1917
			else if (token == _L("debug"))
sl@0
  1918
				{
sl@0
  1919
				if (!TestSilent)
sl@0
  1920
					{
sl@0
  1921
					TestDebug = ETrue;
sl@0
  1922
					gTestPrioChange = ETrue;
sl@0
  1923
					}
sl@0
  1924
				}
sl@0
  1925
			else if (token == _L("silent"))
sl@0
  1926
				{
sl@0
  1927
				TestSilent = ETrue;
sl@0
  1928
				TestDebug = EFalse;
sl@0
  1929
				}
sl@0
  1930
			else if (token == _L("single"))
sl@0
  1931
				{
sl@0
  1932
				gTestType = ETestSingle;
sl@0
  1933
				}
sl@0
  1934
			else if (token == _L("multiple"))
sl@0
  1935
				{
sl@0
  1936
				TPtrC val=lex.NextToken();
sl@0
  1937
				TLex lexv(val);
sl@0
  1938
				TInt value;
sl@0
  1939
sl@0
  1940
				if (lexv.Val(value) == KErrNone)
sl@0
  1941
					{
sl@0
  1942
					if ((value <= 0) || (value > (TInt)KMaxTestThreads))
sl@0
  1943
						{
sl@0
  1944
						gNumTestThreads = KMaxTestThreads;
sl@0
  1945
						}
sl@0
  1946
					else
sl@0
  1947
						{
sl@0
  1948
						gNumTestThreads = value;
sl@0
  1949
						}
sl@0
  1950
					}
sl@0
  1951
				else
sl@0
  1952
					{
sl@0
  1953
					RDBGS_PRINT(("Bad value for thread count '%S' was ignored.\n", &val));
sl@0
  1954
					}
sl@0
  1955
				gTestType = ETestMultiple;
sl@0
  1956
				}
sl@0
  1957
			else if (token == _L("prio"))
sl@0
  1958
				{
sl@0
  1959
				gTestPrioChange = !gTestPrioChange;
sl@0
  1960
				}
sl@0
  1961
			else if (token == _L("lowmem"))
sl@0
  1962
				{
sl@0
  1963
				gTestType = ETestLowMem;
sl@0
  1964
				}
sl@0
  1965
			else if (token == _L("media"))
sl@0
  1966
				{
sl@0
  1967
				gTestType = ETestMedia;
sl@0
  1968
				}
sl@0
  1969
			else if (token == _L("stack"))
sl@0
  1970
				{
sl@0
  1971
				gSetTests = TEST_STACK;
sl@0
  1972
				}
sl@0
  1973
			else if (token == _L("chunk"))
sl@0
  1974
				{
sl@0
  1975
				gSetTests = TEST_CHUNK;
sl@0
  1976
				}
sl@0
  1977
			else if (token == _L("commit"))
sl@0
  1978
				{
sl@0
  1979
				gTestType = ETestCommit;
sl@0
  1980
				gSetTests = TEST_COMMIT;
sl@0
  1981
				}
sl@0
  1982
			else if (token == _L("ipc"))
sl@0
  1983
				{
sl@0
  1984
				gSetTests = TEST_IPC;
sl@0
  1985
				}
sl@0
  1986
			else if (token == _L("badserver"))
sl@0
  1987
				{
sl@0
  1988
				gTestType = ETestBadServer;
sl@0
  1989
				}
sl@0
  1990
			else if (token == _L("all"))
sl@0
  1991
				{
sl@0
  1992
				gSetTests = TEST_ALL;
sl@0
  1993
				}
sl@0
  1994
			else  if (token == _L("iters"))
sl@0
  1995
				{
sl@0
  1996
				TPtrC val=lex.NextToken();
sl@0
  1997
				TLex lexv(val);
sl@0
  1998
				TInt value;
sl@0
  1999
sl@0
  2000
				if (lexv.Val(value) == KErrNone)
sl@0
  2001
					{
sl@0
  2002
					gPerformTestLoop = value;
sl@0
  2003
					}
sl@0
  2004
				else
sl@0
  2005
					{
sl@0
  2006
					RDBGS_PRINT(("Bad value for loop count '%S' was ignored.\n", &val));
sl@0
  2007
					retVal = EFalse;
sl@0
  2008
					break;
sl@0
  2009
					}
sl@0
  2010
				}
sl@0
  2011
			else  if (token == _L("interleave"))
sl@0
  2012
				{
sl@0
  2013
				gTestType = ETestInterleave;
sl@0
  2014
				}
sl@0
  2015
			else
sl@0
  2016
				{
sl@0
  2017
				if ((foundArgs == EFalse) && (token.Length() == 1))
sl@0
  2018
					{
sl@0
  2019
					// Single letter argument...only run on 'd'
sl@0
  2020
					if (token.CompareF(_L("d")) == 0)
sl@0
  2021
						{
sl@0
  2022
						break;
sl@0
  2023
						}
sl@0
  2024
					else
sl@0
  2025
						{
sl@0
  2026
						if (!TestSilent)
sl@0
  2027
							{
sl@0
  2028
							test.Title();
sl@0
  2029
							test.Start(_L("Skipping non drive 'd' - Test Exiting."));
sl@0
  2030
							test.End();
sl@0
  2031
							}
sl@0
  2032
						foundArgs = ETrue;
sl@0
  2033
						TestExit = ETrue;
sl@0
  2034
						break;
sl@0
  2035
						}
sl@0
  2036
					}
sl@0
  2037
				RDBGS_PRINT(("Unknown argument '%S' was ignored.\n", &token));
sl@0
  2038
				break;
sl@0
  2039
				}
sl@0
  2040
			foundArgs = ETrue;
sl@0
  2041
			}
sl@0
  2042
		else
sl@0
  2043
			{
sl@0
  2044
			break;
sl@0
  2045
			}
sl@0
  2046
		}
sl@0
  2047
	if (!foundArgs)
sl@0
  2048
		{
sl@0
  2049
		retVal = EFalse;
sl@0
  2050
		}
sl@0
  2051
	return retVal;
sl@0
  2052
	}
sl@0
  2053
sl@0
  2054
//
sl@0
  2055
// AreWeTheTestBase
sl@0
  2056
//
sl@0
  2057
// Test whether we are the root of the tests.
sl@0
  2058
//
sl@0
  2059
sl@0
  2060
void AreWeTheTestBase(void)
sl@0
  2061
	{
sl@0
  2062
	if (!TestSilent)
sl@0
  2063
		{
sl@0
  2064
		TFileName  filename(RProcess().FileName());
sl@0
  2065
sl@0
  2066
		TParse	myParse;
sl@0
  2067
		myParse.Set(filename, NULL, NULL);
sl@0
  2068
		gTestNameBuffer.Zero();
sl@0
  2069
		gTestNameBuffer.Append(myParse.Name());
sl@0
  2070
		gTestNameBuffer.Append(_L(".exe"));
sl@0
  2071
sl@0
  2072
		TestWeAreTheTestBase = !gTestNameBuffer.Compare(_L("t_wdpstress.exe"));
sl@0
  2073
sl@0
  2074
		}
sl@0
  2075
	else
sl@0
  2076
		{
sl@0
  2077
		gTestNameBuffer.Zero();
sl@0
  2078
		gTestNameBuffer.Append(_L("t_wdpstress.exe"));
sl@0
  2079
		}
sl@0
  2080
	}
sl@0
  2081
sl@0
  2082
//
sl@0
  2083
// PerformAutoTest
sl@0
  2084
//
sl@0
  2085
// Perform the autotest
sl@0
  2086
//
sl@0
  2087
TInt PerformAutoTest()
sl@0
  2088
	{
sl@0
  2089
	TInt r = KErrNone;
sl@0
  2090
sl@0
  2091
	// Run all the different types of test
sl@0
  2092
	for (TUint testType = 0; testType < ETestTypes; testType++)
sl@0
  2093
		{
sl@0
  2094
		r = DoTest(testType);
sl@0
  2095
		if (r != KErrNone)
sl@0
  2096
			return r;
sl@0
  2097
		}
sl@0
  2098
sl@0
  2099
	return r;
sl@0
  2100
	}
sl@0
  2101
sl@0
  2102
//
sl@0
  2103
// DoLowMemTest
sl@0
  2104
//
sl@0
  2105
// Low Memory Test
sl@0
  2106
//
sl@0
  2107
sl@0
  2108
TInt DoLowMemTest()
sl@0
  2109
	{
sl@0
  2110
	TInt r = User::LoadLogicalDevice(KPageStressTestLddName);
sl@0
  2111
	RUNTEST1(r==KErrNone || r==KErrAlreadyExists);
sl@0
  2112
	RUNTEST(Ldd.Open(),KErrNone);
sl@0
  2113
	
sl@0
  2114
	SVMCacheInfo  tempPages;
sl@0
  2115
	memset(&tempPages, 0, sizeof(tempPages));
sl@0
  2116
sl@0
  2117
	if (gIsDemandPaged)
sl@0
  2118
		{
sl@0
  2119
		// get the old cache info
sl@0
  2120
		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
sl@0
  2121
		TInt	minSize = 8 << gPageShift;
sl@0
  2122
		TInt	maxSize = 256 << gPageShift;
sl@0
  2123
		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
sl@0
  2124
		}
sl@0
  2125
sl@0
  2126
sl@0
  2127
	// First load some pages onto the page cache 
sl@0
  2128
	gPerformTestLoop = 1;
sl@0
  2129
	r = DoTest(ETestSingle);
sl@0
  2130
	test_KErrNone(r);
sl@0
  2131
sl@0
  2132
sl@0
  2133
	Ldd.DoConsumeRamSetup(TEST_LM_NUM_FREE, TEST_LM_BLOCKSIZE);
sl@0
  2134
	TEST_NEXT((_L("Single thread with Low memory.")));
sl@0
  2135
	gNumTestThreads	= KMaxTestThreads / 2;
sl@0
  2136
	gPerformTestLoop = 20;
sl@0
  2137
sl@0
  2138
	r = DoTest(ETestSingle, ETrue);
sl@0
  2139
	Ldd.DoConsumeRamFinish();
sl@0
  2140
	test_KErrNone(r);
sl@0
  2141
sl@0
  2142
	TEST_NEXT((_L("Multiple thread with Low memory.")));
sl@0
  2143
	// First load some pages onto the page cache 
sl@0
  2144
	gPerformTestLoop = 1;
sl@0
  2145
	r = DoTest(ETestSingle);
sl@0
  2146
	test_KErrNone(r);
sl@0
  2147
sl@0
  2148
	Ldd.DoConsumeRamSetup(TEST_LM_NUM_FREE, TEST_LM_BLOCKSIZE);
sl@0
  2149
	
sl@0
  2150
	gPerformTestLoop = 10;
sl@0
  2151
	gNumTestThreads	= KMaxTestThreads / 2;
sl@0
  2152
	r = DoTest(ETestMultiple, ETrue);
sl@0
  2153
	Ldd.DoConsumeRamFinish();
sl@0
  2154
	test_KErrNone(r);
sl@0
  2155
sl@0
  2156
	TEST_NEXT((_L("Multiple thread with Low memory, with starting free ram.")));
sl@0
  2157
	// First load some pages onto the page cache 
sl@0
  2158
	gPerformTestLoop = 1;
sl@0
  2159
	r = DoTest(ETestSingle);
sl@0
  2160
	test_KErrNone(r);
sl@0
  2161
sl@0
  2162
	Ldd.DoConsumeRamSetup(32, TEST_LM_BLOCKSIZE);
sl@0
  2163
	
sl@0
  2164
	gPerformTestLoop = 10;
sl@0
  2165
	gNumTestThreads	= KMaxTestThreads / 2;
sl@0
  2166
	r = DoTest(ETestMultiple, ETrue);
sl@0
  2167
	Ldd.DoConsumeRamFinish();
sl@0
  2168
	test_KErrNone(r);
sl@0
  2169
sl@0
  2170
	TEST_NEXT((_L("Close test driver")));
sl@0
  2171
	Ldd.Close();
sl@0
  2172
	RUNTEST(User::FreeLogicalDevice(KPageStressTestLddName), KErrNone);
sl@0
  2173
	if (gIsDemandPaged)
sl@0
  2174
		{
sl@0
  2175
		TInt minSize = tempPages.iMinSize;
sl@0
  2176
		TInt maxSize = tempPages.iMaxSize;
sl@0
  2177
		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
sl@0
  2178
		}
sl@0
  2179
sl@0
  2180
	return r;
sl@0
  2181
	}
sl@0
  2182
sl@0
  2183
void RestoreDefaults()
sl@0
  2184
	{
sl@0
  2185
	gPerformTestLoop			= 10;					
sl@0
  2186
	gNumTestThreads				= KMaxTestThreads;	
sl@0
  2187
sl@0
  2188
	gTestInterleave				= EFalse;
sl@0
  2189
	
sl@0
  2190
	gTestWhichTests				= gSetTests;
sl@0
  2191
	gTestPrioChange				= EFalse;
sl@0
  2192
	gTestStopMedia				= EFalse;
sl@0
  2193
	gTestMediaAccess			= EFalse;
sl@0
  2194
	}
sl@0
  2195
sl@0
  2196
sl@0
  2197
sl@0
  2198
TInt DoTest(TInt gTestType, TBool aLowMem)
sl@0
  2199
	{
sl@0
  2200
	TInt r = KErrNone;
sl@0
  2201
	
sl@0
  2202
	switch(gTestType)
sl@0
  2203
		{
sl@0
  2204
		case ETestSingle:
sl@0
  2205
			TEST_NEXT((_L("Single thread")));
sl@0
  2206
			r = DoSingleTest(aLowMem);
sl@0
  2207
			break;
sl@0
  2208
sl@0
  2209
		case ETestMultiple:
sl@0
  2210
			TEST_NEXT((_L("Multiple thread")));
sl@0
  2211
			
sl@0
  2212
			r = DoMultipleTest(aLowMem);
sl@0
  2213
			break;
sl@0
  2214
sl@0
  2215
		case ETestLowMem:
sl@0
  2216
			TEST_NEXT((_L("Low Memory Tests")));
sl@0
  2217
			r = DoLowMemTest();
sl@0
  2218
			break;
sl@0
  2219
sl@0
  2220
		case ETestMedia:
sl@0
  2221
			TEST_NEXT((_L("Background Media Activity Tests")));
sl@0
  2222
			gTestMediaAccess = ETrue;
sl@0
  2223
			gPerformTestLoop = 2;					
sl@0
  2224
			gNumTestThreads	= KMaxTestThreads / 2;	
sl@0
  2225
			r = DoMultipleTest(aLowMem);
sl@0
  2226
			break;
sl@0
  2227
sl@0
  2228
		case ETestCommit:
sl@0
  2229
			TEST_NEXT((_L("Committing and Decommitting Tests")));	
sl@0
  2230
			gTestWhichTests = TEST_COMMIT;
sl@0
  2231
			r = DoSingleTest(aLowMem);
sl@0
  2232
			break;
sl@0
  2233
sl@0
  2234
		case ETestInterleave:
sl@0
  2235
			TEST_NEXT((_L("Testing multiple with thread interleaving")));
sl@0
  2236
			gTestInterleave = ETrue;
sl@0
  2237
			r = DoMultipleTest(aLowMem);
sl@0
  2238
			break;
sl@0
  2239
sl@0
  2240
		case ETestBadServer:
sl@0
  2241
			TEST_NEXT((_L("Testing multiple with thread interleaving")));
sl@0
  2242
			gTestBadServer = ETrue;
sl@0
  2243
			gTestWhichTests = TEST_IPC;
sl@0
  2244
			r = DoSingleTest(aLowMem);
sl@0
  2245
			break;
sl@0
  2246
sl@0
  2247
sl@0
  2248
		}
sl@0
  2249
	RestoreDefaults();
sl@0
  2250
	return r;
sl@0
  2251
	}
sl@0
  2252
//
sl@0
  2253
// E32Main
sl@0
  2254
//
sl@0
  2255
// Main entry point.
sl@0
  2256
//
sl@0
  2257
sl@0
  2258
TInt E32Main()
sl@0
  2259
	{
sl@0
  2260
#ifndef TEST_ON_UNPAGED
sl@0
  2261
	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
sl@0
  2262
	if(!romHeader->iPageableRomStart)
sl@0
  2263
		{
sl@0
  2264
		gIsDemandPaged = EFalse;
sl@0
  2265
		}
sl@0
  2266
#endif
sl@0
  2267
	TUint start = User::TickCount();
sl@0
  2268
	
sl@0
  2269
	gResultsArray = (SThreadExitResults *)User::AllocZ(sizeof(SThreadExitResults) * KMaxTestThreads);
sl@0
  2270
	if (gResultsArray == NULL)
sl@0
  2271
		return KErrNoMemory;
sl@0
  2272
sl@0
  2273
	AreWeTheTestBase();
sl@0
  2274
	RestoreDefaults();
sl@0
  2275
sl@0
  2276
	TBool parseResult = ParseCommandLine();
sl@0
  2277
sl@0
  2278
	if (TestExit)
sl@0
  2279
		{
sl@0
  2280
		return KErrNone;
sl@0
  2281
		}
sl@0
  2282
sl@0
  2283
	// Retrieve the page size and use it to detemine the page shift (assumes 32-bit system).
sl@0
  2284
	TInt r = HAL::Get(HAL::EMemoryPageSize, gPageSize);
sl@0
  2285
	if (r != KErrNone)
sl@0
  2286
		{
sl@0
  2287
		RDBGS_PRINT(("Cannot obtain the page size\n"));
sl@0
  2288
		return r;
sl@0
  2289
		}
sl@0
  2290
	else
sl@0
  2291
		{
sl@0
  2292
		RDBGS_PRINT(("page size = %d\n", gPageSize));
sl@0
  2293
		}
sl@0
  2294
sl@0
  2295
sl@0
  2296
	TUint32 pageMask = gPageSize;
sl@0
  2297
	TUint i = 0;
sl@0
  2298
	for (; i < 32; i++)
sl@0
  2299
		{
sl@0
  2300
		if (pageMask & 1)
sl@0
  2301
			{
sl@0
  2302
			if (pageMask & ~1u)
sl@0
  2303
				{
sl@0
  2304
				test.Printf(_L("ERROR - page size not a power of 2"));
sl@0
  2305
				return KErrNotSupported;
sl@0
  2306
				}
sl@0
  2307
			gPageShift = i;
sl@0
  2308
			break;
sl@0
  2309
			}
sl@0
  2310
		pageMask >>= 1;
sl@0
  2311
		}
sl@0
  2312
sl@0
  2313
	TInt  minSize = 8 << gPageShift;
sl@0
  2314
	TInt  maxSize = 64 << gPageShift; 
sl@0
  2315
	SVMCacheInfo  tempPages;
sl@0
  2316
	memset(&tempPages, 0, sizeof(tempPages));
sl@0
  2317
	if (gIsDemandPaged)
sl@0
  2318
		{
sl@0
  2319
		// get the old cache info
sl@0
  2320
		UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0);
sl@0
  2321
		// set the cache to our test value
sl@0
  2322
		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
sl@0
  2323
		}
sl@0
  2324
sl@0
  2325
sl@0
  2326
	if (!TestSilent)
sl@0
  2327
		{
sl@0
  2328
		test.Title();
sl@0
  2329
		test.Start(_L("Writable Data Paging stress tests..."));
sl@0
  2330
		test.Printf(_L("%S\n"), &gTestNameBuffer);
sl@0
  2331
		}
sl@0
  2332
sl@0
  2333
	if (parseResult)
sl@0
  2334
		{
sl@0
  2335
		if (!TestSilent)
sl@0
  2336
			{
sl@0
  2337
			extern TInt *CheckLdmiaInstr(void);
sl@0
  2338
			test.Printf(_L("%S : CheckLdmiaInstr\n"), &gTestNameBuffer);
sl@0
  2339
			TInt   *theAddr = CheckLdmiaInstr();
sl@0
  2340
			test.Printf(_L("%S : CheckLdmiaInstr complete 0x%x...\n"), &gTestNameBuffer, (TInt)theAddr);
sl@0
  2341
			}
sl@0
  2342
		
sl@0
  2343
		if (gTestType < 0 || gTestType >= ETestTypeEnd)
sl@0
  2344
			{
sl@0
  2345
			r = PerformAutoTest();
sl@0
  2346
			test_KErrNone(r);
sl@0
  2347
			}
sl@0
  2348
		else
sl@0
  2349
			{
sl@0
  2350
			r = DoTest(gTestType);
sl@0
  2351
			test_KErrNone(r);
sl@0
  2352
			}
sl@0
  2353
		}
sl@0
  2354
	else
sl@0
  2355
		{
sl@0
  2356
		r = PerformAutoTest();
sl@0
  2357
		test_KErrNone(r);
sl@0
  2358
		}
sl@0
  2359
sl@0
  2360
	if (gIsDemandPaged)
sl@0
  2361
		{
sl@0
  2362
		minSize = tempPages.iMinSize;
sl@0
  2363
		maxSize = tempPages.iMaxSize;
sl@0
  2364
		// put the cache back to the the original values.
sl@0
  2365
		UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
sl@0
  2366
		}
sl@0
  2367
sl@0
  2368
	if (!TestSilent)
sl@0
  2369
		{
sl@0
  2370
		test.Printf(_L("%S : Complete (%u ticks)\n"), &gTestNameBuffer, User::TickCount() - start);	
sl@0
  2371
		test.End();
sl@0
  2372
		}
sl@0
  2373
sl@0
  2374
	User::Free(gResultsArray);
sl@0
  2375
	gResultsArray = NULL;
sl@0
  2376
	
sl@0
  2377
	return 0;
sl@0
  2378
	}
sl@0
  2379
sl@0
  2380