sl@0: // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test/mmu/t_shbuf_perf.cpp sl@0: // sl@0: // sl@0: sl@0: /** sl@0: * @file sl@0: * sl@0: * Performance Testing of shared buffers. sl@0: * sl@0: * Runs a number of tests using descriptors and RShBuf handles and compares sl@0: * the results to see the improvements in performance. sl@0: */ sl@0: sl@0: sl@0: #define __E32TEST_EXTENSION__ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include "d_shbuf.h" sl@0: #include "t_shbuf_perfclient.h" sl@0: sl@0: sl@0: // sl@0: // Test name (and process name!)... sl@0: // sl@0: _LIT(KTestProcessName, "T_SHBUF_PERF"); sl@0: sl@0: sl@0: /** sl@0: * Global test object (must be called 'test' to match some macros)... sl@0: */ sl@0: RTest test(KTestProcessName); sl@0: sl@0: // sl@0: // Number of iterations to run for each test. The timings are worked out by sl@0: // running the test X number of times and dividing the total time by X. sl@0: // sl@0: #ifdef _DEBUG sl@0: /** sl@0: * Number of iterations to run for each test (WINS/WINSCW/Target Debug). sl@0: */ sl@0: const TInt KNumberOfIterations(50); // Used for debuging and hence not measurement. sl@0: #else sl@0: #ifdef __WINS__ sl@0: /** sl@0: * Number of iterations to run for each test (WINS/WINSCW Release). sl@0: */ sl@0: const TInt KNumberOfIterations(5000); // Proper emulator performance testing. sl@0: #else sl@0: /** sl@0: * Number of iterations to run for each test (Target Release). sl@0: */ sl@0: const TInt KNumberOfIterations(500); // Proper target performance testing. sl@0: #endif sl@0: #endif sl@0: sl@0: sl@0: TUint8 iClearCache[32768]; sl@0: sl@0: sl@0: /** sl@0: * RShBuf performance test types. sl@0: */ sl@0: enum TRShBufPerfTest sl@0: { sl@0: /** sl@0: * Send buffer from the client to the driver directly and back. sl@0: */ sl@0: ERShBufPerfTestClientToDriverReturn, sl@0: sl@0: /** sl@0: * Send buffer from the client to the driver directly one way. sl@0: */ sl@0: ERShBufPerfTestClientToDriverOneWay, sl@0: sl@0: /** sl@0: * Send buffer from the client to a second process to the driver and back. sl@0: */ sl@0: ERShBufPerfTestClientToProcessToDriverReturn, sl@0: sl@0: /** sl@0: * Send buffer from the client to a second process to the driver one way. sl@0: */ sl@0: ERShBufPerfTestClientToProcessToDriverOneWay, sl@0: sl@0: /** sl@0: * Read buffer from the driver directly and send it back. sl@0: */ sl@0: ERShBufPerfTestDriverToClientReturn, sl@0: sl@0: /** sl@0: * Read buffer from the driver directly one way. sl@0: */ sl@0: ERShBufPerfTestDriverToClientOneWay, sl@0: sl@0: /** sl@0: * Read buffer from the driver via a second process and send it back. sl@0: */ sl@0: ERShBufPerfTestDriverToProcessToClientReturn, sl@0: sl@0: /** sl@0: * Read buffer from the driver via a second process one way. sl@0: */ sl@0: ERShBufPerfTestDriverToProcessToClientOneWay sl@0: }; sl@0: sl@0: sl@0: void StartSecondProcessAndDriver(TRShBufPerfTest aTestType, sl@0: RShBufTestChannel& aLdd, sl@0: RShBufTestServerSession& aTestServer, sl@0: RThread& aTestServerThread, sl@0: TInt aDriverNum) sl@0: { sl@0: // sl@0: // If a second process is needed start this process as a child... sl@0: // sl@0: if (aTestType == ERShBufPerfTestClientToProcessToDriverReturn || sl@0: aTestType == ERShBufPerfTestClientToProcessToDriverOneWay || sl@0: aTestType == ERShBufPerfTestDriverToProcessToClientReturn || sl@0: aTestType == ERShBufPerfTestDriverToProcessToClientOneWay) sl@0: { sl@0: test.Next(_L("Start slave server process...")); sl@0: test_KErrNone(aTestServer.Connect()); sl@0: test.Next(_L("Find slave server thread...")); sl@0: test_KErrNone(aTestServerThread.Open(_L("t_shbuf_perf.exe[00000000]0001::!RShBufServer"))); sl@0: } sl@0: sl@0: // sl@0: // Open the driver (always open it as it is used to get buffers too!)... sl@0: // sl@0: TInt r = User::LoadLogicalDevice(_L("D_SHBUF_CLIENT.LDD")); sl@0: test(r == KErrNone || r == KErrAlreadyExists); sl@0: r = User::LoadLogicalDevice(_L("D_SHBUF_OWN.LDD")); sl@0: test(r == KErrNone || r == KErrAlreadyExists); sl@0: test_KErrNone(aLdd.Open(aDriverNum)); sl@0: } // StartSecondProcessAndDriver sl@0: sl@0: sl@0: void StopSecondProcessAndDriver(TRShBufPerfTest aTestType, sl@0: RShBufTestChannel& aLdd, sl@0: RShBufTestServerSession& aTestServer, sl@0: RThread& aTestServerThread) sl@0: { sl@0: // sl@0: // Close the driver.. sl@0: // sl@0: aLdd.Close(); sl@0: sl@0: if (aTestType == ERShBufPerfTestClientToProcessToDriverReturn || sl@0: aTestType == ERShBufPerfTestClientToProcessToDriverOneWay || sl@0: aTestType == ERShBufPerfTestDriverToProcessToClientReturn || sl@0: aTestType == ERShBufPerfTestDriverToProcessToClientOneWay) sl@0: { sl@0: #ifdef CAN_TRANSFER_SHBUF_TO_ANOTHER_PROCESS sl@0: test.Next(_L("Stop slave server process...")); sl@0: test_KErrNone(aTestServer.ShutdownServer()); sl@0: #endif sl@0: aTestServerThread.Close(); sl@0: aTestServer.Close(); sl@0: } sl@0: } // StopSecondProcessAndDriver sl@0: sl@0: sl@0: /** sl@0: * Print the TRShBufPerfTest enum. sl@0: */ sl@0: void PrinTRShBufPerfTestType(const TDesC& aPrefix, TRShBufPerfTest aTestType) sl@0: { sl@0: switch (aTestType) sl@0: { sl@0: case ERShBufPerfTestClientToDriverReturn: sl@0: { sl@0: test.Printf(_L("%SaTestType=ERShBufPerfTestClientToDriverReturn (%d)"), &aPrefix, aTestType); sl@0: } sl@0: break; sl@0: sl@0: case ERShBufPerfTestClientToDriverOneWay: sl@0: { sl@0: test.Printf(_L("%SaTestType=ERShBufPerfTestClientToDriverOneWay (%d)"), &aPrefix, aTestType); sl@0: } sl@0: break; sl@0: sl@0: case ERShBufPerfTestClientToProcessToDriverReturn: sl@0: { sl@0: test.Printf(_L("%SaTestType=ERShBufPerfTestClientToProcessToDriverReturn (%d)"), &aPrefix, aTestType); sl@0: } sl@0: break; sl@0: sl@0: case ERShBufPerfTestClientToProcessToDriverOneWay: sl@0: { sl@0: test.Printf(_L("%SaTestType=ERShBufPerfTestClientToProcessToDriverOneWay (%d)"), &aPrefix, aTestType); sl@0: } sl@0: break; sl@0: sl@0: case ERShBufPerfTestDriverToClientReturn: sl@0: { sl@0: test.Printf(_L("%SaTestType=ERShBufPerfTestDriverToClientReturn (%d)"), &aPrefix, aTestType); sl@0: } sl@0: break; sl@0: sl@0: case ERShBufPerfTestDriverToClientOneWay: sl@0: { sl@0: test.Printf(_L("%SaTestType=ERShBufPerfTestDriverToClientOneWay (%d)"), &aPrefix, aTestType); sl@0: } sl@0: break; sl@0: sl@0: case ERShBufPerfTestDriverToProcessToClientReturn: sl@0: { sl@0: test.Printf(_L("%SaTestType=ERShBufPerfTestDriverToProcessToClientReturn (%d)"), &aPrefix, aTestType); sl@0: } sl@0: break; sl@0: sl@0: case ERShBufPerfTestDriverToProcessToClientOneWay: sl@0: { sl@0: test.Printf(_L("%SaTestType=ERShBufPerfTestDriverToProcessToClientOneWay (%d)"), &aPrefix, aTestType); sl@0: } sl@0: break; sl@0: sl@0: default: sl@0: { sl@0: test.Printf(_L("%SaTestType= (%d)"), &aPrefix, aTestType); sl@0: } sl@0: break; sl@0: } sl@0: } // PrinTRShBufPerfTestType sl@0: sl@0: sl@0: /** sl@0: * Print the TShPoolCreateInfo object. sl@0: */ sl@0: void PrintTShPoolInfo(const TDesC& aPrefix, TShPoolInfo aShPoolInfo) sl@0: { sl@0: test.Printf(_L("%SaShPoolInfo.iBufSize=%d"), &aPrefix, aShPoolInfo.iBufSize); sl@0: test.Printf(_L("%SaShPoolInfo.iInitialBufs=%d"), &aPrefix, aShPoolInfo.iInitialBufs); sl@0: test.Printf(_L("%SaShPoolInfo.iMaxBufs=%d"), &aPrefix, aShPoolInfo.iMaxBufs); sl@0: test.Printf(_L("%SaShPoolInfo.iGrowTriggerRatio=%d"), &aPrefix, aShPoolInfo.iGrowTriggerRatio); sl@0: test.Printf(_L("%SaShPoolInfo.iGrowByRatio=%d"), &aPrefix, aShPoolInfo.iGrowByRatio); sl@0: test.Printf(_L("%SaShPoolInfo.iShrinkHysteresisRatio=%d"), &aPrefix, aShPoolInfo.iShrinkHysteresisRatio); sl@0: test.Printf(_L("%SaShPoolInfo.iAlignment=%d (0x%x)"), &aPrefix, aShPoolInfo.iAlignment, sl@0: 2 << (aShPoolInfo.iAlignment - 1)); sl@0: test.Printf(_L("%SaShPoolInfo.iFlags=0x%08x"), &aPrefix, aShPoolInfo.iFlags); sl@0: } // PrintTShPoolInfo sl@0: sl@0: sl@0: void TestSharedBufferPerformanceL(TRShBufPerfTest aTestType, sl@0: TInt aMinAllocSize, TInt aMaxAllocSize, sl@0: TInt aBufferSizeSteps, TInt aTotalIterations, sl@0: TShPoolCreateFlags aFlags, TInt aDriverNum, sl@0: TDes& aSummaryBuf) sl@0: { sl@0: TShPoolInfo shPoolInfo; sl@0: sl@0: shPoolInfo.iBufSize = aMaxAllocSize; sl@0: shPoolInfo.iInitialBufs = 5; sl@0: shPoolInfo.iMaxBufs = 5; sl@0: shPoolInfo.iGrowTriggerRatio = 0; sl@0: shPoolInfo.iGrowByRatio = 0; sl@0: shPoolInfo.iShrinkHysteresisRatio = 0; sl@0: shPoolInfo.iAlignment = 9; sl@0: shPoolInfo.iFlags = aFlags; sl@0: sl@0: // sl@0: // Start test and print the parameters... sl@0: // sl@0: test.Printf(_L(" Test parameters:")); sl@0: PrinTRShBufPerfTestType(_L(" "), aTestType); sl@0: PrintTShPoolInfo(_L(" "), shPoolInfo); sl@0: test.Printf(_L(" aMinAllocSize=%d"), aMinAllocSize); sl@0: test.Printf(_L(" aMaxAllocSize=%d"), aMaxAllocSize); sl@0: test.Printf(_L(" aBufferSizeSteps=%d"), aBufferSizeSteps); sl@0: test.Printf(_L(" aTotalIterations=%d"), aTotalIterations); sl@0: test.Printf(_L(" aDriverNum=%d"), aDriverNum); sl@0: sl@0: // sl@0: // Initialise second process and/or open the driver... sl@0: // sl@0: RShBufTestServerSession testServer; sl@0: RShBufTestChannel shBufLdd; sl@0: RThread testServerThread; sl@0: sl@0: StartSecondProcessAndDriver(aTestType, shBufLdd, testServer, testServerThread, aDriverNum); sl@0: CleanupClosePushL(testServer); sl@0: sl@0: // sl@0: // Allocate a RShPool... sl@0: // sl@0: RShPool shPool; sl@0: sl@0: if (aFlags & EShPoolPageAlignedBuffer) sl@0: { sl@0: TShPoolCreateInfo shPoolCreateInfo(TShPoolCreateInfo::EPageAlignedBuffer, sl@0: shPoolInfo.iBufSize, shPoolInfo.iInitialBufs); sl@0: test_KErrNone(shPool.Create(shPoolCreateInfo, KDefaultPoolHandleFlags)); sl@0: CleanupClosePushL(shPool); sl@0: sl@0: test_KErrNone(shPool.SetBufferWindow(-1, ETrue)); sl@0: shPoolInfo.iAlignment = 12; sl@0: } sl@0: else if (aFlags & EShPoolNonPageAlignedBuffer) sl@0: { sl@0: TShPoolCreateInfo shPoolCreateInfo(TShPoolCreateInfo::ENonPageAlignedBuffer, sl@0: shPoolInfo.iBufSize, shPoolInfo.iInitialBufs, sl@0: shPoolInfo.iAlignment); sl@0: test_KErrNone(shPool.Create(shPoolCreateInfo, KDefaultPoolHandleFlags)); sl@0: CleanupClosePushL(shPool); sl@0: } sl@0: sl@0: test(shPool.Handle() != 0); sl@0: sl@0: if (aTestType == ERShBufPerfTestClientToProcessToDriverReturn || sl@0: aTestType == ERShBufPerfTestClientToProcessToDriverOneWay || sl@0: aTestType == ERShBufPerfTestDriverToProcessToClientReturn || sl@0: aTestType == ERShBufPerfTestDriverToProcessToClientOneWay) sl@0: { sl@0: test_KErrNone(testServer.OpenRShBufPool(shPool.Handle(), shPoolInfo)); sl@0: } sl@0: else sl@0: { sl@0: test_KErrNone(shBufLdd.OpenUserPool(shPool.Handle(), shPoolInfo)); sl@0: } sl@0: sl@0: // sl@0: // Run the test iterations and time the result... sl@0: // sl@0: TInt fastTimerFreq; sl@0: HAL::Get(HALData::EFastCounterFrequency, fastTimerFreq); sl@0: TReal ticksPerMicroSec = 1.0E-6 * fastTimerFreq; sl@0: sl@0: // Bind this thread to CPU 0. This is so that timer deltas don't drift from sl@0: // scheduling - else, it causes spurious failures. sl@0: if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0) > 1) sl@0: (void)UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny *)0, 0); sl@0: sl@0: TReal64 totalLengthOfDesTest(0); sl@0: TReal64 totalLengthOfShBufTest(0); sl@0: TInt breakevenPoint = 0; sl@0: TInt bufferStep; sl@0: sl@0: test.Printf(_L("BufSize\tTotalTime(Des)\tAvTime(Des)\tTotalTime(ShBuf)\tAvTime(ShBuf)\tSpeedUp(%%)")); sl@0: #ifndef __WINS__ sl@0: test.Printf(_L("\n")); sl@0: #endif sl@0: for (bufferStep = 0; bufferStep < aBufferSizeSteps; bufferStep++) sl@0: { sl@0: // sl@0: // Run a single buffer size through these tests... sl@0: // sl@0: TInt bufferSize = aMinAllocSize + sl@0: (((aMaxAllocSize - aMinAllocSize) * bufferStep) / (aBufferSizeSteps-1)); sl@0: TUint32 startDesTest = 0; sl@0: TUint32 startShBufTest = 0; sl@0: TInt iteration; sl@0: sl@0: TUint32 lengthOfDesTest=0; sl@0: sl@0: // sl@0: // Test normal descriptor methods first... sl@0: // sl@0: sl@0: for (iteration = 0; iteration < aTotalIterations; iteration++) sl@0: { sl@0: // sl@0: // Allocate a local buffer for this test... sl@0: // sl@0: HBufC8* singleBuf = HBufC8::NewLC(bufferSize); sl@0: sl@0: startDesTest = User::FastCounter(); sl@0: test(singleBuf != NULL); sl@0: sl@0: TPtr8 singleBufPtr = singleBuf->Des(); sl@0: singleBufPtr.SetLength(bufferSize); sl@0: sl@0: // sl@0: // Are we sending or receiving? sl@0: // sl@0: if (aTestType == ERShBufPerfTestClientToDriverOneWay || sl@0: aTestType == ERShBufPerfTestClientToProcessToDriverOneWay) sl@0: { sl@0: #ifdef _DEBUG // do not cache sl@0: TUint8* bufptr = const_cast(singleBuf->Ptr()); sl@0: sl@0: // We are sending... sl@0: for (TInt pos = 0; pos < bufferSize; pos++) sl@0: { sl@0: bufptr[pos] = (TUint8)(pos%32); sl@0: } sl@0: // clear cache sl@0: memset(iClearCache, 0xFF, sizeof(iClearCache)); sl@0: #endif sl@0: } sl@0: sl@0: sl@0: // sl@0: // Either send to the driver or to the other process... sl@0: // sl@0: if (aTestType == ERShBufPerfTestClientToDriverReturn) sl@0: { sl@0: test_KErrNone(shBufLdd.FromTPtr8ProcessAndReturn(singleBufPtr, bufferSize)); sl@0: test(singleBufPtr.Length() == bufferSize-2); sl@0: } sl@0: else if (aTestType == ERShBufPerfTestClientToDriverOneWay) sl@0: { sl@0: test_KErrNone(shBufLdd.FromTPtr8ProcessAndRelease(singleBufPtr)); sl@0: } sl@0: else if (aTestType == ERShBufPerfTestClientToProcessToDriverReturn) sl@0: { sl@0: test_KErrNone(testServer.FromTPtr8ProcessAndReturn(singleBufPtr, bufferSize)); sl@0: test(singleBufPtr.Length() == bufferSize-2); sl@0: } sl@0: else if (aTestType == ERShBufPerfTestClientToProcessToDriverOneWay) sl@0: { sl@0: test_KErrNone(testServer.FromTPtr8ProcessAndRelease(singleBufPtr)); sl@0: } sl@0: sl@0: lengthOfDesTest += (User::FastCounter() - startDesTest); sl@0: sl@0: CleanupStack::PopAndDestroy(singleBuf); sl@0: } sl@0: sl@0: TInt64 lengthOfShBufTest = 0; sl@0: sl@0: // sl@0: // Test ShBuf methods... sl@0: // sl@0: for (iteration = 0; iteration < aTotalIterations; iteration++) sl@0: { sl@0: RShBuf shBuf; sl@0: TInt* lengthPtr; sl@0: // sl@0: // Are we sending or receiving? sl@0: // sl@0: startShBufTest = User::FastCounter(); sl@0: if (aTestType == ERShBufPerfTestClientToDriverOneWay || sl@0: aTestType == ERShBufPerfTestClientToProcessToDriverOneWay) sl@0: { sl@0: // We are sending... sl@0: sl@0: // sl@0: // Allocate a buffer (using a pool)... sl@0: // sl@0: sl@0: test_KErrNone(shBuf.Alloc(shPool)); sl@0: TUint8* shBufPtr = shBuf.Ptr(); sl@0: sl@0: lengthPtr = (TInt*)(&shBufPtr[0]); // First 32bit word is length! sl@0: *lengthPtr = bufferSize; sl@0: #ifdef _DEBUG // do not cache sl@0: for (TInt pos = 4; pos < bufferSize; pos++) sl@0: { sl@0: shBufPtr[pos] = (TUint8)(pos%32); sl@0: } sl@0: // clear cache sl@0: memset(iClearCache, 0xFF, sizeof(iClearCache)); sl@0: #endif sl@0: } sl@0: sl@0: sl@0: // sl@0: // Either send to the driver or to the other process... sl@0: // sl@0: if (aTestType == ERShBufPerfTestClientToDriverReturn) sl@0: { sl@0: TInt retHandle; sl@0: retHandle = shBufLdd.FromRShBufProcessAndReturn(bufferSize); sl@0: test_Compare(retHandle, >, 0); sl@0: shBuf.SetReturnedHandle(retHandle); sl@0: sl@0: TInt* retPtr = (TInt*)shBuf.Ptr(); sl@0: sl@0: test(*retPtr == bufferSize-2); sl@0: sl@0: shBuf.Close(); sl@0: } sl@0: else if (aTestType == ERShBufPerfTestClientToDriverOneWay) sl@0: { sl@0: test_KErrNone(shBufLdd.FromRShBufProcessAndRelease(shBuf.Handle())); sl@0: } sl@0: else if (aTestType == ERShBufPerfTestClientToProcessToDriverReturn) sl@0: { sl@0: test_KErrNone(testServer.FromRShBufProcessAndReturn(shBuf, bufferSize)); sl@0: TInt* retPtr = (TInt*)shBuf.Ptr(); sl@0: sl@0: test(*retPtr == bufferSize-2); sl@0: sl@0: shBuf.Close(); sl@0: } sl@0: else if (aTestType == ERShBufPerfTestClientToProcessToDriverOneWay) sl@0: { sl@0: test_KErrNone(testServer.FromRShBufProcessAndRelease(shBuf)); sl@0: } sl@0: lengthOfShBufTest += (User::FastCounter() - startShBufTest); sl@0: } sl@0: sl@0: // sl@0: // Print results of this buffer size... sl@0: // sl@0: sl@0: test.Printf(_L("%d\t%10.2lfusec\t%10.2lfusec\t%.2f%%"), bufferSize, sl@0: I64REAL(lengthOfDesTest) / (TReal(aTotalIterations) * ticksPerMicroSec), sl@0: I64REAL(lengthOfShBufTest) / (TReal(aTotalIterations) * ticksPerMicroSec), sl@0: ((100.0 / I64REAL(lengthOfShBufTest)) * I64REAL(lengthOfDesTest)) - 100.0); sl@0: #ifndef __WINS__ sl@0: test.Printf(_L("\n")); sl@0: #endif sl@0: sl@0: totalLengthOfDesTest += lengthOfDesTest; sl@0: totalLengthOfShBufTest += lengthOfShBufTest; sl@0: sl@0: // sl@0: // Track the breakeven point (e.g. the buffer size at which RShBuf is sl@0: // quicker). This is normally when the number of bytes copied by the sl@0: // descriptor takes longer than the handling of the RShBuf. sl@0: // sl@0: if (lengthOfShBufTest >= lengthOfDesTest) sl@0: { sl@0: breakevenPoint = aMinAllocSize + sl@0: (((aMaxAllocSize - aMinAllocSize) * (bufferStep + 1)) / (aBufferSizeSteps-1)); sl@0: } sl@0: } sl@0: sl@0: // sl@0: // Display timing information... sl@0: // sl@0: test.Printf(_L("Average\t%10.2lfusec\t%10.2lfusec\t%.2f%%"), sl@0: I64REAL(totalLengthOfDesTest) / (TReal(aTotalIterations * aBufferSizeSteps) * ticksPerMicroSec), sl@0: I64REAL(totalLengthOfShBufTest) / (TReal(aTotalIterations * aBufferSizeSteps) * ticksPerMicroSec), sl@0: ((100.0 / I64REAL(totalLengthOfShBufTest)) * I64REAL(totalLengthOfDesTest)) - 100.0); sl@0: #ifndef __WINS__ sl@0: test.Printf(_L("\n")); sl@0: #endif sl@0: sl@0: // sl@0: // Record summary info for later use... sl@0: // sl@0: aSummaryBuf.Zero(); sl@0: sl@0: if (breakevenPoint <= aMaxAllocSize) sl@0: { sl@0: aSummaryBuf.AppendFormat(_L("%10.2lfusec\t%10.2lfusec\t%.2f%%%%\t%d"), sl@0: I64REAL(totalLengthOfDesTest) / TReal(aTotalIterations * aBufferSizeSteps * ticksPerMicroSec), sl@0: I64REAL(totalLengthOfShBufTest) / TReal(aTotalIterations * aBufferSizeSteps * ticksPerMicroSec), sl@0: ((100.0 / I64REAL(totalLengthOfShBufTest)) * I64REAL(totalLengthOfDesTest)) - 100.0, sl@0: breakevenPoint); sl@0: } sl@0: else sl@0: { sl@0: aSummaryBuf.AppendFormat(_L("%10.2lfusec\t%10.2lfusec\t%.2f%%%%\tFailed to breakeven"), sl@0: I64REAL(totalLengthOfDesTest) / TReal(aTotalIterations * aBufferSizeSteps * ticksPerMicroSec), sl@0: I64REAL(totalLengthOfShBufTest) / TReal(aTotalIterations * aBufferSizeSteps * ticksPerMicroSec), sl@0: ((100.0 / I64REAL(totalLengthOfShBufTest)) * I64REAL(totalLengthOfDesTest)) - 100.0); sl@0: } sl@0: sl@0: // sl@0: // Clean up... sl@0: // sl@0: TInt shPoolHandle = shPool.Handle(); sl@0: CleanupStack::PopAndDestroy(&shPool); sl@0: sl@0: if (aTestType == ERShBufPerfTestClientToProcessToDriverReturn || sl@0: aTestType == ERShBufPerfTestClientToProcessToDriverOneWay || sl@0: aTestType == ERShBufPerfTestDriverToProcessToClientReturn || sl@0: aTestType == ERShBufPerfTestDriverToProcessToClientOneWay) sl@0: { sl@0: testServer.CloseRShBufPool(shPoolHandle); sl@0: } sl@0: else sl@0: { sl@0: test_KErrNone(shBufLdd.CloseUserPool()); sl@0: } sl@0: sl@0: // sl@0: // Shutdown the second process and/or close the driver. sl@0: // sl@0: CleanupStack::Pop(&testServer); sl@0: StopSecondProcessAndDriver(aTestType, shBufLdd, testServer, testServerThread); sl@0: } // TestSharedBufferPerformanceL sl@0: sl@0: sl@0: /** sl@0: * Main test process which performs the testing. sl@0: */ sl@0: void RunTestsL() sl@0: { sl@0: // sl@0: // Setup the test... sl@0: // sl@0: test.Title(); sl@0: sl@0: test.Start(_L("Check for Shared Buffers availability")); sl@0: TInt r; sl@0: RShPool pool; sl@0: TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 100, 10); sl@0: r = pool.Create(inf, KDefaultPoolHandleFlags); sl@0: if (r == KErrNotSupported) sl@0: { sl@0: test.Printf(_L("Not supported by this memory model.\n")); sl@0: } sl@0: else sl@0: { sl@0: test_KErrNone(r); sl@0: pool.Close(); sl@0: sl@0: test.Next(_L("Performance test shared buffers")); sl@0: sl@0: // sl@0: // Create a summary buffer to hold the average speeds of different pools... sl@0: // sl@0: HBufC* summaryBuf = HBufC::NewLC(16 * 128 * 2); sl@0: TPtr summaryBufPtr = summaryBuf->Des(); sl@0: TBuf<128> testName, testSummary; sl@0: sl@0: summaryBufPtr.Append(_L("Test Type\tAverage Time(Des)\tAverage Time(ShBuf)\tAverage SpeedUp(%%)\tBreakeven Buffer Size\n")); sl@0: sl@0: // sl@0: // Run tests... sl@0: // sl@0: testName.Copy(_L("Client->Driver (non-aligned/client-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToDriverOneWay, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolNonPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EClientThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Driver (aligned/client-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToDriverOneWay, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EClientThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Driver (non-aligned/own-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToDriverOneWay, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolNonPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EOwnThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Driver (aligned/own-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToDriverOneWay, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EOwnThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Driver->Client (non-aligned/client-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToDriverReturn, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolNonPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EClientThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Driver->Client (aligned/client-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToDriverReturn, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EClientThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Driver->Client (non-aligned/own-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToDriverReturn, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolNonPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EOwnThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Driver->Client (aligned/own-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToDriverReturn, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EOwnThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Process->Driver (non-aligned/client-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToProcessToDriverOneWay, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolNonPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EClientThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Process->Driver (aligned/client-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToProcessToDriverOneWay, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EClientThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Process->Driver (non-aligned/own-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToProcessToDriverOneWay, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolNonPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EOwnThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Process->Driver (aligned/own-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToProcessToDriverOneWay, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EOwnThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Process->Driver->Process->Client (non-aligned/client-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToProcessToDriverReturn, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolNonPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EClientThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Process->Driver->Process->Client (aligned/client-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToProcessToDriverReturn, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EClientThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Process->Driver->Process->Client (non-aligned/own-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToProcessToDriverReturn, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolNonPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EOwnThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: testName.Copy(_L("Client->Process->Driver->Process->Client (aligned/own-thread)")); sl@0: test.Next(testName); sl@0: TestSharedBufferPerformanceL( sl@0: /* Test type */ ERShBufPerfTestClientToProcessToDriverReturn, sl@0: /* Min Alloc size */ 64, sl@0: /* Max Alloc size */ 8192, sl@0: /* Buffer size steps */ 128, sl@0: /* Total iterations */ KNumberOfIterations, sl@0: /* Buffer flags */ EShPoolPageAlignedBuffer, sl@0: /* Driver to use */ RShBufTestChannel::EOwnThread, sl@0: /* Summary string */ testSummary); sl@0: summaryBufPtr.AppendFormat(_L("%S\t%S\n"), &testName, &testSummary); sl@0: sl@0: // sl@0: // Print the summary... sl@0: // sl@0: TInt nextLineBreak = summaryBufPtr.Find(_L("\n")); sl@0: sl@0: test.Next(_L("Results summary (average values for each test)")); sl@0: sl@0: while (nextLineBreak != KErrNotFound) sl@0: { sl@0: test.Printf(summaryBufPtr.Left(nextLineBreak)); sl@0: #ifndef __WINS__ sl@0: test.Printf(_L("\n")); sl@0: #endif sl@0: sl@0: summaryBufPtr = summaryBufPtr.Mid(nextLineBreak+1); sl@0: nextLineBreak = summaryBufPtr.Find(_L("\n")); sl@0: } sl@0: CleanupStack::PopAndDestroy(summaryBuf); sl@0: } sl@0: test.End(); sl@0: test.Close(); sl@0: } // RunTestsL sl@0: sl@0: sl@0: /** sl@0: * Main entry point. sl@0: */ sl@0: TInt E32Main() sl@0: { sl@0: // sl@0: // Allocate a clean up stack and top level TRAP... sl@0: // sl@0: __UHEAP_MARK; sl@0: CTrapCleanup* cleanup = CTrapCleanup::New(); sl@0: TInt err = KErrNoMemory; sl@0: sl@0: if (cleanup) sl@0: { sl@0: TRAP(err, RunTestsL()); sl@0: delete cleanup; sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: return err; sl@0: } // E32Main sl@0: