kerneltest/e32test/mmu/t_shbuf_perf.cpp
changeset 9 96e5fb8b040d
equal deleted inserted replaced
-1:000000000000 9:96e5fb8b040d
       
     1 // Copyright (c) 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 // e32test/mmu/t_shbuf_perf.cpp
       
    15 //
       
    16 //
       
    17 
       
    18 /**
       
    19  *  @file
       
    20  *
       
    21  *  Performance Testing of shared buffers.
       
    22  *
       
    23  *  Runs a number of tests using descriptors and RShBuf handles and compares
       
    24  *  the results to see the improvements in performance.
       
    25  */
       
    26 
       
    27 
       
    28 #define __E32TEST_EXTENSION__
       
    29 
       
    30 #include <e32def.h>
       
    31 #include <e32test.h>
       
    32 #include <e32debug.h>
       
    33 #include <e32msgqueue.h>
       
    34 #include <e32shbuf.h>
       
    35 #include <hal.h>
       
    36 #include <u32hal.h>
       
    37 #include <e32svr.h>
       
    38 
       
    39 #include "d_shbuf.h"
       
    40 #include "t_shbuf_perfclient.h"
       
    41 
       
    42 
       
    43 //
       
    44 // Test name (and process name!)...
       
    45 //
       
    46 _LIT(KTestProcessName, "T_SHBUF_PERF");
       
    47 
       
    48 
       
    49 /**
       
    50  *  Global test object (must be called 'test' to match some macros)...
       
    51  */
       
    52 RTest  test(KTestProcessName);
       
    53 
       
    54 //
       
    55 // Number of iterations to run for each test. The timings are worked out by
       
    56 // running the test X number of times and dividing the total time by X.
       
    57 //
       
    58 #ifdef _DEBUG
       
    59 /**
       
    60  *  Number of iterations to run for each test (WINS/WINSCW/Target Debug).
       
    61  */
       
    62 const TInt  KNumberOfIterations(50);      // Used for debuging and hence not measurement.
       
    63 #else
       
    64 #ifdef __WINS__
       
    65 /**
       
    66  *  Number of iterations to run for each test (WINS/WINSCW Release).
       
    67  */
       
    68 const TInt  KNumberOfIterations(5000);   // Proper emulator performance testing.
       
    69 #else
       
    70 /**
       
    71  *  Number of iterations to run for each test (Target Release).
       
    72  */
       
    73 const TInt  KNumberOfIterations(500);   // Proper target performance testing.
       
    74 #endif
       
    75 #endif
       
    76 
       
    77 
       
    78 TUint8  iClearCache[32768];
       
    79 
       
    80 
       
    81 /**
       
    82  *  RShBuf performance test types.
       
    83  */
       
    84 enum TRShBufPerfTest
       
    85 	{
       
    86 	/**
       
    87 	 *  Send buffer from the client to the driver directly and back.
       
    88 	 */
       
    89 	ERShBufPerfTestClientToDriverReturn,
       
    90 	
       
    91 	/**
       
    92 	 *  Send buffer from the client to the driver directly one way.
       
    93 	 */
       
    94 	ERShBufPerfTestClientToDriverOneWay,
       
    95 	
       
    96 	/**
       
    97 	 *  Send buffer from the client to a second process to the driver and back.
       
    98 	 */
       
    99 	ERShBufPerfTestClientToProcessToDriverReturn,
       
   100 	
       
   101 	/**
       
   102 	 *  Send buffer from the client to a second process to the driver one way.
       
   103 	 */
       
   104 	ERShBufPerfTestClientToProcessToDriverOneWay,
       
   105 	
       
   106 	/**
       
   107 	 *  Read buffer from the driver directly and send it back.
       
   108 	 */
       
   109 	ERShBufPerfTestDriverToClientReturn,
       
   110 	
       
   111 	/**
       
   112 	 *  Read buffer from the driver directly one way.
       
   113 	 */
       
   114 	ERShBufPerfTestDriverToClientOneWay,
       
   115 	
       
   116 	/**
       
   117 	 *  Read buffer from the driver via a second process and send it back.
       
   118 	 */
       
   119 	ERShBufPerfTestDriverToProcessToClientReturn,
       
   120 	
       
   121 	/**
       
   122 	 *  Read buffer from the driver via a second process one way.
       
   123 	 */
       
   124 	ERShBufPerfTestDriverToProcessToClientOneWay
       
   125 	};
       
   126 
       
   127 
       
   128 void StartSecondProcessAndDriver(TRShBufPerfTest aTestType,
       
   129 								 RShBufTestChannel&  aLdd,
       
   130 								 RShBufTestServerSession& aTestServer,
       
   131 								 RThread& aTestServerThread,
       
   132 								 TInt aDriverNum)
       
   133 	{
       
   134 	//
       
   135 	// If a second process is needed start this process as a child...
       
   136 	//
       
   137 	if (aTestType == ERShBufPerfTestClientToProcessToDriverReturn  ||
       
   138 		aTestType == ERShBufPerfTestClientToProcessToDriverOneWay  ||
       
   139 		aTestType == ERShBufPerfTestDriverToProcessToClientReturn  ||
       
   140 		aTestType == ERShBufPerfTestDriverToProcessToClientOneWay)
       
   141 		{
       
   142 		test.Next(_L("Start slave server process..."));
       
   143 		test_KErrNone(aTestServer.Connect());
       
   144 		test.Next(_L("Find slave server thread..."));
       
   145 		test_KErrNone(aTestServerThread.Open(_L("t_shbuf_perf.exe[00000000]0001::!RShBufServer")));
       
   146 		}
       
   147 
       
   148 	//
       
   149 	// Open the driver (always open it as it is used to get buffers too!)...
       
   150 	//
       
   151 	TInt r = User::LoadLogicalDevice(_L("D_SHBUF_CLIENT.LDD"));
       
   152 	test(r == KErrNone || r == KErrAlreadyExists);
       
   153 	r = User::LoadLogicalDevice(_L("D_SHBUF_OWN.LDD"));
       
   154 	test(r == KErrNone || r == KErrAlreadyExists);
       
   155 	test_KErrNone(aLdd.Open(aDriverNum));
       
   156 	} // StartSecondProcessAndDriver
       
   157 
       
   158 
       
   159 void StopSecondProcessAndDriver(TRShBufPerfTest aTestType,
       
   160 								RShBufTestChannel&  aLdd,
       
   161 								RShBufTestServerSession& aTestServer,
       
   162 								RThread& aTestServerThread)
       
   163 	{
       
   164 	//
       
   165 	// Close the driver..
       
   166 	//
       
   167 	aLdd.Close();
       
   168 
       
   169 	if (aTestType == ERShBufPerfTestClientToProcessToDriverReturn  ||
       
   170 		aTestType == ERShBufPerfTestClientToProcessToDriverOneWay  ||
       
   171 		aTestType == ERShBufPerfTestDriverToProcessToClientReturn  ||
       
   172 		aTestType == ERShBufPerfTestDriverToProcessToClientOneWay)
       
   173 		{
       
   174 #ifdef CAN_TRANSFER_SHBUF_TO_ANOTHER_PROCESS
       
   175 		test.Next(_L("Stop slave server process..."));
       
   176 		test_KErrNone(aTestServer.ShutdownServer());
       
   177 #endif
       
   178 		aTestServerThread.Close();
       
   179 		aTestServer.Close();
       
   180 		}
       
   181 	} // StopSecondProcessAndDriver
       
   182 
       
   183 
       
   184 /**
       
   185  *  Print the TRShBufPerfTest enum.
       
   186  */
       
   187 void PrinTRShBufPerfTestType(const TDesC& aPrefix, TRShBufPerfTest aTestType)
       
   188 	{
       
   189 	switch (aTestType)
       
   190 		{
       
   191 		case ERShBufPerfTestClientToDriverReturn:
       
   192 			{
       
   193 			test.Printf(_L("%SaTestType=ERShBufPerfTestClientToDriverReturn (%d)"), &aPrefix, aTestType);
       
   194 			}
       
   195 			break;
       
   196 			
       
   197 		case ERShBufPerfTestClientToDriverOneWay:
       
   198 			{
       
   199 			test.Printf(_L("%SaTestType=ERShBufPerfTestClientToDriverOneWay (%d)"), &aPrefix, aTestType);
       
   200 			}
       
   201 			break;
       
   202 			
       
   203 		case ERShBufPerfTestClientToProcessToDriverReturn:
       
   204 			{
       
   205 			test.Printf(_L("%SaTestType=ERShBufPerfTestClientToProcessToDriverReturn (%d)"), &aPrefix, aTestType);
       
   206 			}
       
   207 			break;
       
   208 			
       
   209 		case ERShBufPerfTestClientToProcessToDriverOneWay:
       
   210 			{
       
   211 			test.Printf(_L("%SaTestType=ERShBufPerfTestClientToProcessToDriverOneWay (%d)"), &aPrefix, aTestType);
       
   212 			}
       
   213 			break;
       
   214 			
       
   215 		case ERShBufPerfTestDriverToClientReturn:
       
   216 			{
       
   217 			test.Printf(_L("%SaTestType=ERShBufPerfTestDriverToClientReturn (%d)"), &aPrefix, aTestType);
       
   218 			}
       
   219 			break;
       
   220 			
       
   221 		case ERShBufPerfTestDriverToClientOneWay:
       
   222 			{
       
   223 			test.Printf(_L("%SaTestType=ERShBufPerfTestDriverToClientOneWay (%d)"), &aPrefix, aTestType);
       
   224 			}
       
   225 			break;
       
   226 			
       
   227 		case ERShBufPerfTestDriverToProcessToClientReturn:
       
   228 			{
       
   229 			test.Printf(_L("%SaTestType=ERShBufPerfTestDriverToProcessToClientReturn (%d)"), &aPrefix, aTestType);
       
   230 			}
       
   231 			break;
       
   232 			
       
   233 		case ERShBufPerfTestDriverToProcessToClientOneWay:
       
   234 			{
       
   235 			test.Printf(_L("%SaTestType=ERShBufPerfTestDriverToProcessToClientOneWay (%d)"), &aPrefix, aTestType);
       
   236 			}
       
   237 			break;
       
   238 			
       
   239 		default:
       
   240 			{
       
   241 			test.Printf(_L("%SaTestType=<unknown> (%d)"), &aPrefix, aTestType);
       
   242 			}
       
   243 			break;
       
   244 		}
       
   245 	} // PrinTRShBufPerfTestType
       
   246 
       
   247 
       
   248 /**
       
   249  *  Print the TShPoolCreateInfo object.
       
   250  */
       
   251 void PrintTShPoolInfo(const TDesC& aPrefix, TShPoolInfo aShPoolInfo)
       
   252 	{
       
   253 	test.Printf(_L("%SaShPoolInfo.iBufSize=%d"), &aPrefix, aShPoolInfo.iBufSize);
       
   254 	test.Printf(_L("%SaShPoolInfo.iInitialBufs=%d"), &aPrefix, aShPoolInfo.iInitialBufs);
       
   255 	test.Printf(_L("%SaShPoolInfo.iMaxBufs=%d"), &aPrefix, aShPoolInfo.iMaxBufs);
       
   256 	test.Printf(_L("%SaShPoolInfo.iGrowTriggerRatio=%d"), &aPrefix, aShPoolInfo.iGrowTriggerRatio);
       
   257 	test.Printf(_L("%SaShPoolInfo.iGrowByRatio=%d"), &aPrefix, aShPoolInfo.iGrowByRatio);
       
   258 	test.Printf(_L("%SaShPoolInfo.iShrinkHysteresisRatio=%d"), &aPrefix, aShPoolInfo.iShrinkHysteresisRatio);
       
   259 	test.Printf(_L("%SaShPoolInfo.iAlignment=%d (0x%x)"), &aPrefix, aShPoolInfo.iAlignment,
       
   260 				2 << (aShPoolInfo.iAlignment - 1));
       
   261 	test.Printf(_L("%SaShPoolInfo.iFlags=0x%08x"), &aPrefix, aShPoolInfo.iFlags);
       
   262 	} // PrintTShPoolInfo
       
   263 
       
   264 
       
   265 void TestSharedBufferPerformanceL(TRShBufPerfTest aTestType,
       
   266 								  TInt aMinAllocSize, TInt aMaxAllocSize,
       
   267 								  TInt aBufferSizeSteps,  TInt aTotalIterations,
       
   268 								  TShPoolCreateFlags aFlags, TInt aDriverNum,
       
   269 								  TDes& aSummaryBuf)
       
   270 	{
       
   271 	TShPoolInfo  shPoolInfo;
       
   272 
       
   273     shPoolInfo.iBufSize               = aMaxAllocSize;
       
   274     shPoolInfo.iInitialBufs           = 5;
       
   275 	shPoolInfo.iMaxBufs               = 5;
       
   276 	shPoolInfo.iGrowTriggerRatio      = 0;
       
   277 	shPoolInfo.iGrowByRatio           = 0;
       
   278 	shPoolInfo.iShrinkHysteresisRatio = 0;
       
   279 	shPoolInfo.iAlignment             = 9;
       
   280 	shPoolInfo.iFlags                 = aFlags;
       
   281 
       
   282 	//
       
   283 	// Start test and print the parameters...
       
   284 	//
       
   285 	test.Printf(_L(" Test parameters:"));
       
   286 	PrinTRShBufPerfTestType(_L("  "), aTestType);
       
   287 	PrintTShPoolInfo(_L("  "), shPoolInfo);
       
   288 	test.Printf(_L("  aMinAllocSize=%d"), aMinAllocSize);
       
   289 	test.Printf(_L("  aMaxAllocSize=%d"), aMaxAllocSize);
       
   290 	test.Printf(_L("  aBufferSizeSteps=%d"), aBufferSizeSteps);
       
   291 	test.Printf(_L("  aTotalIterations=%d"), aTotalIterations);
       
   292 	test.Printf(_L("  aDriverNum=%d"), aDriverNum);
       
   293 
       
   294 	//
       
   295 	// Initialise second process and/or open the driver...
       
   296 	//
       
   297 	RShBufTestServerSession  testServer;
       
   298 	RShBufTestChannel  shBufLdd;
       
   299 	RThread  testServerThread;
       
   300 
       
   301 	StartSecondProcessAndDriver(aTestType, shBufLdd, testServer, testServerThread, aDriverNum);
       
   302 	CleanupClosePushL(testServer);
       
   303 	
       
   304 	//
       
   305 	// Allocate a RShPool...
       
   306 	//
       
   307 	RShPool  shPool;
       
   308 		
       
   309 	if (aFlags & EShPoolPageAlignedBuffer)
       
   310 		{
       
   311 		TShPoolCreateInfo  shPoolCreateInfo(TShPoolCreateInfo::EPageAlignedBuffer,
       
   312 		                                    shPoolInfo.iBufSize, shPoolInfo.iInitialBufs);
       
   313 		test_KErrNone(shPool.Create(shPoolCreateInfo, KDefaultPoolHandleFlags));
       
   314 		CleanupClosePushL(shPool);
       
   315 		
       
   316 		test_KErrNone(shPool.SetBufferWindow(-1, ETrue));
       
   317 		shPoolInfo.iAlignment = 12;
       
   318 		}
       
   319 	else if (aFlags & EShPoolNonPageAlignedBuffer)
       
   320 		{
       
   321 		TShPoolCreateInfo  shPoolCreateInfo(TShPoolCreateInfo::ENonPageAlignedBuffer,
       
   322 		                                    shPoolInfo.iBufSize, shPoolInfo.iInitialBufs,
       
   323 				                            shPoolInfo.iAlignment);
       
   324 		test_KErrNone(shPool.Create(shPoolCreateInfo, KDefaultPoolHandleFlags));
       
   325 		CleanupClosePushL(shPool);
       
   326 		}
       
   327 
       
   328 	test(shPool.Handle() != 0);
       
   329 	
       
   330 	if (aTestType == ERShBufPerfTestClientToProcessToDriverReturn  ||
       
   331 		aTestType == ERShBufPerfTestClientToProcessToDriverOneWay  ||
       
   332 		aTestType == ERShBufPerfTestDriverToProcessToClientReturn  ||
       
   333 		aTestType == ERShBufPerfTestDriverToProcessToClientOneWay)
       
   334 		{
       
   335 		test_KErrNone(testServer.OpenRShBufPool(shPool.Handle(), shPoolInfo));
       
   336 		}
       
   337 	else
       
   338 		{
       
   339 		test_KErrNone(shBufLdd.OpenUserPool(shPool.Handle(), shPoolInfo));
       
   340 		}
       
   341 	
       
   342 	//
       
   343 	// Run the test iterations and time the result...
       
   344 	//
       
   345 	TInt fastTimerFreq;
       
   346 	HAL::Get(HALData::EFastCounterFrequency, fastTimerFreq);
       
   347 	TReal ticksPerMicroSec = 1.0E-6 * fastTimerFreq;
       
   348 
       
   349 	// Bind this thread to CPU 0. This is so that timer deltas don't drift from
       
   350 	// scheduling - else, it causes spurious failures.
       
   351     if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0) > 1)
       
   352 	   (void)UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny *)0, 0);
       
   353 
       
   354 	TReal64  totalLengthOfDesTest(0);
       
   355 	TReal64  totalLengthOfShBufTest(0);
       
   356 	TInt  breakevenPoint = 0;
       
   357 	TInt  bufferStep;
       
   358 
       
   359 	test.Printf(_L("BufSize\tTotalTime(Des)\tAvTime(Des)\tTotalTime(ShBuf)\tAvTime(ShBuf)\tSpeedUp(%%)"));
       
   360 #ifndef __WINS__
       
   361 	test.Printf(_L("\n"));
       
   362 #endif
       
   363 	for (bufferStep = 0;  bufferStep < aBufferSizeSteps;  bufferStep++)
       
   364 		{
       
   365 		//
       
   366 		// Run a single buffer size through these tests...
       
   367 		//
       
   368 		TInt  bufferSize = aMinAllocSize +
       
   369 						   (((aMaxAllocSize - aMinAllocSize) * bufferStep) / (aBufferSizeSteps-1));
       
   370 		TUint32  startDesTest = 0;
       
   371 		TUint32 startShBufTest = 0;
       
   372 		TInt  iteration;
       
   373 
       
   374 		TUint32  lengthOfDesTest=0;
       
   375 
       
   376 		//
       
   377 		// Test normal descriptor methods first...
       
   378 		//
       
   379 
       
   380 		for (iteration = 0;  iteration < aTotalIterations;  iteration++)
       
   381 			{
       
   382 			//
       
   383 			// Allocate a local buffer for this test...
       
   384 			//
       
   385 			HBufC8*  singleBuf = HBufC8::NewLC(bufferSize);
       
   386 
       
   387 			startDesTest = User::FastCounter();
       
   388 			test(singleBuf != NULL);
       
   389 
       
   390 			TPtr8 singleBufPtr = singleBuf->Des();
       
   391 			singleBufPtr.SetLength(bufferSize);
       
   392 
       
   393 			//
       
   394 			// Are we sending or receiving?
       
   395 			//
       
   396 			if (aTestType == ERShBufPerfTestClientToDriverOneWay  ||
       
   397 				aTestType == ERShBufPerfTestClientToProcessToDriverOneWay)
       
   398 				{
       
   399 #ifdef _DEBUG // do not cache
       
   400 				TUint8* bufptr = const_cast<TUint8*>(singleBuf->Ptr());
       
   401 
       
   402 				// We are sending...
       
   403 				for (TInt pos = 0;  pos < bufferSize;  pos++)
       
   404 					{
       
   405 					bufptr[pos] = (TUint8)(pos%32);
       
   406 					}
       
   407 				// clear cache
       
   408 				memset(iClearCache, 0xFF, sizeof(iClearCache));
       
   409 #endif
       
   410 				}
       
   411 
       
   412 
       
   413 			//
       
   414 			// Either send to the driver or to the other process...
       
   415 			//
       
   416 			if (aTestType == ERShBufPerfTestClientToDriverReturn)
       
   417 				{
       
   418 				test_KErrNone(shBufLdd.FromTPtr8ProcessAndReturn(singleBufPtr, bufferSize));
       
   419 				test(singleBufPtr.Length() == bufferSize-2);
       
   420 				}
       
   421 			else if (aTestType == ERShBufPerfTestClientToDriverOneWay)
       
   422 				{
       
   423 				test_KErrNone(shBufLdd.FromTPtr8ProcessAndRelease(singleBufPtr));
       
   424 				}
       
   425 			else if (aTestType == ERShBufPerfTestClientToProcessToDriverReturn)
       
   426 				{
       
   427 				test_KErrNone(testServer.FromTPtr8ProcessAndReturn(singleBufPtr, bufferSize));
       
   428 				test(singleBufPtr.Length() == bufferSize-2);
       
   429 				}
       
   430 			else if (aTestType == ERShBufPerfTestClientToProcessToDriverOneWay)
       
   431 				{
       
   432 				test_KErrNone(testServer.FromTPtr8ProcessAndRelease(singleBufPtr));
       
   433 				}
       
   434 
       
   435 			lengthOfDesTest += (User::FastCounter() - startDesTest);
       
   436 
       
   437 			CleanupStack::PopAndDestroy(singleBuf);
       
   438 			}
       
   439 
       
   440 		TInt64  lengthOfShBufTest = 0;
       
   441 
       
   442 		//
       
   443 		// Test ShBuf methods...
       
   444 		//
       
   445 		for (iteration = 0;  iteration < aTotalIterations;  iteration++)
       
   446 			{
       
   447 			RShBuf  shBuf;
       
   448 			TInt*  lengthPtr;
       
   449 			//
       
   450 			// Are we sending or receiving?
       
   451 			//
       
   452 			startShBufTest = User::FastCounter();
       
   453 			if (aTestType == ERShBufPerfTestClientToDriverOneWay ||
       
   454 				aTestType == ERShBufPerfTestClientToProcessToDriverOneWay)
       
   455 				{
       
   456 				// We are sending...
       
   457 
       
   458 				//
       
   459 				// Allocate a buffer (using a pool)...
       
   460 				//
       
   461 
       
   462 				test_KErrNone(shBuf.Alloc(shPool));
       
   463 				TUint8*  shBufPtr = shBuf.Ptr();
       
   464 
       
   465 				lengthPtr = (TInt*)(&shBufPtr[0]); // First 32bit word is length!
       
   466 				*lengthPtr = bufferSize;
       
   467 #ifdef _DEBUG // do not cache
       
   468 				for (TInt pos = 4;  pos < bufferSize;  pos++)
       
   469 					{
       
   470 					shBufPtr[pos] = (TUint8)(pos%32);
       
   471 					}
       
   472 				// clear cache
       
   473 				memset(iClearCache, 0xFF, sizeof(iClearCache));
       
   474 #endif
       
   475 				}
       
   476 
       
   477 
       
   478 			//
       
   479 			// Either send to the driver or to the other process...
       
   480 			//
       
   481 			if (aTestType == ERShBufPerfTestClientToDriverReturn)
       
   482 				{
       
   483 				TInt retHandle;
       
   484 				retHandle = shBufLdd.FromRShBufProcessAndReturn(bufferSize);
       
   485 				test_Compare(retHandle, >, 0);
       
   486 				shBuf.SetReturnedHandle(retHandle);
       
   487 
       
   488 				TInt* retPtr = (TInt*)shBuf.Ptr();
       
   489 
       
   490 				test(*retPtr == bufferSize-2);
       
   491 
       
   492 				shBuf.Close();
       
   493 				}
       
   494 			else if (aTestType == ERShBufPerfTestClientToDriverOneWay)
       
   495 				{
       
   496 				test_KErrNone(shBufLdd.FromRShBufProcessAndRelease(shBuf.Handle()));
       
   497 				}
       
   498 			else if (aTestType == ERShBufPerfTestClientToProcessToDriverReturn)
       
   499 				{
       
   500 				test_KErrNone(testServer.FromRShBufProcessAndReturn(shBuf, bufferSize));
       
   501 				TInt* retPtr = (TInt*)shBuf.Ptr();
       
   502 
       
   503 				test(*retPtr == bufferSize-2);
       
   504 
       
   505 				shBuf.Close();
       
   506 				}
       
   507 			else if (aTestType == ERShBufPerfTestClientToProcessToDriverOneWay)
       
   508 				{
       
   509 				test_KErrNone(testServer.FromRShBufProcessAndRelease(shBuf));
       
   510 				}
       
   511 			lengthOfShBufTest +=  (User::FastCounter() - startShBufTest);
       
   512 			}
       
   513 
       
   514 		//
       
   515 		// Print results of this buffer size...
       
   516 		//
       
   517 
       
   518 		test.Printf(_L("%d\t%10.2lfusec\t%10.2lfusec\t%.2f%%"), bufferSize,
       
   519 					I64REAL(lengthOfDesTest) / (TReal(aTotalIterations) * ticksPerMicroSec),
       
   520 					I64REAL(lengthOfShBufTest) / (TReal(aTotalIterations) * ticksPerMicroSec),
       
   521 					((100.0 / I64REAL(lengthOfShBufTest)) * I64REAL(lengthOfDesTest)) - 100.0);
       
   522 #ifndef __WINS__
       
   523 		test.Printf(_L("\n"));
       
   524 #endif
       
   525 		
       
   526 		totalLengthOfDesTest   += lengthOfDesTest;
       
   527 		totalLengthOfShBufTest += lengthOfShBufTest;
       
   528 
       
   529 		//
       
   530 		// Track the breakeven point (e.g. the buffer size at which RShBuf is
       
   531 		// quicker). This is normally when the number of bytes copied by the
       
   532 		// descriptor takes longer than the handling of the RShBuf.
       
   533 		//
       
   534 		if (lengthOfShBufTest >= lengthOfDesTest)
       
   535 			{
       
   536 			breakevenPoint = aMinAllocSize +
       
   537 						   (((aMaxAllocSize - aMinAllocSize) * (bufferStep + 1)) / (aBufferSizeSteps-1));
       
   538 			}
       
   539 		}
       
   540 
       
   541 	//
       
   542 	// Display timing information...
       
   543 	//
       
   544 	test.Printf(_L("Average\t%10.2lfusec\t%10.2lfusec\t%.2f%%"),
       
   545 				I64REAL(totalLengthOfDesTest) / (TReal(aTotalIterations * aBufferSizeSteps) * ticksPerMicroSec),
       
   546 				I64REAL(totalLengthOfShBufTest) / (TReal(aTotalIterations * aBufferSizeSteps) * ticksPerMicroSec),
       
   547 				((100.0 / I64REAL(totalLengthOfShBufTest)) * I64REAL(totalLengthOfDesTest)) - 100.0);
       
   548 #ifndef __WINS__
       
   549 	test.Printf(_L("\n"));
       
   550 #endif
       
   551 
       
   552 	//
       
   553 	// Record summary info for later use...
       
   554 	//
       
   555 	aSummaryBuf.Zero();
       
   556 	
       
   557 	if (breakevenPoint <= aMaxAllocSize)
       
   558 		{
       
   559 		aSummaryBuf.AppendFormat(_L("%10.2lfusec\t%10.2lfusec\t%.2f%%%%\t%d"),
       
   560 								 I64REAL(totalLengthOfDesTest) / TReal(aTotalIterations * aBufferSizeSteps * ticksPerMicroSec),
       
   561 								 I64REAL(totalLengthOfShBufTest) / TReal(aTotalIterations * aBufferSizeSteps * ticksPerMicroSec),
       
   562 								 ((100.0 / I64REAL(totalLengthOfShBufTest)) * I64REAL(totalLengthOfDesTest)) - 100.0,
       
   563 								 breakevenPoint);
       
   564 		}
       
   565 	else
       
   566 		{
       
   567 		aSummaryBuf.AppendFormat(_L("%10.2lfusec\t%10.2lfusec\t%.2f%%%%\tFailed to breakeven"),
       
   568 								 I64REAL(totalLengthOfDesTest) / TReal(aTotalIterations * aBufferSizeSteps * ticksPerMicroSec),
       
   569 								 I64REAL(totalLengthOfShBufTest) / TReal(aTotalIterations * aBufferSizeSteps * ticksPerMicroSec),
       
   570 								 ((100.0 / I64REAL(totalLengthOfShBufTest)) * I64REAL(totalLengthOfDesTest)) - 100.0);
       
   571 		}
       
   572 	
       
   573 	//
       
   574 	// Clean up...
       
   575 	//
       
   576 	TInt  shPoolHandle = shPool.Handle();
       
   577 	CleanupStack::PopAndDestroy(&shPool);
       
   578 
       
   579 	if (aTestType == ERShBufPerfTestClientToProcessToDriverReturn  ||
       
   580 		aTestType == ERShBufPerfTestClientToProcessToDriverOneWay  ||
       
   581 		aTestType == ERShBufPerfTestDriverToProcessToClientReturn  ||
       
   582 		aTestType == ERShBufPerfTestDriverToProcessToClientOneWay)
       
   583 		{
       
   584 		testServer.CloseRShBufPool(shPoolHandle);
       
   585 		}
       
   586 	else
       
   587 		{
       
   588 		test_KErrNone(shBufLdd.CloseUserPool());
       
   589 		}
       
   590 
       
   591 	//
       
   592 	// Shutdown the second process and/or close the driver.
       
   593 	//
       
   594 	CleanupStack::Pop(&testServer);
       
   595 	StopSecondProcessAndDriver(aTestType, shBufLdd, testServer, testServerThread);
       
   596 	} // TestSharedBufferPerformanceL
       
   597 
       
   598 
       
   599 /**
       
   600  *  Main test process which performs the testing.
       
   601  */
       
   602 void RunTestsL()
       
   603 	{
       
   604 	//
       
   605 	// Setup the test...
       
   606 	//
       
   607 	test.Title();
       
   608 	
       
   609 	test.Start(_L("Check for Shared Buffers availability"));
       
   610 	TInt r;
       
   611 	RShPool pool;
       
   612 	TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 100, 10);
       
   613 	r = pool.Create(inf, KDefaultPoolHandleFlags);
       
   614 	if (r == KErrNotSupported)
       
   615 		{
       
   616 		test.Printf(_L("Not supported by this memory model.\n"));
       
   617 		}
       
   618 	else
       
   619 		{
       
   620 		test_KErrNone(r);
       
   621 		pool.Close();
       
   622 
       
   623 		test.Next(_L("Performance test shared buffers"));
       
   624 
       
   625 		//
       
   626 		// Create a summary buffer to hold the average speeds of different pools...
       
   627 		//
       
   628 		HBufC*  summaryBuf = HBufC::NewLC(16 * 128 * 2);
       
   629 		TPtr  summaryBufPtr = summaryBuf->Des();
       
   630 		TBuf<128>  testName, testSummary;
       
   631 		
       
   632 		summaryBufPtr.Append(_L("Test Type\tAverage Time(Des)\tAverage Time(ShBuf)\tAverage SpeedUp(%%)\tBreakeven Buffer Size\n"));
       
   633 
       
   634 		//
       
   635 		// Run tests...
       
   636 		//
       
   637 		testName.Copy(_L("Client->Driver (non-aligned/client-thread)"));
       
   638 		test.Next(testName);
       
   639 		TestSharedBufferPerformanceL(
       
   640 			/* Test type */			 ERShBufPerfTestClientToDriverOneWay,
       
   641 			/* Min Alloc size */	 64,
       
   642 			/* Max Alloc size */	 8192,
       
   643 			/* Buffer size steps */	 128,
       
   644 			/* Total iterations */	 KNumberOfIterations,
       
   645 			/* Buffer flags */       EShPoolNonPageAlignedBuffer,
       
   646 			/* Driver to use */      RShBufTestChannel::EClientThread,
       
   647 			/* Summary string */     testSummary);
       
   648 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   649 
       
   650 		testName.Copy(_L("Client->Driver (aligned/client-thread)"));
       
   651 		test.Next(testName);
       
   652 		TestSharedBufferPerformanceL(
       
   653 			/* Test type */			 ERShBufPerfTestClientToDriverOneWay,
       
   654 			/* Min Alloc size */	 64,
       
   655 			/* Max Alloc size */	 8192,
       
   656 			/* Buffer size steps */	 128,
       
   657 			/* Total iterations */	 KNumberOfIterations,
       
   658 			/* Buffer flags */       EShPoolPageAlignedBuffer,
       
   659 			/* Driver to use */      RShBufTestChannel::EClientThread,
       
   660 			/* Summary string */     testSummary);
       
   661 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   662 
       
   663 		testName.Copy(_L("Client->Driver (non-aligned/own-thread)"));
       
   664 		test.Next(testName);
       
   665 		TestSharedBufferPerformanceL(
       
   666 			/* Test type */			 ERShBufPerfTestClientToDriverOneWay,
       
   667 			/* Min Alloc size */	 64,
       
   668 			/* Max Alloc size */	 8192,
       
   669 			/* Buffer size steps */	 128,
       
   670 			/* Total iterations */	 KNumberOfIterations,
       
   671 			/* Buffer flags */       EShPoolNonPageAlignedBuffer,
       
   672 			/* Driver to use */      RShBufTestChannel::EOwnThread,
       
   673 			/* Summary string */     testSummary);
       
   674 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   675 
       
   676 		testName.Copy(_L("Client->Driver (aligned/own-thread)"));
       
   677 		test.Next(testName);
       
   678 		TestSharedBufferPerformanceL(
       
   679 			/* Test type */			 ERShBufPerfTestClientToDriverOneWay,
       
   680 			/* Min Alloc size */	 64,
       
   681 			/* Max Alloc size */	 8192,
       
   682 			/* Buffer size steps */	 128,
       
   683 			/* Total iterations */	 KNumberOfIterations,
       
   684 			/* Buffer flags */       EShPoolPageAlignedBuffer,
       
   685 			/* Driver to use */      RShBufTestChannel::EOwnThread,
       
   686 			/* Summary string */     testSummary);
       
   687 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   688 
       
   689 		testName.Copy(_L("Client->Driver->Client (non-aligned/client-thread)"));
       
   690 		test.Next(testName);
       
   691 		TestSharedBufferPerformanceL(
       
   692 			/* Test type */			ERShBufPerfTestClientToDriverReturn,
       
   693 			/* Min Alloc size */	64,
       
   694 			/* Max Alloc size */	8192,
       
   695 			/* Buffer size steps */	128,
       
   696 			/* Total iterations */	KNumberOfIterations,
       
   697 			/* Buffer flags */      EShPoolNonPageAlignedBuffer,
       
   698 			/* Driver to use */     RShBufTestChannel::EClientThread,
       
   699 			/* Summary string */    testSummary);
       
   700 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   701 
       
   702 		testName.Copy(_L("Client->Driver->Client (aligned/client-thread)"));
       
   703 		test.Next(testName);
       
   704 		TestSharedBufferPerformanceL(
       
   705 			/* Test type */			 ERShBufPerfTestClientToDriverReturn,
       
   706 			/* Min Alloc size */	 64,
       
   707 			/* Max Alloc size */	 8192,
       
   708 			/* Buffer size steps */	 128,
       
   709 			/* Total iterations */	 KNumberOfIterations,
       
   710 			/* Buffer flags */       EShPoolPageAlignedBuffer,
       
   711 			/* Driver to use */      RShBufTestChannel::EClientThread,
       
   712 			/* Summary string */     testSummary);
       
   713 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   714 
       
   715 		testName.Copy(_L("Client->Driver->Client (non-aligned/own-thread)"));
       
   716 		test.Next(testName);
       
   717 		TestSharedBufferPerformanceL(
       
   718 			/* Test type */			 ERShBufPerfTestClientToDriverReturn,
       
   719 			/* Min Alloc size */	 64,
       
   720 			/* Max Alloc size */	 8192,
       
   721 			/* Buffer size steps */	 128,
       
   722 			/* Total iterations */	 KNumberOfIterations,
       
   723 			/* Buffer flags */       EShPoolNonPageAlignedBuffer,
       
   724 			/* Driver to use */      RShBufTestChannel::EOwnThread,
       
   725 			/* Summary string */     testSummary);
       
   726 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   727 
       
   728 		testName.Copy(_L("Client->Driver->Client (aligned/own-thread)"));
       
   729 		test.Next(testName);
       
   730 		TestSharedBufferPerformanceL(
       
   731 			/* Test type */			 ERShBufPerfTestClientToDriverReturn,
       
   732 			/* Min Alloc size */	 64,
       
   733 			/* Max Alloc size */	 8192,
       
   734 			/* Buffer size steps */	 128,
       
   735 			/* Total iterations */	 KNumberOfIterations,
       
   736 			/* Buffer flags */       EShPoolPageAlignedBuffer,
       
   737 			/* Driver to use */      RShBufTestChannel::EOwnThread,
       
   738 			/* Summary string */     testSummary);
       
   739 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   740 
       
   741 		testName.Copy(_L("Client->Process->Driver (non-aligned/client-thread)"));
       
   742 		test.Next(testName);
       
   743 		TestSharedBufferPerformanceL(
       
   744 			/* Test type */			 ERShBufPerfTestClientToProcessToDriverOneWay,
       
   745 			/* Min Alloc size */	 64,
       
   746 			/* Max Alloc size */	 8192,
       
   747 			/* Buffer size steps */	 128,
       
   748 			/* Total iterations */	 KNumberOfIterations,
       
   749 			/* Buffer flags */       EShPoolNonPageAlignedBuffer,
       
   750 			/* Driver to use */      RShBufTestChannel::EClientThread,
       
   751 			/* Summary string */     testSummary);
       
   752 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   753 
       
   754 		testName.Copy(_L("Client->Process->Driver (aligned/client-thread)"));
       
   755 		test.Next(testName);
       
   756 		TestSharedBufferPerformanceL(
       
   757 			/* Test type */			 ERShBufPerfTestClientToProcessToDriverOneWay,
       
   758 			/* Min Alloc size */	 64,
       
   759 			/* Max Alloc size */	 8192,
       
   760 			/* Buffer size steps */	 128,
       
   761 			/* Total iterations */	 KNumberOfIterations,
       
   762 			/* Buffer flags */       EShPoolPageAlignedBuffer,
       
   763 			/* Driver to use */      RShBufTestChannel::EClientThread,
       
   764 			/* Summary string */     testSummary);
       
   765 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   766 
       
   767 		testName.Copy(_L("Client->Process->Driver (non-aligned/own-thread)"));
       
   768 		test.Next(testName);
       
   769 		TestSharedBufferPerformanceL(
       
   770 			/* Test type */			 ERShBufPerfTestClientToProcessToDriverOneWay,
       
   771 			/* Min Alloc size */	 64,
       
   772 			/* Max Alloc size */	 8192,
       
   773 			/* Buffer size steps */	 128,
       
   774 			/* Total iterations */	 KNumberOfIterations,
       
   775 			/* Buffer flags */       EShPoolNonPageAlignedBuffer,
       
   776 			/* Driver to use */      RShBufTestChannel::EOwnThread,
       
   777 			/* Summary string */     testSummary);
       
   778 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   779 
       
   780 		testName.Copy(_L("Client->Process->Driver (aligned/own-thread)"));
       
   781 		test.Next(testName);
       
   782 		TestSharedBufferPerformanceL(
       
   783 			/* Test type */			 ERShBufPerfTestClientToProcessToDriverOneWay,
       
   784 			/* Min Alloc size */	 64,
       
   785 			/* Max Alloc size */	 8192,
       
   786 			/* Buffer size steps */	 128,
       
   787 			/* Total iterations */	 KNumberOfIterations,
       
   788 			/* Buffer flags */       EShPoolPageAlignedBuffer,
       
   789 			/* Driver to use */      RShBufTestChannel::EOwnThread,
       
   790 			/* Summary string */     testSummary);
       
   791 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   792 
       
   793 		testName.Copy(_L("Client->Process->Driver->Process->Client (non-aligned/client-thread)"));
       
   794 		test.Next(testName);
       
   795 		TestSharedBufferPerformanceL(
       
   796 			/* Test type */			 ERShBufPerfTestClientToProcessToDriverReturn,
       
   797 			/* Min Alloc size */	 64,
       
   798 			/* Max Alloc size */	 8192,
       
   799 			/* Buffer size steps */	 128,
       
   800 			/* Total iterations */	 KNumberOfIterations,
       
   801 			/* Buffer flags */       EShPoolNonPageAlignedBuffer,
       
   802 			/* Driver to use */      RShBufTestChannel::EClientThread,
       
   803 			/* Summary string */     testSummary);
       
   804 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   805 
       
   806 		testName.Copy(_L("Client->Process->Driver->Process->Client (aligned/client-thread)"));
       
   807 		test.Next(testName);
       
   808 		TestSharedBufferPerformanceL(
       
   809 			/* Test type */			 ERShBufPerfTestClientToProcessToDriverReturn,
       
   810 			/* Min Alloc size */	 64,
       
   811 			/* Max Alloc size */	 8192,
       
   812 			/* Buffer size steps */	 128,
       
   813 			/* Total iterations */	 KNumberOfIterations,
       
   814 			/* Buffer flags */       EShPoolPageAlignedBuffer,
       
   815 			/* Driver to use */      RShBufTestChannel::EClientThread,
       
   816 			/* Summary string */     testSummary);
       
   817 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   818 
       
   819 		testName.Copy(_L("Client->Process->Driver->Process->Client (non-aligned/own-thread)"));
       
   820 		test.Next(testName);
       
   821 		TestSharedBufferPerformanceL(
       
   822 			/* Test type */			 ERShBufPerfTestClientToProcessToDriverReturn,
       
   823 			/* Min Alloc size */	 64,
       
   824 			/* Max Alloc size */	 8192,
       
   825 			/* Buffer size steps */	 128,
       
   826 			/* Total iterations */	 KNumberOfIterations,
       
   827 			/* Buffer flags */       EShPoolNonPageAlignedBuffer,
       
   828 			/* Driver to use */      RShBufTestChannel::EOwnThread,
       
   829 			/* Summary string */     testSummary);
       
   830 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   831 
       
   832 		testName.Copy(_L("Client->Process->Driver->Process->Client (aligned/own-thread)"));
       
   833 		test.Next(testName);
       
   834 		TestSharedBufferPerformanceL(
       
   835 			/* Test type */			ERShBufPerfTestClientToProcessToDriverReturn,
       
   836 			/* Min Alloc size */	 64,
       
   837 			/* Max Alloc size */	 8192,
       
   838 			/* Buffer size steps */	 128,
       
   839 			/* Total iterations */	 KNumberOfIterations,
       
   840 			/* Buffer flags */       EShPoolPageAlignedBuffer,
       
   841 			/* Driver to use */      RShBufTestChannel::EOwnThread,
       
   842 			/* Summary string */     testSummary);
       
   843 		summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary);
       
   844 
       
   845 		//
       
   846 		// Print the summary...
       
   847 		//
       
   848 		TInt  nextLineBreak = summaryBufPtr.Find(_L("\n"));
       
   849 		
       
   850 		test.Next(_L("Results summary (average values for each test)"));
       
   851 		
       
   852 		while (nextLineBreak != KErrNotFound)
       
   853 			{
       
   854 			test.Printf(summaryBufPtr.Left(nextLineBreak));
       
   855 #ifndef __WINS__
       
   856 			test.Printf(_L("\n"));
       
   857 #endif
       
   858 
       
   859 			summaryBufPtr = summaryBufPtr.Mid(nextLineBreak+1);
       
   860 			nextLineBreak = summaryBufPtr.Find(_L("\n"));
       
   861 			}
       
   862 		CleanupStack::PopAndDestroy(summaryBuf);
       
   863 		}
       
   864 	test.End();
       
   865 	test.Close();
       
   866 	} // RunTestsL
       
   867 
       
   868 
       
   869 /**
       
   870  *  Main entry point.
       
   871  */
       
   872 TInt E32Main()
       
   873 	{
       
   874 	//
       
   875 	// Allocate a clean up stack and top level TRAP...
       
   876 	//
       
   877 	__UHEAP_MARK;
       
   878 	CTrapCleanup*  cleanup = CTrapCleanup::New();
       
   879 	TInt  err = KErrNoMemory;
       
   880 	
       
   881 	if (cleanup)
       
   882 		{
       
   883 		TRAP(err, RunTestsL());
       
   884         delete cleanup;
       
   885 		}
       
   886 	
       
   887 	__UHEAP_MARKEND;
       
   888 	return err;
       
   889 	} // E32Main
       
   890