|
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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // f32test\demandpaging\t_pagestress.cpp |
|
15 // Demand Paging Stress Tests |
|
16 // t_pagestress.exe basically attempts to cause large ammounts of paging by calling |
|
17 // functions (256) which are alligned on a page boundary from multiple threads. |
|
18 // There are mulitple versions of t_pagestress installed on a test system to test rom |
|
19 // and code paging from various media types. |
|
20 // Usage: |
|
21 // t_pagestress and t_pagestress_rom |
|
22 // Common command lines: |
|
23 // t_pagestress lowmem |
|
24 // debug - switch on debugging information |
|
25 // silent - no output to the screen or serial port |
|
26 // check - check the allignments |
|
27 // single - run the tests in a single thread |
|
28 // multiple <numThreads> - run the tests in multiple threads where <numThreads> |
|
29 // interleave - force thread interleaving |
|
30 // prio - each thread reschedules in between each function call, causes lots of context changes |
|
31 // media - perform media access during the tests, very stressful |
|
32 // lowmem - low memory tests |
|
33 // forward - patern in which to execute function calls |
|
34 // backward - patern in which to execute function calls |
|
35 // random - patern in which to execute function calls |
|
36 // all - patern in which to execute function calls (forward, backward and random) |
|
37 // inst - for debugging a parameter passed to a spawned exe to give it an id. |
|
38 // iters <count> - the number of times to loop (a '-' means run forever) |
|
39 // t_pagestress causes a large ammount of paging by repeatedly calling |
|
40 // 256 functions which have been aligned on page boundaries from |
|
41 // multiple threads. |
|
42 // 1 - a single thread calling all functions |
|
43 // 2 - Multiple threads calling all functions |
|
44 // 3 - Multiple threads calling all functions with a priority change |
|
45 // after each function call |
|
46 // 4 - Multiple threads calling all functions with background |
|
47 // media activity |
|
48 // 5 - Multiple threads calling all functions with media activity and |
|
49 // a priority change after each function call |
|
50 // 6 - Multiple threads calling all functions with process interleave |
|
51 // 7 - Multiple threads calling all functions with process interleave |
|
52 // and a priority change after each function call |
|
53 // 8 - Multiple threads calling all functions with process interleave |
|
54 // media acess and a priority change after each function call |
|
55 // 9 - Multiple threads calling all functions with low available memory |
|
56 // 10 - Multiple threads calling all functions with low available memory, |
|
57 // starting with initial free ram. |
|
58 // |
|
59 // |
|
60 |
|
61 //! @SYMTestCaseID KBASE-T_PAGESTRESS-0327 |
|
62 //! @SYMTestType UT |
|
63 //! @SYMPREQ PREQ1110 |
|
64 //! @SYMTestCaseDesc Demand Paging Stress Tests |
|
65 //! @SYMTestActions 0 - Check the alignment of all functions |
|
66 //! @SYMTestExpectedResults All tests should pass. |
|
67 //! @SYMTestPriority High |
|
68 //! @SYMTestStatus Implemented |
|
69 |
|
70 #include <e32test.h> |
|
71 RTest test(_L("T_PAGESTRESS")); |
|
72 |
|
73 #include <e32rom.h> |
|
74 #include <u32hal.h> |
|
75 #include <f32file.h> |
|
76 #include <f32dbg.h> |
|
77 #include <e32msgqueue.h> |
|
78 #include <e32math.h> |
|
79 |
|
80 #include "testdefs.h" |
|
81 |
|
82 #ifdef __X86__ |
|
83 #define TEST_ON_UNPAGED |
|
84 #endif |
|
85 |
|
86 |
|
87 /* The following line will cause t_pagestress.h to declare an array of function |
|
88 * pointers to page boundary aligned functions that we can use in this test... |
|
89 */ |
|
90 #define TPS_DECLARE_ARRAY |
|
91 #include "t_pagestress.h" |
|
92 |
|
93 TBool TestDebug = EFalse; |
|
94 TBool TestSilent = EFalse; |
|
95 TBool TestExit = EFalse; |
|
96 |
|
97 TBool TestCheck = EFalse; |
|
98 TBool TestSingle = EFalse; |
|
99 TBool TestMultiple = EFalse; |
|
100 TBool TestForever = EFalse; |
|
101 TInt TestMaxLoops = 20; |
|
102 TInt TestMultipleThreadCount = 50; |
|
103 TInt TestInstanceId = 0; |
|
104 |
|
105 #define TEST_INTERLEAVE_PRIO EPriorityMore//EPriorityRealTime //23 // KNandThreadPriority - 1 |
|
106 TBool TestInterleave = EFalse; |
|
107 TBool TestWeAreTheTestBase = EFalse; |
|
108 TBool TestBootedFromMmc = EFalse; |
|
109 TInt DriveNumber=-1; // Parameter - Which drive? -1 = autodetect. |
|
110 #define TEST_NONE 0x0 |
|
111 #define TEST_FORWARD 0x2 |
|
112 #define TEST_BACKWARD 0x4 |
|
113 #define TEST_RANDOM 0x8 |
|
114 #define TEST_ALL (TEST_RANDOM | TEST_BACKWARD | TEST_FORWARD) |
|
115 TUint32 TestWhichTests = TEST_ALL; |
|
116 TBuf<32> TestNameBuffer; |
|
117 TBool TestPrioChange = ETrue; |
|
118 TBool TestStopMedia = EFalse; |
|
119 TBool TestMediaAccess = EFalse; |
|
120 #define TEST_LM_NUM_FREE 0 |
|
121 #define TEST_LM_BLOCKSIZE 1 |
|
122 #define TEST_LM_BLOCKS_FREE 4 |
|
123 TBool TestLowMem = EFalse; |
|
124 RPageStressTestLdd Ldd; |
|
125 TInt TestPageSize = 4096; |
|
126 RSemaphore TestMultiSem; |
|
127 RMsgQueue<TBuf <64> > TestMsgQueue; |
|
128 TBool TestIsDemandPaged = ETrue; |
|
129 |
|
130 |
|
131 #define TEST_NEXT(__args) \ |
|
132 if (!TestSilent)\ |
|
133 test.Next __args; |
|
134 |
|
135 #define DBGS_PRINT(__args)\ |
|
136 if (!TestSilent)\ |
|
137 test.Printf __args ; |
|
138 |
|
139 #define DBGD_PRINT(__args)\ |
|
140 if (TestDebug)\ |
|
141 test.Printf __args ;\ |
|
142 |
|
143 #define DEBUG_PRINT(__args)\ |
|
144 if (!TestSilent)\ |
|
145 {\ |
|
146 if (aMsgQueue && aBuffer && aTheSem)\ |
|
147 {\ |
|
148 aBuffer->Zero();\ |
|
149 aBuffer->Format __args ;\ |
|
150 aTheSem->Wait();\ |
|
151 aMsgQueue->SendBlocking(*aBuffer);\ |
|
152 aTheSem->Signal();\ |
|
153 }\ |
|
154 else\ |
|
155 {\ |
|
156 test.Printf __args ;\ |
|
157 }\ |
|
158 } |
|
159 |
|
160 #define RUNTEST(__test, __error)\ |
|
161 if (!TestSilent)\ |
|
162 test(__test == __error);\ |
|
163 else\ |
|
164 __test; |
|
165 |
|
166 #define RUNTEST1(__test)\ |
|
167 if (!TestSilent)\ |
|
168 test(__test); |
|
169 |
|
170 #define DEBUG_PRINT1(__args)\ |
|
171 if (TestDebug)\ |
|
172 {\ |
|
173 DEBUG_PRINT(__args)\ |
|
174 } |
|
175 |
|
176 // |
|
177 // CheckAlignments |
|
178 // |
|
179 // The following functions wanders through the function pointer array |
|
180 // declared in t_pagestress.h and ensures that the alignment has worked, |
|
181 // (a good start!) and then calls each of the functions in turn to |
|
182 // ensure that they work, simple first sanity check test. |
|
183 // |
|
184 |
|
185 TInt CheckAlignments() |
|
186 { |
|
187 // now it's time to play with the array of function pointers... |
|
188 TInt seed = 1; |
|
189 TUint32 index = 0; |
|
190 TInt ret = KErrNone; |
|
191 |
|
192 while (index < (PAGESTRESS_FUNC_COUNT - 1)) |
|
193 { |
|
194 DBGD_PRINT((_L("\nAddress (%u) 0x%x difference to next %u\n"), index, (TUint32)PagestressFuncPtrs[index], (TUint32)PagestressFuncPtrs[index + 1] - (TUint32)PagestressFuncPtrs[index])); |
|
195 if ((((TUint32)PagestressFuncPtrs[index + 1] - (TUint32)PagestressFuncPtrs[0]) % 4096) != 0) |
|
196 { |
|
197 DBGS_PRINT((_L("\nError! Allignment for %u is not offset of 4096 from index 0 0x%x 0x%x\n"), index, (TUint32)PagestressFuncPtrs[index + 1], (TUint32)PagestressFuncPtrs[0])); |
|
198 ret = KErrGeneral; |
|
199 } |
|
200 //seed = PagestressFuncPtrs[index](seed, index); |
|
201 seed = CallTestFunc(seed, index, index); |
|
202 index ++; |
|
203 } |
|
204 return ret; |
|
205 } |
|
206 |
|
207 // |
|
208 // RunThreadForward |
|
209 // |
|
210 // Walk through the function pointer array (forwards) calling each function |
|
211 // |
|
212 |
|
213 void RunThreadForward() |
|
214 { |
|
215 TInt seed = 1; |
|
216 TUint32 index = 0; |
|
217 RThread thisThread; |
|
218 |
|
219 while (index < PAGESTRESS_FUNC_COUNT) |
|
220 { |
|
221 if (TestPrioChange) |
|
222 { |
|
223 TThreadPriority originalThreadPriority = thisThread.Priority(); |
|
224 thisThread.SetPriority(EPriorityLess); |
|
225 User::AfterHighRes(0); |
|
226 thisThread.SetPriority(originalThreadPriority); |
|
227 } |
|
228 //seed = PagestressFuncPtrs[index](seed, index); |
|
229 seed = CallTestFunc(seed, index, index); |
|
230 index ++; |
|
231 } |
|
232 } |
|
233 |
|
234 // |
|
235 // RunThreadBackward |
|
236 // |
|
237 // Walk through the function pointer array (backwards) calling each function |
|
238 // |
|
239 |
|
240 void RunThreadBackward() |
|
241 { |
|
242 TInt seed = 1; |
|
243 TInt index = PAGESTRESS_FUNC_COUNT; |
|
244 RThread thisThread; |
|
245 |
|
246 while (index > 0) |
|
247 { |
|
248 if (TestPrioChange) |
|
249 { |
|
250 TThreadPriority originalThreadPriority = thisThread.Priority(); |
|
251 thisThread.SetPriority(EPriorityLess); |
|
252 User::AfterHighRes(0); |
|
253 thisThread.SetPriority(originalThreadPriority); |
|
254 } |
|
255 index --; |
|
256 //seed = PagestressFuncPtrs[index](seed, index); |
|
257 seed = CallTestFunc(seed, index, index); |
|
258 } |
|
259 } |
|
260 |
|
261 // |
|
262 // RunThreadRandom |
|
263 // |
|
264 // Walk through the function pointer array in a random order a number of times calling each function |
|
265 // |
|
266 |
|
267 void RunThreadRandom() |
|
268 { |
|
269 TInt seed = 1; |
|
270 TInt index = 0; |
|
271 TInt randNum; |
|
272 RThread thisThread; |
|
273 |
|
274 while (index < (TInt)PAGESTRESS_FUNC_COUNT) |
|
275 { |
|
276 if (TestPrioChange) |
|
277 { |
|
278 TThreadPriority originalThreadPriority = thisThread.Priority(); |
|
279 thisThread.SetPriority(EPriorityLess); |
|
280 User::AfterHighRes(0); |
|
281 thisThread.SetPriority(originalThreadPriority); |
|
282 } |
|
283 randNum = Math::Random(); |
|
284 randNum %= PAGESTRESS_FUNC_COUNT; |
|
285 //seed = PagestressFuncPtrs[randNum](seed, randNum); |
|
286 seed = CallTestFunc(seed, randNum, randNum); |
|
287 index ++; |
|
288 } |
|
289 } |
|
290 |
|
291 |
|
292 // |
|
293 // PerformTestThread |
|
294 // |
|
295 // This is the function that actually does the work. |
|
296 // It is complicated a little because test.Printf can only be called from the first thread that calls it |
|
297 // so if we are using multiple threads we need to use a message queue to pass the debug info from the |
|
298 // child threads back to the parent for the parent to then call printf. |
|
299 // |
|
300 // |
|
301 |
|
302 LOCAL_C void PerformTestThread(TInt aThreadIndex, |
|
303 RMsgQueue<TBuf <64> > *aMsgQueue = NULL, |
|
304 TBuf<64> *aBuffer = NULL, |
|
305 RSemaphore *aTheSem = NULL) |
|
306 { |
|
307 TUint start = User::TickCount(); |
|
308 |
|
309 DEBUG_PRINT1((_L("%S : thread Starting %d\n"), &TestNameBuffer, aThreadIndex)); |
|
310 |
|
311 // now select how we do the test... |
|
312 TInt iterIndex; |
|
313 |
|
314 if (TEST_ALL == (TestWhichTests & TEST_ALL)) |
|
315 { |
|
316 #define LOCAL_ORDER_INDEX1 6 |
|
317 #define LOCAL_ORDER_INDEX2 3 |
|
318 TInt order[LOCAL_ORDER_INDEX1][LOCAL_ORDER_INDEX2] = { {TEST_FORWARD, TEST_BACKWARD,TEST_RANDOM}, |
|
319 {TEST_FORWARD, TEST_RANDOM, TEST_BACKWARD}, |
|
320 {TEST_BACKWARD,TEST_FORWARD, TEST_RANDOM}, |
|
321 {TEST_BACKWARD,TEST_RANDOM, TEST_FORWARD}, |
|
322 {TEST_RANDOM, TEST_FORWARD, TEST_BACKWARD}, |
|
323 {TEST_RANDOM, TEST_BACKWARD,TEST_FORWARD}}; |
|
324 TInt whichOrder = 0; |
|
325 |
|
326 for (iterIndex = 0; iterIndex < TestMaxLoops; iterIndex ++) |
|
327 { |
|
328 TInt selOrder = ((aThreadIndex + 1) * (iterIndex + 1)) % LOCAL_ORDER_INDEX1; |
|
329 for (whichOrder = 0; whichOrder < LOCAL_ORDER_INDEX2; whichOrder ++) |
|
330 { |
|
331 switch (order[selOrder][whichOrder]) |
|
332 { |
|
333 case TEST_FORWARD: |
|
334 DEBUG_PRINT1((_L("%S : %d Iter %d Forward\n"), &TestNameBuffer, aThreadIndex, iterIndex)); |
|
335 RunThreadForward(); |
|
336 break; |
|
337 |
|
338 case TEST_BACKWARD: |
|
339 DEBUG_PRINT1((_L("%S : %d Iter %d Backward\n"), &TestNameBuffer, aThreadIndex, iterIndex)); |
|
340 RunThreadBackward(); |
|
341 break; |
|
342 |
|
343 case TEST_RANDOM: |
|
344 DEBUG_PRINT1((_L("%S : %d Iter %d Random\n"), &TestNameBuffer, aThreadIndex, iterIndex)); |
|
345 RunThreadRandom(); |
|
346 break; |
|
347 |
|
348 default: // this is really an error. |
|
349 break; |
|
350 } |
|
351 } |
|
352 } |
|
353 } |
|
354 else |
|
355 { |
|
356 if (TestWhichTests & TEST_FORWARD) |
|
357 { |
|
358 for (iterIndex = 0; iterIndex < TestMaxLoops; iterIndex ++) |
|
359 { |
|
360 DEBUG_PRINT1((_L("%S : %d Iter %d Forward\n"), &TestNameBuffer, aThreadIndex, iterIndex)); |
|
361 RunThreadForward(); |
|
362 } |
|
363 } |
|
364 |
|
365 if (TestWhichTests & TEST_BACKWARD) |
|
366 { |
|
367 for (iterIndex = 0; iterIndex < TestMaxLoops; iterIndex ++) |
|
368 { |
|
369 DEBUG_PRINT1((_L("%S : %d Iter %d Backward\n"), &TestNameBuffer, aThreadIndex, iterIndex)); |
|
370 RunThreadBackward(); |
|
371 } |
|
372 } |
|
373 |
|
374 if (TestWhichTests & TEST_RANDOM) |
|
375 { |
|
376 for (iterIndex = 0; iterIndex < TestMaxLoops; iterIndex ++) |
|
377 { |
|
378 DEBUG_PRINT1((_L("%S : %d Iter %d Random\n"), &TestNameBuffer, aThreadIndex, iterIndex)); |
|
379 RunThreadRandom(); |
|
380 } |
|
381 } |
|
382 } |
|
383 DEBUG_PRINT1((_L("%S : thread Exiting %d (tickcount %u)\n"), &TestNameBuffer, aThreadIndex, User::TickCount() - start)); |
|
384 } |
|
385 |
|
386 |
|
387 // |
|
388 // MultipleTestThread |
|
389 // |
|
390 // Thread function, one created for each thread in a multiple thread test. |
|
391 // |
|
392 |
|
393 LOCAL_C TInt MultipleTestThread(TAny* aUseTb) |
|
394 { |
|
395 TBuf<64> localBuffer; |
|
396 |
|
397 if (TestInterleave) |
|
398 { |
|
399 RThread thisThread; |
|
400 thisThread.SetPriority((TThreadPriority) TEST_INTERLEAVE_PRIO); |
|
401 } |
|
402 |
|
403 PerformTestThread((TInt) aUseTb, &TestMsgQueue, &localBuffer, &TestMultiSem); |
|
404 |
|
405 return KErrNone; |
|
406 } |
|
407 |
|
408 // |
|
409 // DoSingleTest |
|
410 // |
|
411 // Perform the single thread test, spawning a number of threads. |
|
412 // |
|
413 |
|
414 LOCAL_C void DoSingleTest() |
|
415 { |
|
416 PerformTestThread((TInt) TestInstanceId); |
|
417 } |
|
418 |
|
419 // |
|
420 // FindDriveNumber |
|
421 // |
|
422 // Find the first read write drive. |
|
423 // |
|
424 |
|
425 TInt FindDriveNumber(RFs fs) |
|
426 { |
|
427 TDriveInfo driveInfo; |
|
428 for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum) |
|
429 { |
|
430 TInt r = fs.Drive(driveInfo, drvNum); |
|
431 if (r >= 0) |
|
432 { |
|
433 if (driveInfo.iType == EMediaHardDisk) |
|
434 return (drvNum); |
|
435 } |
|
436 } |
|
437 return -1; |
|
438 } |
|
439 |
|
440 // |
|
441 // FindFsNANDDrive |
|
442 // |
|
443 // Find the NAND drive |
|
444 // |
|
445 |
|
446 static TInt FindFsNANDDrive(RFs& aFs) |
|
447 { |
|
448 TDriveList driveList; |
|
449 TDriveInfo driveInfo; |
|
450 TInt r=aFs.DriveList(driveList); |
|
451 if (r == KErrNone) |
|
452 { |
|
453 for (TInt drvNum= (DriveNumber<0)?0:DriveNumber; drvNum<KMaxDrives; ++drvNum) |
|
454 { |
|
455 if(!driveList[drvNum]) |
|
456 continue; //-- skip unexisting drive |
|
457 |
|
458 if (aFs.Drive(driveInfo, drvNum) == KErrNone) |
|
459 { |
|
460 if(driveInfo.iMediaAtt&KMediaAttPageable) |
|
461 { |
|
462 TBool readOnly = driveInfo.iMediaAtt & KMediaAttWriteProtected; // skip ROFS partitions |
|
463 if(!readOnly) |
|
464 { |
|
465 if ((drvNum==DriveNumber) || (DriveNumber<0)) // only test if running on this drive |
|
466 { |
|
467 return (drvNum); |
|
468 } |
|
469 } |
|
470 } |
|
471 } |
|
472 } |
|
473 } |
|
474 return -1; |
|
475 } |
|
476 |
|
477 // |
|
478 // FindMMCDriveNumber |
|
479 // |
|
480 // Find the first read write drive. |
|
481 // |
|
482 |
|
483 TInt FindMMCDriveNumber(RFs& aFs) |
|
484 { |
|
485 TDriveInfo driveInfo; |
|
486 for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum) |
|
487 { |
|
488 TInt r = aFs.Drive(driveInfo, drvNum); |
|
489 if (r >= 0) |
|
490 { |
|
491 if (driveInfo.iType == EMediaHardDisk) |
|
492 return (drvNum); |
|
493 } |
|
494 } |
|
495 return -1; |
|
496 } |
|
497 |
|
498 // |
|
499 // PerformRomAndFileSystemAccess |
|
500 // |
|
501 // Access the rom and dump it out to one of the writeable partitions... |
|
502 // really just to make the media server a little busy during the test. |
|
503 // |
|
504 |
|
505 TInt PerformRomAndFileSystemAccessThread(RMsgQueue<TBuf <64> > *aMsgQueue = NULL, |
|
506 TBuf<64> *aBuffer = NULL, |
|
507 RSemaphore *aTheSem = NULL) |
|
508 { |
|
509 TUint maxBytes = KMaxTUint; |
|
510 TInt startTime = User::TickCount(); |
|
511 |
|
512 RFs fs; |
|
513 RFile file; |
|
514 if (KErrNone != fs.Connect()) |
|
515 { |
|
516 DEBUG_PRINT(_L("PerformRomAndFileSystemAccessThread : Can't connect to the FS\n")); |
|
517 return KErrGeneral; |
|
518 } |
|
519 |
|
520 // get info about the ROM... |
|
521 TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress(); |
|
522 TUint8* start; |
|
523 TUint8* end; |
|
524 if(romHeader->iPageableRomStart) |
|
525 { |
|
526 start = (TUint8*)romHeader + romHeader->iPageableRomStart; |
|
527 end = start + romHeader->iPageableRomSize; |
|
528 } |
|
529 else |
|
530 { |
|
531 start = (TUint8*)romHeader; |
|
532 end = start + romHeader->iUncompressedSize; |
|
533 } |
|
534 if (end <= start) |
|
535 return KErrGeneral; |
|
536 |
|
537 // read all ROM pages in a random order...and write out to file in ROFs, |
|
538 TUint size = end - start - TestPageSize; |
|
539 if(size > maxBytes) |
|
540 size = maxBytes; |
|
541 |
|
542 TUint32 random=1; |
|
543 TPtrC8 rom; |
|
544 TUint8 *theAddr; |
|
545 |
|
546 TInt drvNum = TestBootedFromMmc ? FindMMCDriveNumber(fs) : FindFsNANDDrive(fs); |
|
547 TBuf<32> filename = _L("d:\\Pageldrtst.tmp"); |
|
548 if (drvNum >= 0) |
|
549 { |
|
550 filename[0] = 'a' + drvNum; |
|
551 DEBUG_PRINT((_L("%S : Filename %S\n"), &TestNameBuffer, &filename)); |
|
552 } |
|
553 else |
|
554 DEBUG_PRINT((_L("PerformRomAndFileSystemAccessThread : error getting drive num\n"))); |
|
555 |
|
556 for(TInt i=size/(TestPageSize); i>0; --i) |
|
557 { |
|
558 DEBUG_PRINT1((_L("%S : Opening the file\n"), &TestNameBuffer)); |
|
559 if (KErrNone != file.Replace(fs, filename, EFileWrite)) |
|
560 { |
|
561 DEBUG_PRINT((_L("%S : Opening the file Failed!\n"), &TestNameBuffer)); |
|
562 } |
|
563 |
|
564 random = random*69069+1; |
|
565 theAddr = (TUint8*)(start+((TInt64(random)*TInt64(size))>>32)); |
|
566 if (theAddr + TestPageSize > end) |
|
567 { |
|
568 DEBUG_PRINT((_L("%S : address is past the end 0x%x / 0x%x\n"), &TestNameBuffer, (TInt)theAddr, (TInt)end)); |
|
569 } |
|
570 rom.Set(theAddr,TestPageSize); |
|
571 DEBUG_PRINT1((_L("%S : Writing the file\n"), &TestNameBuffer)); |
|
572 TInt ret = file.Write(rom); |
|
573 if (ret != KErrNone) |
|
574 { |
|
575 DEBUG_PRINT1((_L("%S : Write returned error %d\n"), &TestNameBuffer, ret)); |
|
576 } |
|
577 DEBUG_PRINT1((_L("%S : Closing the file\n"), &TestNameBuffer)); |
|
578 file.Close(); |
|
579 |
|
580 DEBUG_PRINT1((_L("%S : Deleting the file\n"), &TestNameBuffer)); |
|
581 ret = fs.Delete(filename); |
|
582 if (KErrNone != ret) |
|
583 { |
|
584 DEBUG_PRINT((_L("%S : Delete returned error %d\n"), &TestNameBuffer, ret)); |
|
585 } |
|
586 if (TestStopMedia) |
|
587 break; |
|
588 } |
|
589 fs.Close(); |
|
590 DEBUG_PRINT1((_L("Done in %d ticks\n"), User::TickCount() - startTime)); |
|
591 return KErrNone; |
|
592 } |
|
593 |
|
594 |
|
595 // |
|
596 // PerformRomAndFileSystemAccess |
|
597 // |
|
598 // Thread function, kicks off the file system access. |
|
599 // |
|
600 |
|
601 LOCAL_C TInt PerformRomAndFileSystemAccess(TAny* ) |
|
602 { |
|
603 TBuf<64> localBuffer; |
|
604 |
|
605 PerformRomAndFileSystemAccessThread(&TestMsgQueue, &localBuffer, &TestMultiSem); |
|
606 |
|
607 return KErrNone; |
|
608 } |
|
609 |
|
610 // |
|
611 // DoMultipleTest |
|
612 // |
|
613 // Perform the multiple thread test, spawning a number of threads. |
|
614 // It is complicated a little because test.Printf can only be called from the first thread that calls it |
|
615 // so if we are using multiple threads we need to use a message queue to pass the debug info from the |
|
616 // child threads back to the parent for the parent to then call printf. |
|
617 // |
|
618 #define DOTEST(__operation, __condition)\ |
|
619 if (aLowMem) \ |
|
620 {\ |
|
621 __operation;\ |
|
622 while (!__condition)\ |
|
623 {\ |
|
624 Ldd.DoReleaseSomeRam(TEST_LM_BLOCKS_FREE);\ |
|
625 __operation;\ |
|
626 }\ |
|
627 RUNTEST1(__condition);\ |
|
628 }\ |
|
629 else\ |
|
630 {\ |
|
631 __operation;\ |
|
632 RUNTEST1(__condition);\ |
|
633 } |
|
634 |
|
635 void DoMultipleTest(TBool aLowMem = EFalse) |
|
636 { |
|
637 TInt index; |
|
638 |
|
639 RThread *pTheThreads = (RThread *)User::AllocZ(sizeof(RThread) * TestMultipleThreadCount); |
|
640 TInt *pThreadInUse = (TInt *)User::AllocZ(sizeof(TInt) * TestMultipleThreadCount); |
|
641 |
|
642 TRequestStatus mediaStatus; |
|
643 RThread mediaThread; |
|
644 |
|
645 TInt ret; |
|
646 DOTEST((ret = TestMsgQueue.CreateLocal(TestMultipleThreadCount * 10, EOwnerProcess)), |
|
647 (KErrNone == ret)); |
|
648 |
|
649 DOTEST((ret = TestMultiSem.CreateLocal(1)), |
|
650 (KErrNone == ret)); |
|
651 |
|
652 // make sure we have a priority higher than that of the threads we spawn... |
|
653 RThread thisThread; |
|
654 TThreadPriority savedThreadPriority = thisThread.Priority(); |
|
655 const TThreadPriority KMainThreadPriority = EPriorityMuchMore; |
|
656 __ASSERT_COMPILE(KMainThreadPriority>TEST_INTERLEAVE_PRIO); |
|
657 thisThread.SetPriority(KMainThreadPriority); |
|
658 |
|
659 if (TestMediaAccess) |
|
660 { |
|
661 TestStopMedia = EFalse; |
|
662 mediaThread.Create(_L(""),PerformRomAndFileSystemAccess,KDefaultStackSize,NULL,NULL); |
|
663 mediaThread.Logon(mediaStatus); |
|
664 RUNTEST1(mediaStatus == KRequestPending); |
|
665 mediaThread.Resume(); |
|
666 } |
|
667 |
|
668 // spawn some processes to call the functions.... |
|
669 for (index = 0; index < TestMultipleThreadCount; index++) |
|
670 { |
|
671 DBGD_PRINT((_L("%S : Starting thread.%d!\n"), &TestNameBuffer, index)); |
|
672 DOTEST((ret = pTheThreads[index].Create(_L(""),MultipleTestThread,KDefaultStackSize,NULL,(TAny*) index)), |
|
673 (ret == KErrNone)); |
|
674 pTheThreads[index].Resume(); |
|
675 pThreadInUse[index] = 1; |
|
676 } |
|
677 |
|
678 // now process any messages sent from the child threads. |
|
679 TBool anyUsed = ETrue; |
|
680 TBuf<64> localBuffer; |
|
681 |
|
682 while(anyUsed) |
|
683 { |
|
684 anyUsed = EFalse; |
|
685 // check the message queue and call printf if we get a message. |
|
686 while (KErrNone == TestMsgQueue.Receive(localBuffer)) |
|
687 { |
|
688 DBGS_PRINT((localBuffer)); |
|
689 } |
|
690 |
|
691 // walk through the thread list to check which are still alive. |
|
692 for (index = 0; index < TestMultipleThreadCount; index++) |
|
693 { |
|
694 if (pThreadInUse[index]) |
|
695 { |
|
696 if (pTheThreads[index].ExitType() != EExitPending) |
|
697 { |
|
698 if (pTheThreads[index].ExitType() == EExitPanic) |
|
699 { |
|
700 DBGS_PRINT((_L("%S : Thread Panic'd %d...\n"), &TestNameBuffer, index)); |
|
701 } |
|
702 pThreadInUse[index] = EFalse; |
|
703 pTheThreads[index].Close(); |
|
704 } |
|
705 else |
|
706 { |
|
707 anyUsed = ETrue; |
|
708 } |
|
709 } |
|
710 } |
|
711 User::AfterHighRes(50000); |
|
712 } |
|
713 |
|
714 if (TestMediaAccess) |
|
715 { |
|
716 TestStopMedia = ETrue; |
|
717 DBGD_PRINT((_L("%S : Waiting for media thread to exit...\n"), &TestNameBuffer)); |
|
718 User::WaitForRequest(mediaStatus); |
|
719 mediaThread.Close(); |
|
720 } |
|
721 |
|
722 TestMsgQueue.Close(); |
|
723 TestMultiSem.Close(); |
|
724 |
|
725 // cleanup the resources and exit. |
|
726 User::Free(pTheThreads); |
|
727 User::Free(pThreadInUse); |
|
728 |
|
729 thisThread.SetPriority(savedThreadPriority); |
|
730 } |
|
731 |
|
732 |
|
733 // |
|
734 // ParseCommandLine |
|
735 // |
|
736 // read the arguments passed from the command line and set global variables to |
|
737 // control the tests. |
|
738 // |
|
739 |
|
740 TBool ParseCommandLine() |
|
741 { |
|
742 TBuf<256> args; |
|
743 User::CommandLine(args); |
|
744 TLex lex(args); |
|
745 TBool retVal = ETrue; |
|
746 |
|
747 // initially test for arguments, the parse them, if not apply some sensible defaults. |
|
748 TBool foundArgs = EFalse; |
|
749 |
|
750 FOREVER |
|
751 { |
|
752 TPtrC token=lex.NextToken(); |
|
753 if(token.Length()!=0) |
|
754 { |
|
755 if ((token == _L("help")) || (token == _L("-h")) || (token == _L("-?"))) |
|
756 { |
|
757 DBGS_PRINT((_L("\nUsage: %S [debug] [check] [single | multiple <numThreads>] [forward | backward | random | all] [iters <iters>] [media] [lowmem] [interleave]\n'-' indicated infinity.\n\n"), &TestNameBuffer)); |
|
758 test.Getch(); |
|
759 } |
|
760 else if (token == _L("debug")) |
|
761 { |
|
762 if (!TestSilent) |
|
763 { |
|
764 TestDebug = ETrue; |
|
765 TestPrioChange = ETrue; |
|
766 } |
|
767 } |
|
768 else if (token == _L("silent")) |
|
769 { |
|
770 TestSilent = ETrue; |
|
771 TestDebug = EFalse; |
|
772 } |
|
773 else if (token == _L("check")) |
|
774 { |
|
775 TestCheck = ETrue; |
|
776 } |
|
777 else if (token == _L("single")) |
|
778 { |
|
779 TestSingle = ETrue; |
|
780 } |
|
781 else if (token == _L("multiple")) |
|
782 { |
|
783 TPtrC val=lex.NextToken(); |
|
784 TLex lexv(val); |
|
785 TInt value; |
|
786 |
|
787 if (lexv.Val(value)==KErrNone) |
|
788 { |
|
789 if ((value <= 0) || (value > 100)) |
|
790 { |
|
791 TestMultipleThreadCount = 10; |
|
792 } |
|
793 else |
|
794 { |
|
795 TestMultipleThreadCount = value; |
|
796 } |
|
797 } |
|
798 else |
|
799 { |
|
800 DBGS_PRINT((_L("Bad value for thread count '%S' was ignored.\n"), &val)); |
|
801 retVal = EFalse; |
|
802 break; |
|
803 } |
|
804 TestMultiple = ETrue; |
|
805 } |
|
806 else if (token == _L("prio")) |
|
807 { |
|
808 TestPrioChange = !TestPrioChange; |
|
809 } |
|
810 else if (token == _L("lowmem")) |
|
811 { |
|
812 TestLowMem = ETrue; |
|
813 } |
|
814 else if (token == _L("media")) |
|
815 { |
|
816 TestMediaAccess = ETrue; |
|
817 } |
|
818 else if (token == _L("forward")) |
|
819 { |
|
820 TestWhichTests = TEST_FORWARD; |
|
821 } |
|
822 else if (token == _L("backward")) |
|
823 { |
|
824 TestWhichTests = TEST_BACKWARD; |
|
825 } |
|
826 else if (token == _L("random")) |
|
827 { |
|
828 TestWhichTests = TEST_RANDOM; |
|
829 } |
|
830 else if (token == _L("all")) |
|
831 { |
|
832 TestWhichTests = TEST_ALL; |
|
833 } |
|
834 else if (token == _L("iters")) |
|
835 { |
|
836 TPtrC val=lex.NextToken(); |
|
837 TLex lexv(val); |
|
838 TInt value; |
|
839 |
|
840 if (val==_L("-")) |
|
841 { |
|
842 TestForever = ETrue; |
|
843 TestMaxLoops = KMaxTInt; |
|
844 } |
|
845 else |
|
846 { |
|
847 if (lexv.Val(value)==KErrNone) |
|
848 { |
|
849 TestMaxLoops = value; |
|
850 } |
|
851 else |
|
852 { |
|
853 DBGS_PRINT((_L("Bad value for thread count '%S' was ignored.\n"), &val)); |
|
854 retVal = EFalse; |
|
855 break; |
|
856 } |
|
857 } |
|
858 } |
|
859 else if (token == _L("interleave")) |
|
860 { |
|
861 TestInterleave = ETrue; |
|
862 } |
|
863 else if (token == _L("inst")) |
|
864 { |
|
865 TPtrC val=lex.NextToken(); |
|
866 TLex lexv(val); |
|
867 TInt value; |
|
868 |
|
869 if (lexv.Val(value)==KErrNone) |
|
870 { |
|
871 TestInstanceId = value; |
|
872 } |
|
873 } |
|
874 else |
|
875 { |
|
876 if ((foundArgs == EFalse) && (token.Length() == 1)) |
|
877 { |
|
878 // Single letter argument...only run on MMC drive |
|
879 if (token.CompareF(_L("d")) == 0) |
|
880 { |
|
881 break; |
|
882 } |
|
883 else |
|
884 { |
|
885 if (!TestSilent) |
|
886 { |
|
887 test.Title(); |
|
888 test.Start(_L("Skipping non drive 'd' - Test Exiting.")); |
|
889 test.End(); |
|
890 } |
|
891 foundArgs = ETrue; |
|
892 TestExit = ETrue; |
|
893 break; |
|
894 } |
|
895 } |
|
896 DBGS_PRINT((_L("Unknown argument '%S' was ignored.\n"), &token)); |
|
897 break; |
|
898 } |
|
899 foundArgs = ETrue; |
|
900 } |
|
901 else |
|
902 { |
|
903 break; |
|
904 } |
|
905 } |
|
906 if (!foundArgs) |
|
907 { |
|
908 retVal = EFalse; |
|
909 } |
|
910 return retVal; |
|
911 } |
|
912 |
|
913 // |
|
914 // AreWeTheTestBase |
|
915 // |
|
916 // Test whether we are the root of the tests. |
|
917 // |
|
918 |
|
919 void AreWeTheTestBase(void) |
|
920 { |
|
921 if (!TestSilent) |
|
922 { |
|
923 TFileName filename(RProcess().FileName()); |
|
924 |
|
925 TParse myParse; |
|
926 myParse.Set(filename, NULL, NULL); |
|
927 TestNameBuffer.Zero(); |
|
928 TestNameBuffer.Append(myParse.Name()); |
|
929 TestNameBuffer.Append(_L(".exe")); |
|
930 |
|
931 TestWeAreTheTestBase = !TestNameBuffer.Compare(_L("t_pagestress.exe")); |
|
932 |
|
933 RFs fs; |
|
934 if (KErrNone != fs.Connect()) |
|
935 { |
|
936 TEntry anEntry; |
|
937 TInt retVal = fs.Entry(_L("z:\\test\\mmcdemandpaginge32tests.bat"), anEntry); |
|
938 if (retVal == KErrNone) |
|
939 { |
|
940 TestBootedFromMmc = ETrue; |
|
941 } |
|
942 else |
|
943 { |
|
944 TestBootedFromMmc = EFalse; |
|
945 } |
|
946 fs.Close(); |
|
947 } |
|
948 |
|
949 } |
|
950 else |
|
951 { |
|
952 TestNameBuffer.Zero(); |
|
953 TestNameBuffer.Append(_L("t_pagestress.exe")); |
|
954 } |
|
955 } |
|
956 |
|
957 // |
|
958 // PerformAutoTest |
|
959 // |
|
960 // Perform the autotest |
|
961 // |
|
962 void PerformAutoTest() |
|
963 { |
|
964 SVMCacheInfo tempPages; |
|
965 |
|
966 if (TestIsDemandPaged) |
|
967 { |
|
968 UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0); |
|
969 DBGS_PRINT((_L("PerformAutoTest : Start cache info: iMinSize %d iMaxSize %d iCurrentSize %d iMaxFreeSize %d\n"), |
|
970 tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize ,tempPages.iMaxFreeSize)); |
|
971 } |
|
972 TestInterleave = EFalse; |
|
973 TestPrioChange = EFalse; |
|
974 TestMediaAccess = EFalse; |
|
975 |
|
976 #if defined __ARMCC__ || defined __X86__ |
|
977 // Currently we only build aligned DLLs on ARMV5 and X86 builds. |
|
978 TEST_NEXT((_L("Alignment Check."))); |
|
979 RUNTEST1(CheckAlignments() == KErrNone); |
|
980 #endif |
|
981 |
|
982 TestMaxLoops = 2; |
|
983 TestWhichTests = TEST_RANDOM; |
|
984 |
|
985 TEST_NEXT((_L("Single thread all."))); |
|
986 DoSingleTest(); |
|
987 |
|
988 TEST_NEXT((_L("Multiple threads all."))); |
|
989 DoMultipleTest(); |
|
990 |
|
991 TestPrioChange = ETrue; |
|
992 TEST_NEXT((_L("Multiple threads all with prio."))); |
|
993 DoMultipleTest(); |
|
994 |
|
995 TestPrioChange = EFalse; |
|
996 TestMediaAccess = ETrue; |
|
997 TEST_NEXT((_L("Multiple threads all with media activity."))); |
|
998 DoMultipleTest(); |
|
999 |
|
1000 TestPrioChange = ETrue; |
|
1001 TestMediaAccess = ETrue; |
|
1002 TEST_NEXT((_L("Multiple threads all with media activity and prio."))); |
|
1003 DoMultipleTest(); |
|
1004 |
|
1005 TestInterleave = ETrue; |
|
1006 TestPrioChange = EFalse; |
|
1007 TestMediaAccess = EFalse; |
|
1008 |
|
1009 TEST_NEXT((_L("Multiple threads random with interleave."))); |
|
1010 DoMultipleTest(); |
|
1011 |
|
1012 TestPrioChange = ETrue; |
|
1013 TEST_NEXT((_L("Multiple threads random with interleave and prio."))); |
|
1014 DoMultipleTest(); |
|
1015 |
|
1016 TestMediaAccess = ETrue; |
|
1017 TEST_NEXT((_L("Multiple threads random with media interleave and prio."))); |
|
1018 DoMultipleTest(); |
|
1019 |
|
1020 if (TestIsDemandPaged) |
|
1021 { |
|
1022 UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0); |
|
1023 DBGS_PRINT((_L("PerformAutoTest : End cache info: iMinSize %d iMaxSize %d iCurrentSize %d iMaxFreeSize %d\n"), |
|
1024 tempPages.iMinSize, tempPages.iMaxSize, tempPages.iCurrentSize ,tempPages.iMaxFreeSize)); |
|
1025 } |
|
1026 TestInterleave = EFalse; |
|
1027 TestPrioChange = EFalse; |
|
1028 TestMediaAccess = EFalse; |
|
1029 } |
|
1030 |
|
1031 // |
|
1032 // DoLowMemTest |
|
1033 // |
|
1034 // Low Memory Test |
|
1035 // |
|
1036 |
|
1037 void DoLowMemTest() |
|
1038 { |
|
1039 TInt r = User::LoadLogicalDevice(KPageStressTestLddName); |
|
1040 RUNTEST1(r==KErrNone || r==KErrAlreadyExists); |
|
1041 RUNTEST(Ldd.Open(),KErrNone); |
|
1042 |
|
1043 SVMCacheInfo tempPages; |
|
1044 memset(&tempPages, 0, sizeof(tempPages)); |
|
1045 |
|
1046 if (TestIsDemandPaged) |
|
1047 { |
|
1048 // get the old cache info |
|
1049 UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0); |
|
1050 TInt minSize = 8 * 4096; |
|
1051 TInt maxSize = 256 * 4096; |
|
1052 UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); |
|
1053 } |
|
1054 |
|
1055 // First load some pages onto the page cache |
|
1056 TestMaxLoops = 1; |
|
1057 TestWhichTests = TEST_RANDOM; |
|
1058 DoSingleTest(); |
|
1059 |
|
1060 Ldd.DoConsumeRamSetup(TEST_LM_NUM_FREE, TEST_LM_BLOCKSIZE); |
|
1061 TEST_NEXT((_L("Single thread with Low memory."))); |
|
1062 TestMultipleThreadCount = 25; |
|
1063 TestInterleave = EFalse; |
|
1064 TestMaxLoops = 20; |
|
1065 TestPrioChange = EFalse; |
|
1066 TestMediaAccess = EFalse; |
|
1067 TestWhichTests = TEST_ALL; |
|
1068 |
|
1069 DoSingleTest(); |
|
1070 |
|
1071 Ldd.DoConsumeRamFinish(); |
|
1072 |
|
1073 TEST_NEXT((_L("Multiple thread with Low memory."))); |
|
1074 // First load some pages onto the page cache |
|
1075 TestMaxLoops = 1; |
|
1076 TestWhichTests = TEST_RANDOM; |
|
1077 DoSingleTest(); |
|
1078 |
|
1079 Ldd.DoConsumeRamSetup(TEST_LM_NUM_FREE, TEST_LM_BLOCKSIZE); |
|
1080 |
|
1081 TestWhichTests = TEST_ALL; |
|
1082 TestMaxLoops = 10; |
|
1083 TestMultipleThreadCount = 25; |
|
1084 DoMultipleTest(ETrue); |
|
1085 |
|
1086 Ldd.DoConsumeRamFinish(); |
|
1087 |
|
1088 TEST_NEXT((_L("Multiple thread with Low memory, with starting free ram."))); |
|
1089 // First load some pages onto the page cache |
|
1090 TestMaxLoops = 1; |
|
1091 TestWhichTests = TEST_RANDOM; |
|
1092 DoSingleTest(); |
|
1093 |
|
1094 Ldd.DoConsumeRamSetup(32, TEST_LM_BLOCKSIZE); |
|
1095 |
|
1096 TestWhichTests = TEST_ALL; |
|
1097 TestMaxLoops = 10; |
|
1098 TestMultipleThreadCount = 25; |
|
1099 DoMultipleTest(ETrue); |
|
1100 |
|
1101 Ldd.DoConsumeRamFinish(); |
|
1102 |
|
1103 TEST_NEXT((_L("Close test driver"))); |
|
1104 Ldd.Close(); |
|
1105 RUNTEST(User::FreeLogicalDevice(KPageStressTestLddName), KErrNone); |
|
1106 if (TestIsDemandPaged) |
|
1107 { |
|
1108 TInt minSize = tempPages.iMinSize; |
|
1109 TInt maxSize = tempPages.iMaxSize; |
|
1110 UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); |
|
1111 } |
|
1112 } |
|
1113 |
|
1114 // |
|
1115 // E32Main |
|
1116 // |
|
1117 // Main entry point. |
|
1118 // |
|
1119 |
|
1120 TInt E32Main() |
|
1121 { |
|
1122 #ifndef TEST_ON_UNPAGED |
|
1123 TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress(); |
|
1124 if(!romHeader->iPageableRomStart) |
|
1125 { |
|
1126 TestIsDemandPaged = EFalse; |
|
1127 } |
|
1128 #endif |
|
1129 TUint start = User::TickCount(); |
|
1130 |
|
1131 TBool parseResult = ParseCommandLine(); |
|
1132 |
|
1133 if (TestExit) |
|
1134 { |
|
1135 return KErrNone; |
|
1136 } |
|
1137 |
|
1138 AreWeTheTestBase(); |
|
1139 |
|
1140 TInt minSize = 8 * 4096; |
|
1141 TInt maxSize = 64 * 4096; |
|
1142 SVMCacheInfo tempPages; |
|
1143 memset(&tempPages, 0, sizeof(tempPages)); |
|
1144 if (TestIsDemandPaged) |
|
1145 { |
|
1146 // get the old cache info |
|
1147 UserSvr::HalFunction(EHalGroupVM,EVMHalGetCacheSize,&tempPages,0); |
|
1148 // set the cache to our test value |
|
1149 UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); |
|
1150 } |
|
1151 |
|
1152 // get the page size. |
|
1153 UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&TestPageSize,0); |
|
1154 |
|
1155 if (!TestSilent) |
|
1156 { |
|
1157 test.Title(); |
|
1158 test.Start(_L("Demand Paging stress tests...")); |
|
1159 test.Printf(_L("%S\n"), &TestNameBuffer); |
|
1160 } |
|
1161 |
|
1162 if (parseResult) |
|
1163 { |
|
1164 if (!TestSilent) |
|
1165 { |
|
1166 extern TInt *CheckLdmiaInstr(void); |
|
1167 test.Printf(_L("%S : CheckLdmiaInstr\n"), &TestNameBuffer); |
|
1168 TInt *theAddr = CheckLdmiaInstr(); |
|
1169 test.Printf(_L("%S : CheckLdmiaInstr complete 0x%x...\n"), &TestNameBuffer, (TInt)theAddr); |
|
1170 } |
|
1171 if (TestCheck) |
|
1172 { |
|
1173 CheckAlignments(); |
|
1174 } |
|
1175 if (TestLowMem) |
|
1176 { |
|
1177 DoLowMemTest(); |
|
1178 } |
|
1179 if (TestSingle) |
|
1180 { |
|
1181 DoSingleTest(); |
|
1182 } |
|
1183 if (TestMultiple) |
|
1184 { |
|
1185 DoMultipleTest(); |
|
1186 } |
|
1187 } |
|
1188 else |
|
1189 { |
|
1190 PerformAutoTest(); |
|
1191 |
|
1192 DoLowMemTest(); |
|
1193 |
|
1194 if (TestWeAreTheTestBase) |
|
1195 { |
|
1196 RProcess theProcess; |
|
1197 TRequestStatus status; |
|
1198 |
|
1199 TInt retVal = theProcess.Create(_L("t_pagestress_rom.exe"),_L("")); |
|
1200 if (retVal != KErrNotFound) |
|
1201 { |
|
1202 RUNTEST1(retVal == KErrNone); |
|
1203 theProcess.Logon(status); |
|
1204 RUNTEST1(status == KRequestPending); |
|
1205 theProcess.Resume(); |
|
1206 User::WaitForRequest(status); |
|
1207 if (theProcess.ExitType() != EExitPending) |
|
1208 { |
|
1209 RUNTEST1(theProcess.ExitType() != EExitPanic); |
|
1210 } |
|
1211 } |
|
1212 } |
|
1213 } |
|
1214 |
|
1215 if (TestIsDemandPaged) |
|
1216 { |
|
1217 minSize = tempPages.iMinSize; |
|
1218 maxSize = tempPages.iMaxSize; |
|
1219 // put the cache back to the the original values. |
|
1220 UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize); |
|
1221 } |
|
1222 |
|
1223 if (!TestSilent) |
|
1224 { |
|
1225 test.Printf(_L("%S : Complete (%u ticks)\n"), &TestNameBuffer, User::TickCount() - start); |
|
1226 test.End(); |
|
1227 } |
|
1228 return 0; |
|
1229 } |
|
1230 |
|
1231 |