First public contribution.
1 // Copyright (c) 2006-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test/defrag/perf/t_perf.cpp
15 // t_pagemove loads and opens the logical device driver ("D_PAGEMOVE.LDD").
16 // Following this, it requests that the driver attempt to move various kinds of pages
17 // directly amd notes time taken for each of the moves.
18 // Platforms/Drives/Compatibility:
19 // Hardware only. No defrag support on emulator.
20 // 2 - Test the performance of moving user chunk pages
21 // 3 - Test the performance of moving dll pages
22 // 4 - Test the performance of moving kernel stack pages
26 //! @SYMTestCaseID KBASE-T_DEFRAGPERF-0601
29 //! @SYMTestCaseDesc Testing performace of page moving
30 //! @SYMTestActions 1 - Test the performance of moving code chunk pages
31 //! @SYMTestExpectedResults Finishes if the system behaves as expected, panics otherwise
32 //! @SYMTestPriority High
33 //! @SYMTestStatus Implemented
34 //--------------------------------------------------------------------------------------------------
35 #define __E32TEST_EXTENSION__
38 #include <e32std_private.h>
40 #include "..\d_pagemove.h"
41 #include "..\..\mmu\mmudetect.h"
45 LOCAL_D RTest test(_L("T_DEFRAGPERF"));
47 const TPtrC KLddFileName=_L("D_PAGEMOVE.LDD");
49 const TUint KRepetitions=50;
50 const TUint KPageMoves = 2000; // default to moving a page 2000 times
55 #define DEFRAG_CHUNK_MAX (4 * 1024 * 1024)
56 #define DEFRAG_CHUNK_MIN (1 * 1024 * 1024)
60 #define PROC_INCREMENTS 10
62 _LIT(BaseFileName, "t_defragtestperf");
63 _LIT(BaseFileNameExt, ".exe");
65 LOCAL_C void TestUserDataMove(RPageMove& pagemove)
72 timer.CalibrateTimer(test);
74 size = DEFRAG_CHUNK_MAX;
76 while (size > DEFRAG_CHUNK_MIN)
78 /* Create a local chunk */
79 r = chunk.CreateLocal(size,size);
82 TEST_PRINTF(_L("Created %dMB chunk\n"), size/(1024 * 1024));
90 /* Initialise the Chunk */
91 TUint8* base = (TUint8 *)chunk.Base();
92 for (TUint i = 0; i < size/sizeof(*base); i++)
98 TEST_PRINTF(_L("Starting to move chunk pages (%x %d) ...\n"), chunk.Base(), size);
100 for (; j < KRepetitions; j++)
103 base = (TUint8 *)chunk.Base();
107 test_KErrNone(pagemove.TryMovingUserPage(base));
112 test(timer.StopTimer(test) > 0);
115 DTime_t average, max, min, delay;
116 TEST_PRINTF(_L("Finished moving chunk pages\n"));
117 average = timer.GetResult(max, min, delay);
118 test.Printf(_L("Fast counter ticks to move %d chunk pages: Av %d Min %d Max %d (Overhead %d)\n"), size/gPageSize, average, min, max, delay);
119 test.Printf(_L("Average of %d ticks to move one page\n\n"), average / (size/gPageSize));
121 base = (TUint8 *)chunk.Base();
122 for (TUint i = 0; i < size/sizeof(*base); i++)
124 test_Equal((TUint8)i, base[i]);
128 TInt CreateProc(RProcess& aProcess, TInt aIndex)
131 TRequestStatus status;
134 filename.Format(_L("%S%S"), &BaseFileName, &BaseFileNameExt);
135 TInt r=aProcess.Create(filename, command);
139 test.Printf(_L("Process %d could not be loaded!\n"), aIndex);
143 aProcess.Rendezvous(status);
145 User::WaitForRequest(status);
149 void KillAllProcs(RProcess *aProcess, TInt aNum, TInt aError)
152 for (i = 0; i < aNum; i++)
154 aProcess[i].Kill(aError);
158 TInt TestDLL(int aNumProcess, RPageMove& aPageMove)
163 process = new RProcess[aNumProcess];
168 TEST_PRINTF(_L("Starting %d processes\n"), aNumProcess);
169 for (TInt i = 0; i < aNumProcess; i++)
171 retVal = CreateProc(process[i], i);
172 if (retVal != KErrNone)
175 KillAllProcs(process, i, KErrNone);
181 /* Now Map the DLL to this process and Run the tests */
183 TEST_PRINTF(_L("Main Proc Loading The DLL ... \n"));
184 retVal = dll.LoadTheLib(0, test);
186 if (retVal != KErrNone)
188 KillAllProcs(process, aNumProcess, retVal);
189 test.Printf(_L("Error (%d) Loading The DLLs!\n"), retVal);
194 retVal = dll.TestDLLPerformance(0, aPageMove, test);
195 KillAllProcs(process, aNumProcess, KErrNone);
202 * Is this portable .. Hell No, so dont ask.
204 #define isNum(a) ((a) >= '0' && (a) <= '9')
206 TInt atoi(const TBuf<64>& buf, TInt pos)
210 TInt len = User::CommandLineLength();
216 test.Printf(_L("Invalid Argument!\n"));
219 num = (num * 10) + (ch - '0');
224 void TestCodeChunkMoving(RPageMove aPageMove)
226 _LIT(ELOCL_DEFAULT, "");
227 _LIT(ELOCLUS, "T_LOCLUS_RAM");
229 // Change locale and move the locale page repeatedly
230 // On multiple memmodel this is the easiest way to move CodeChunk pages.
233 // Setup the RAM loaded US Locale DLL
234 test_KErrNone(UserSvr::ChangeLocale(ELOCLUS));
239 // Now get a pointer to some data in the DLL. This will be used to move a
241 SLocaleLanguage localeLanguage;
242 TPckg<SLocaleLanguage> localeLanguageBuf(localeLanguage);
243 TInt r = RProperty::Get(KUidSystemCategory, KLocaleLanguageKey, localeLanguageBuf);
245 TAny* localeAddr = (TAny *) localeLanguage.iDateSuffixTable;
246 test(localeAddr != NULL);
249 // Now we have a RAM loaded locale page determine the performance
250 TEST_PRINTF(_L("Start moving a RAM loaded locale page\n"));
253 timer.CalibrateTimer(test);
255 for (; reps < KRepetitions; reps++)
259 for (; i < KPageMoves; i++)
261 test_KErrNone(aPageMove.TryMovingLocaleDll(localeAddr));
263 test_Compare(timer.StopTimer(test), >, 0);
265 DTime_t max, min, delay;
266 TUint average = timer.GetResult(max, min, delay);
267 test.Printf(_L("Fast counter ticks to move code chunk page %d times: Av %d Min %d Max %d (Overhead %d)\n"), KPageMoves, average, min, max, delay);
268 test.Printf(_L("Average of %d ticks to move one page\n\n"), average/ KPageMoves);
271 // Reset the Locale to the default
272 r=UserSvr::ChangeLocale(ELOCL_DEFAULT);
277 GLDEF_C TInt E32Main()
281 _LIT(KStart,"-procs=");
282 const TInt offset = KStart().Length();
285 User::CommandLine(cmd);
289 test.Printf(_L("This test requires an MMU\n"));
292 test.Start(_L("Load test LDD"));
293 TInt r=User::LoadLogicalDevice(KLddFileName);
294 test(r==KErrNone || r==KErrAlreadyExists);
296 r=UserHal::PageSizeInBytes(gPageSize);
300 test.Next(_L("Open test LDD"));
305 timer.CalibrateTimer(test);
306 test.Printf(_L("\nFast Counter Frequency = %dHz \n\n"), timer.iFastCounterFreq);
309 test.Next(_L("Test performance of moving code chunk pages"));
310 TestCodeChunkMoving(pagemove);
314 * Create a large chunk ~ 4MB (> L2 Cache) and move pages from that chunk
316 test.Next(_L("Test performance of moving user chunk pages"));
317 TestUserDataMove(pagemove);
320 test.Next(_L("Test performance of moving dll pages"));
321 TInt pos = cmd.FindF(KStart);
325 procs = atoi(cmd, pos);
328 if (procs < MIN_PROCS)
330 else if (procs > MAX_PROCS)
335 test.Printf(_L("Testing with %d Processes mapping a DLL\n"), i);
336 TestDLL(i, pagemove);
341 if (i + PROC_INCREMENTS >= procs)
344 i += PROC_INCREMENTS;
347 if ((MemModelAttributes()&EMemModelTypeMask) != EMemModelTypeFlexible)
349 test.Next(_L("Test performance of moving kernel stack pages"));
350 r = pagemove.TestKernelDataMovePerformance();
354 test.Next(_L("Close test LDD"));
357 User::FreeLogicalDevice(KLddFileName);