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