Update contrib.
1 // Copyright (c) 2005-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\mmu\t_demandpaging.cpp
15 // Functional tests for demand paging. The test suite covers simple
16 // paging operations as well as HAL configuration and tuning functions.
17 // 001.01 DPTest::Attributes
18 // 001.02 DPTest::FlushCache
19 // 001.03 DPTest::CacheSize
20 // 001.04 DPTest::SetCacheSize
21 // 001.04.01 Changing size of flushed VM cache
22 // 001.04.02 Changing size of full VM cache
23 // 002 Loading test drivers
24 // 003 Test thread realtime state
25 // 003.01 Enable KREALTIME tracing
26 // 003.02 Test ERealtimeStateOff
27 // 003.03 Test ERealtimeStateOn
28 // 003.04 Test ERealtimeStateWarn
29 // 003.05 Test server with ERealtimeStateOff
30 // 003.06 Test server with ERealtimeStateOn
31 // 003.07 Test server with ERealtimeStateWarn
32 // 003.08 Disable KREALTIME tracing
34 // 005 Lock Test again
35 // 006 Test writing to paged ROM
36 // 007 Test IPC read from paged memory
37 // 007.01 Create server
38 // 007.02 IPC read from ROM
40 // 008 Test contiguous RAM allocation reclaims paged memory
42 // 008.02 Contiguous RAM test: alloc size = 128K align = 16
43 // 008.03 Contiguous RAM test: alloc size = 128K align = 0
44 // 008.04 Contiguous RAM test: alloc size = 64K align = 15
45 // 008.05 Contiguous RAM test: alloc size = 64K align = 14
46 // 008.06 Contiguous RAM test: alloc size = 64K align = 13
47 // 008.07 Contiguous RAM test: alloc size = 64K align = 12
48 // 008.08 Contiguous RAM test: alloc size = 64K align = 0
49 // 008.09 Contiguous RAM test: alloc size = 8K align = 13
50 // 008.10 Contiguous RAM test: alloc size = 8K align = 12
51 // 008.11 Contiguous RAM test: alloc size = 8K align = 0
52 // 008.12 Contiguous RAM test: alloc size = 4K align = 13
53 // 008.13 Contiguous RAM test: alloc size = 4K align = 12
54 // 008.14 Contiguous RAM test: alloc size = 4K align = 0
55 // 009 Test no kernel faults when copying data from unpaged rom with mutex held
56 // 010 Close test driver
57 // 011 Test setting publish and subscribe properties from paged area
58 // 012 Rom Paging Benchmark
59 // 012.01 Benchmark ROM paging...
63 //! @SYMTestCaseID KBASE-T_DEMANDPAGING-0334
66 //! @SYMTestCaseDesc Demand Paging functional tests.
67 //! @SYMTestActions 001 Test HAL interface
68 //! @SYMTestExpectedResults All tests should pass.
69 //! @SYMTestPriority High
70 //! @SYMTestStatus Implemented
72 #define __E32TEST_EXTENSION__
76 #include <e32property.h>
78 #include "d_memorytest.h"
79 #include "d_demandpaging.h"
81 #include "mmudetect.h"
82 #include "t_codepaging_dll.h"
85 RTest test(_L("T_DEMANDPAGING"));
87 _LIT(KTCodePagingDll4, "t_codepaging_dll4.dll");
88 const TInt KMinBufferSize = 16384;
89 const TInt KMaxIPCSize = 256*1024;
92 RDemandPagingTestLdd Ldd;
93 RLibrary PagedLibrary;
95 // A buffer containing paged memory, contents may or may not be paged in
96 const TUint8* LargeBuffer = NULL;
97 TInt LargeBufferSize = 0;
99 // A buffer containing paged memeory, contents always paged out before access
100 const TUint8* SmallBuffer = NULL;
101 TInt SmallBufferSize = 0;
103 // A shared buffer mapped to the global address range
104 TInt SharedBufferSize = KMaxIPCSize+4096;
105 TLinAddr SharedBufferAddr = 0;
106 TUint8* SharedBuffer = NULL;
108 // A descriptor whose header is in paged memory (actually just a pointer to a zero word)
109 TDesC8* PagedHeaderDes = NULL;
111 // A data paged chunk used as a buffer, if data paging is supported
112 _LIT(KChunkName, "t_demandpaging chunk");
113 RChunk DataPagedChunk;
114 TBool DataPagingSupported = EFalse;
115 TUint8* DataPagedBuffer = NULL;
117 TUint8 ReadByte(volatile TUint8* aPtr)
122 #define READ(a) ReadByte((volatile TUint8*)(a))
124 void ThrashPaging(TUint aMaxBytes=KMaxTUint)
126 TUint size = LargeBufferSize;
130 // read all ROM pages about 10 times each in a random order...
132 for(TInt i=size/(PageSize/10); i>0; --i)
134 READ(LargeBuffer+((TInt64(random)*TInt64(size))>>32));
135 random = random*69069+1;
139 void FragmentPagingCache(TUint aMaxBytes)
141 DPTest::FlushCache();
143 TUint size = Min(LargeBufferSize, aMaxBytes);
145 test.Printf(_L("WARNING: LargeBuffer not large enough! Have you built a full test ROM?\n"));
148 test(KErrNone==chunk.CreateDisconnectedLocal(0,0,size));
151 for(TUint i=0; i<size; i += PageSize)
153 random = random*69069+1;
154 if(random<0x40000000)
155 chunk.Commit(i,PageSize); // to make paging cache fragmented
156 READ(LargeBuffer + i);
159 CLOSE_AND_WAIT(chunk);
161 UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
165 void RomPagingBenchmark()
167 TInt r=DPTest::FlushCache();
171 test.Start(_L("Benchmark ROM paging..."));
173 // change live list to be a small as possible
174 test(KErrNone==DPTest::SetCacheSize(1,1));
177 test(KErrNone==timer.CreateLocal());
178 TRequestStatus status;
179 timer.After(status,1);
180 User::WaitForRequest(status);
182 TPckgBuf<DPTest::TEventInfo> events0;
183 DPTest::EventInfo(events0);
185 TInt KRunTime = 10*1000*1000;
186 timer.After(status,KRunTime);
187 while(status==KRequestPending)
188 for(const TUint8* ptr=LargeBuffer; ptr<(LargeBuffer+LargeBufferSize); ptr+=PageSize)
191 if(status!=KRequestPending)
195 TPckgBuf<DPTest::TEventInfo> events1;
196 DPTest::EventInfo(events1);
198 User::WaitForRequest(status);
200 TUint pages = events1().iPageInReadCount-events0().iPageInReadCount;
201 test.Printf(_L("%d pages in %d seconds = %d us/page\n"),pages,KRunTime/1000/1000,KRunTime/pages);
203 // restore live list to default size...
204 test(KErrNone==DPTest::SetCacheSize(0,0));
210 void TestResizeVMCache()
212 TInt r = DPTest::SetCacheSize(0,0); // restore cache size to defaults
216 TUint currentSize = 0;
217 DPTest::CacheSize(sizeMin,sizeMax,currentSize);
218 TUint originalMin = sizeMin;
219 TUint originalMax = sizeMax;
220 test.Printf(_L("original min=%u, original max=%u, current=%u\n"),originalMin/PageSize,originalMax/PageSize,currentSize/PageSize);
222 int K = currentSize/PageSize+4;
241 { K+1, K, KErrArgument},
242 { K, K-1, KErrArgument},
243 { KMaxTInt, KMaxTInt, KErrNoMemory},
246 { 0, 0, KErrNone}, // restore defaults
247 { 0, 0, KMaxTInt} // list end marker
250 for(TInt j=0; j<2; ++j)
254 test.Start(_L("Changing size of flushed VM cache"));
255 test.Printf(_L("Original cache size min == %u, max == %u\n"),originalMin/PageSize,originalMax/PageSize);
258 test.Next(_L("Changing size of full VM cache"));
260 while(testArgs[i].iResult!=KMaxTInt)
262 TUint min=testArgs[i].iMinPages*PageSize;
263 TUint max=testArgs[i].iMaxPages*PageSize;
264 TInt result=testArgs[i].iResult;
268 DPTest::FlushCache();
270 test.Printf(_L("DPTest::SetCacheSize min=%u, max=%u, expected result=%d\n"),min/PageSize,max/PageSize,result);
271 TInt r=DPTest::SetCacheSize(min,max);
274 test.Printf(_L("result=%d\n"),r);
279 // we've successfully changed the cache size...
287 sizeMin = originalMin;
288 sizeMax = originalMax;
293 // cache size after OOM is unpredictable, so reset our values
294 DPTest::SetCacheSize(sizeMin,sizeMax);
298 // test 'get' function returns expected cache size
299 r=DPTest::CacheSize(min,max,currentSize);
300 test.Printf(_L("DPTest::CacheSize result=%d min=%u max=%u current=%u\n"),r,min/PageSize,max/PageSize,currentSize/PageSize);
301 if(r!=KErrNone || min!=sizeMin || max!=sizeMax)
303 test(currentSize >= min && currentSize <= max);
314 void TestResizeVMCache2()
316 TUint originalMin = 0;
317 TUint originalMax = 0;
318 TUint currentSize = 0;
319 test_KErrNone(DPTest::CacheSize(originalMax, originalMax, currentSize));
320 test_KErrNone(DPTest::SetCacheSize(1, originalMax));
323 test_KErrNone(DPTest::CacheSize(sizeMin, sizeMax, currentSize));
325 test_KErrNone(DPTest::SetCacheSize(originalMin, originalMax));
331 test.Start(_L("DPTest::Attributes"));
332 TUint32 attr=DPTest::Attributes();
333 test.Printf(_L("Attributes = %08x\n"),attr);
335 test.Next(_L("DPTest::FlushCache"));
336 TInt r=DPTest::FlushCache();
337 if(r==KErrNotSupported)
338 test.Printf(_L("Not Supported\n"));
341 test.Printf(_L("Error = %d\n"),r);
345 test.Next(_L("DPTest::CacheSize"));
348 TUint currentSize = 0;
349 r=DPTest::CacheSize(oldMin,oldMax,currentSize);
350 if(r==KErrNotSupported)
351 test.Printf(_L("Not Supported\n"));
354 test.Printf(_L("Error = %d\n"),r);
359 test.Printf(_L("Size = %dk,%dk,%dk\n"),oldMin>>10,oldMax>>10,currentSize>>10);
362 test.Next(_L("DPTest::SetCacheSize"));
363 r=DPTest::SetCacheSize(oldMin,oldMax);
364 if(r==KErrNotSupported)
365 test.Printf(_L("Not Supported\n"));
368 test.Printf(_L("Error = %d\n"),r);
374 TestResizeVMCache2();
380 // Test IPC and realtime state
395 enum TRealtimeOutcome
403 class RTestSession : public RSessionBase
406 TInt Create(RServer2 aServer)
408 return CreateSession(aServer,TVersion(),-1);
410 inline TInt Send(const TIpcArgs& aArgs)
412 return RSessionBase::SendReceive(0,aArgs);
418 TInt IpcTestServerFunc(TAny* aArg)
420 TIpcDir dir = (TIpcDir)(((TInt)aArg) & 0xff);
421 TIpcObjectPaged paged = (TIpcObjectPaged)((((TInt)aArg) >> 8) & 0xff);
422 User::TRealtimeState realtime = (User::TRealtimeState)((((TInt)aArg) >> 16) & 0xff);
423 User::TRealtimeState clientRealtime = (User::TRealtimeState)((((TInt)aArg) >> 24) & 0xff);
426 // We want the server to fault the client when it is realtime
427 // and accessing paged out memory.
428 r = TestServer.CreateGlobal(KNullDesC, EIpcSession_Sharable, EServerRole_Default, EServerOpt_PinClientDescriptorsDisable);
431 RThread::Rendezvous(KErrNone);
434 TestServer.Receive(message);
435 if ((clientRealtime == User::ERealtimeStateOn) != message.ClientIsRealtime())
437 message.Complete(KErrNone); // complete connection request
440 TestServer.Receive(message,s);
441 User::WaitForRequest(s);
445 TInt32 unpagedContent;
446 TPtr8 unpagedDes((TUint8*)&unpagedContent, 4, 4);
447 TPtrC8 pagedContentBuf(SmallBuffer,sizeof(TInt));
449 TPtr8* dataPagedHeaderDes = (TPtr8*)DataPagedBuffer;
450 if (DataPagingSupported)
451 new (dataPagedHeaderDes) TPtr8((TUint8*)&unpagedContent, 4);
453 TPtr8 dataPagedContentDes(DataPagedBuffer + PageSize, 4);
455 r = DPTest::FlushCache();
459 User::SetRealtimeState(realtime);
460 if (dir == EServerRead)
465 r = message.Read(0,unpagedDes);
468 case EDesHeaderPaged:
469 r = DataPagingSupported ? message.Read(0,*dataPagedHeaderDes) : KErrNotSupported;
472 case EDesContentPaged:
473 r = DataPagingSupported ? message.Read(0,dataPagedContentDes) : KErrNotSupported;
481 else if (dir == EServerWrite)
486 r = message.Write(0,unpagedDes);
489 case EDesHeaderPaged:
490 r = message.Write(0,*PagedHeaderDes);
493 case EDesContentPaged:
494 r = message.Write(0,pagedContentBuf);
504 User::SetRealtimeState(User::ERealtimeStateOff);
506 message.Complete(KErrNone);
510 TInt IpcTestClientFunc(TAny* aArg)
512 TIpcDir dir = (TIpcDir)(((TInt)aArg) & 0xff);
513 TIpcObjectPaged paged = (TIpcObjectPaged)((((TInt)aArg) >> 8) & 0xff);
514 User::TRealtimeState realtime = (User::TRealtimeState)((((TInt)aArg) >> 16) & 0xff);
516 RTestSession session;
517 TInt r = session.Create(TestServer);
521 TInt32 unpagedContent;
522 TPtr8 unpagedDes((TUint8*)&unpagedContent, 4, 4);
523 TPtrC8 pagedContentBuf(SmallBuffer + PageSize, sizeof(TInt));
525 TPtr8* dataPagedHeaderDes = (TPtr8*)(DataPagedBuffer + (2 * PageSize));
526 if (DataPagingSupported)
527 new (dataPagedHeaderDes) TPtr8((TUint8*)&unpagedContent, 4);
529 TPtr8 dataPagedContentDes(DataPagedBuffer + (3 * PageSize), 4);
531 r = DPTest::FlushCache();
535 User::SetRealtimeState(realtime);
536 if (dir == EServerRead)
541 r = session.Send(TIpcArgs(&unpagedDes));
544 case EDesHeaderPaged:
545 r = session.Send(TIpcArgs(PagedHeaderDes));
548 case EDesContentPaged:
549 r = session.Send(TIpcArgs(&pagedContentBuf));
557 else if (dir == EServerWrite)
562 r = session.Send(TIpcArgs(&unpagedDes));
565 case EDesHeaderPaged:
566 r = DataPagingSupported ? session.Send(TIpcArgs(dataPagedHeaderDes)) : KErrNotSupported;
569 case EDesContentPaged:
570 r = DataPagingSupported ? session.Send(TIpcArgs(&dataPagedContentDes)) : KErrNotSupported;
580 User::SetRealtimeState(User::ERealtimeStateOff);
586 void TestRealtimeOutcome(RThread aThread, TRealtimeOutcome aOutcome)
591 test_Equal(EExitKill, aThread.ExitType());
592 test_KErrNone(aThread.ExitReason());
596 test_Equal(EExitKill, aThread.ExitType());
597 test_Equal(KErrBadDescriptor, aThread.ExitReason());
600 case EServerTerminated:
601 test_Equal(EExitKill, aThread.ExitType());
602 test_Equal(KErrServerTerminated, aThread.ExitReason());
606 test_Equal(EExitPanic, aThread.ExitType());
607 test(aThread.ExitCategory()==_L("KERN-EXEC"));
608 test_Equal(EIllegalFunctionForRealtimeThread, aThread.ExitReason());
616 void TestPagedIpc(TIpcDir aIpcDir,
617 TIpcObjectPaged aClientPaged,
618 TIpcObjectPaged aServerPaged,
619 User::TRealtimeState aClientState,
620 User::TRealtimeState aServerState,
621 TRealtimeOutcome aClientOutcome,
622 TRealtimeOutcome aServerOutcome)
624 test.Printf(_L("TestPagedIpc %d %d %d %d %d %d %d\n"), aIpcDir, aClientPaged, aServerPaged,
625 aClientState, aServerState, aClientOutcome, aServerOutcome);
627 RThread serverThread;
628 RThread clientThread;
629 TRequestStatus serverStatus;
630 TRequestStatus clientStatus;
632 TInt serverArg = aIpcDir | (aServerPaged << 8) | (aServerState << 16) | (aClientState << 24);
633 test_KErrNone(serverThread.Create(KNullDesC, &IpcTestServerFunc, 0x1000, NULL, (TAny*)serverArg));
635 name = serverThread.Name();
636 test.Printf(_L(" server: %S\n"), &name);
637 serverThread.Rendezvous(serverStatus);
638 serverThread.Resume();
639 User::WaitForRequest(serverStatus);
640 test_KErrNone(serverStatus.Int());
641 serverThread.Logon(serverStatus);
643 TInt clientArg = aIpcDir | (aClientPaged << 8) | (aClientState << 16);
644 test_KErrNone(clientThread.Create(KNullDesC, &IpcTestClientFunc, 0x1000, NULL, (TAny*)clientArg));
645 name = clientThread.Name();
646 test.Printf(_L(" client: %S\n"), &name);
647 clientThread.Logon(clientStatus);
648 clientThread.Resume();
650 User::WaitForRequest(serverStatus);
651 test.Printf(_L(" server exit type is %d %d\n"), serverThread.ExitType(), serverThread.ExitReason());
652 TestServer.Close(); // because handle is process-relative, it's not closed if the server dies
654 User::WaitForRequest(clientStatus);
655 test.Printf(_L(" client exit type is %d %d\n"), clientThread.ExitType(), clientThread.ExitReason());
657 TestRealtimeOutcome(serverThread, aServerOutcome);
658 TestRealtimeOutcome(clientThread, aClientOutcome);
660 CLOSE_AND_WAIT(serverThread);
661 CLOSE_AND_WAIT(clientThread);
664 TInt TestThreadFunction(TAny* aType)
666 // Ensure that pageable memory is paged out
667 TInt r=DPTest::FlushCache();
671 // Access pageable data whilst thread is in specified realttime state.
672 User::SetRealtimeState((User::TRealtimeState)(TInt)aType);
677 TInt RunTestThread(User::TRealtimeState aType, TRealtimeOutcome aOutcome)
680 TInt r=thread.Create(KNullDesC, &TestThreadFunction, 0x1000, NULL, (TAny*)aType);
685 if(s.Int()!=KRequestPending)
688 User::WaitForRequest(s);
689 TestRealtimeOutcome(thread, aOutcome);
690 CLOSE_AND_WAIT(thread);
694 void TestRealtimeState()
696 // make sure live list is big enough
697 test(KErrNone==DPTest::SetCacheSize(256*PageSize,256*PageSize));
699 test.Start(_L("Enable KREALTIME tracing"));
700 Ldd.SetRealtimeTrace(ETrue);
702 test.Next(_L("Test ERealtimeStateOff"));
703 RunTestThread(User::ERealtimeStateOff, ENoError);
705 test.Next(_L("Test ERealtimeStateOn"));
706 RunTestThread(User::ERealtimeStateOn, ERealtimePanic);
708 test.Next(_L("Test ERealtimeStateWarn"));
709 RunTestThread(User::ERealtimeStateWarn, ENoError);
711 test.Next(_L("Test combinations of IPC with realtime state"));
713 // ipc dir: client paged: server paged: client state: server state: client outcome: server outcome:
714 TestPagedIpc(EServerRead, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError);
715 TestPagedIpc(EServerRead, EDesHeaderPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError);
716 TestPagedIpc(EServerRead, EDesContentPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError);
717 TestPagedIpc(EServerWrite, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError);
718 TestPagedIpc(EServerWrite, ENothingPaged, EDesHeaderPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError);
719 TestPagedIpc(EServerWrite, ENothingPaged, EDesContentPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError);
721 if (DataPagingSupported)
723 TestPagedIpc(EServerRead, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError);
724 TestPagedIpc(EServerRead, ENothingPaged, EDesHeaderPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError);
725 TestPagedIpc(EServerRead, ENothingPaged, EDesContentPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError);
726 TestPagedIpc(EServerWrite, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError);
727 TestPagedIpc(EServerWrite, EDesHeaderPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError);
728 TestPagedIpc(EServerWrite, EDesContentPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError);
731 TestPagedIpc(EServerRead, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError);
732 TestPagedIpc(EServerRead, EDesHeaderPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError);
733 TestPagedIpc(EServerRead, EDesContentPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError);
734 TestPagedIpc(EServerWrite, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError);
735 TestPagedIpc(EServerWrite, ENothingPaged, EDesHeaderPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError);
736 TestPagedIpc(EServerWrite, ENothingPaged, EDesContentPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError);
738 if (DataPagingSupported)
740 TestPagedIpc(EServerRead, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError);
741 TestPagedIpc(EServerRead, ENothingPaged, EDesHeaderPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError);
742 TestPagedIpc(EServerRead, ENothingPaged, EDesContentPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError);
743 TestPagedIpc(EServerWrite, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError);
744 TestPagedIpc(EServerWrite, EDesHeaderPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError);
745 TestPagedIpc(EServerWrite, EDesContentPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError);
748 TestPagedIpc(EServerRead, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ENoError, ENoError);
749 TestPagedIpc(EServerRead, EDesHeaderPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ENoError, ENoError);
750 TestPagedIpc(EServerRead, EDesContentPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ERealtimePanic, EBadDescriptor);
751 TestPagedIpc(EServerWrite, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ENoError, ENoError);
752 TestPagedIpc(EServerWrite, ENothingPaged, EDesHeaderPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, EServerTerminated, ERealtimePanic);
753 TestPagedIpc(EServerWrite, ENothingPaged, EDesContentPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, EServerTerminated, ERealtimePanic);
755 if (DataPagingSupported)
757 TestPagedIpc(EServerRead, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ENoError, ENoError);
758 TestPagedIpc(EServerRead, ENothingPaged, EDesHeaderPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, EServerTerminated, ERealtimePanic);
759 TestPagedIpc(EServerRead, ENothingPaged, EDesContentPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, EServerTerminated, ERealtimePanic);
760 TestPagedIpc(EServerWrite, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ENoError, ENoError);
761 TestPagedIpc(EServerWrite, EDesHeaderPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ENoError, ENoError);
762 TestPagedIpc(EServerWrite, EDesContentPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ERealtimePanic, EBadDescriptor);
767 // retore size of live list
768 test(KErrNone==DPTest::SetCacheSize(0,0));
773 // make sure live list is big enough
774 test(KErrNone==DPTest::SetCacheSize(128 * PageSize, 256 * PageSize));
776 TInt r = Ldd.LockTest(SmallBuffer,SmallBufferSize);
779 test.Next(_L("Lock Test again"));
780 r = Ldd.LockTest(SmallBuffer,SmallBufferSize);
784 test.Printf(_L("failed at D_DEMANPAGING.CPP line %d\n"),r);
788 // restore live list to default size...
789 test(KErrNone==DPTest::SetCacheSize(0,0));
792 const TInt KSmallPropertySize = 512;
793 const TInt KLargePropertySize = 16384;
795 struct SSetPropertyInfo
803 TInt SetPropertyThreadFunction(TAny* aArg)
805 SSetPropertyInfo* info = (SSetPropertyInfo*)aArg;
807 r = DPTest::FlushCache();
810 TPtrC8 data(info->iData, info->iLength);
811 r = RProperty::Set(info->iCategory, info->iKey, data);
815 r = buffer.Create(KLargePropertySize);
818 r = RProperty::Get(info->iCategory, info->iKey, buffer);
819 if (r == KErrNone && buffer != data)
825 void TestPublishAndSubscribe()
827 RProcess thisProcess;
828 TUid category = thisProcess.SecureId();
830 TSecurityPolicy alwaysPass(TSecurityPolicy::EAlwaysPass);
831 test(RProperty::Define(category, 0, RProperty::EByteArray, alwaysPass, alwaysPass) == KErrNone);
832 test(RProperty::Define(category, 1, RProperty::ELargeByteArray, alwaysPass, alwaysPass) == KErrNone);
834 TPtrC8 smallData(SmallBuffer, KSmallPropertySize);
835 TPtrC8 largeData(SmallBuffer, KLargePropertySize);
838 test(buffer.Create(KLargePropertySize) == KErrNone);
840 // Set small property from paged data, method 1
841 test(DPTest::FlushCache() == KErrNone);
842 test(RProperty::Set(category, 0, smallData) == KErrNone);
843 test(RProperty::Get(category, 0, buffer) == KErrNone);
844 test(buffer == smallData);
846 // Set small property from paged data, method 2
848 test(smallProp.Attach(category, 0) == KErrNone);
849 test(DPTest::FlushCache() == KErrNone);
850 test(smallProp.Set(smallData) == KErrNone);
851 test(smallProp.Get(buffer) == KErrNone);
852 test(buffer == smallData);
854 // Set large property from paged data, method 1
855 test(DPTest::FlushCache() == KErrNone);
856 test(RProperty::Set(category, 1, largeData) == KErrNone);
857 test(RProperty::Get(category, 1, buffer) == KErrNone);
858 test(buffer == largeData);
860 // Set large property from paged data, method 2
862 test(largeProp.Attach(category, 1) == KErrNone);
863 test(DPTest::FlushCache() == KErrNone);
864 test(largeProp.Set(largeData) == KErrNone);
865 test(largeProp.Get(buffer) == KErrNone);
866 test(buffer == largeData);
868 // Set small property from unmapped address
870 #if !defined( __VC32__)
871 SSetPropertyInfo info = { category, 0, 0, KSmallPropertySize };
873 SSetPropertyInfo info = { category.iUid, 0, 0, KSmallPropertySize };
875 test(thread.Create(_L("SetPropertyThread"), SetPropertyThreadFunction, 4096, NULL, &info) == KErrNone);
877 TRequestStatus status;
878 thread.Logon(status);
879 User::WaitForRequest(status);
880 test(thread.ExitType()==EExitPanic);
881 test(thread.ExitCategory()==_L("KERN-EXEC"));
882 test(thread.ExitReason()==ECausedException);
885 // Set large property from unmapped address
887 info.iLength = KLargePropertySize;
888 test(thread.Create(_L("SetPropertyThread"), SetPropertyThreadFunction, 4096, NULL, &info) == KErrNone);
890 thread.Logon(status);
891 User::WaitForRequest(status);
892 test(thread.ExitType()==EExitPanic);
893 test(thread.ExitCategory()==_L("KERN-EXEC"));
894 test(thread.ExitReason()==ECausedException);
897 test(RProperty::Delete(category, 0) == KErrNone);
898 test(RProperty::Delete(category, 1) == KErrNone);
901 void TestWriteToPagedArea()
903 RMemoryTestLdd memoryTest;
904 test(KErrNone==memoryTest.Open());
906 TModuleMemoryInfo exeInfo;
907 test(KErrNone==RProcess().GetMemoryInfo(exeInfo));
908 test.Printf(_L("test program code is %x+%x"),exeInfo.iCodeBase,exeInfo.iCodeSize);
910 TUint8* ptr = const_cast<TUint8*>(LargeBuffer);
911 TUint8* end = ptr + LargeBufferSize;
914 if(ptr>=(TUint8*)_ALIGN_DOWN(exeInfo.iCodeBase,PageSize) && ptr<(TUint8*)_ALIGN_UP(exeInfo.iCodeBase+exeInfo.iCodeSize,PageSize))
916 // avoid testing the ROM which contains this test program
921 DPTest::FlushCache();
923 TInt stateBits = UserSvr::HalFunction(EHalGroupVM, EVMPageState, ptr, 0);
925 // write to paged out memory should cause exception...
926 test(KErrBadDescriptor==memoryTest.WriteMemory(ptr,0));
927 // page state should be unchanged...
928 TInt newStateBits = UserSvr::HalFunction(EHalGroupVM, EVMPageState, ptr, 0);
929 if(stateBits!=newStateBits)
931 test.Printf(_L("ptr=%x stateBits=%x newStateBits=%x"),ptr,stateBits,newStateBits);
934 // page-in in memory...
935 TUint32 value = *(TUint32*)ptr;
936 // write to paged out memory should still cause exception...
937 test(KErrBadDescriptor==memoryTest.WriteMemory(ptr,~value));
938 // memory should be unchanged...
939 test(value==*(TUint32*)ptr);
946 void TestContiguousRamAlloc()
948 test.Start(_L("Start..."));
950 const TInt KCacheSize = 1024*1024;
952 DPTest::SetCacheSize(0, KCacheSize); // make sure paging cache is a reasonable size
954 TInt testData[][2] = /* array of page size (in units of 'half pages') and align values */
973 while((1<<pageShift)<PageSize)
976 TInt* params = (TInt*)&testData;
979 TInt size = *params++<<(pageShift-1); //Size is units of half pages, so one less shift to get required memory size
980 TInt align = *params++;
982 align += pageShift - 1;
984 title.AppendFormat(_L("Contiguous RAM test: alloc size = %dK align = %d"),size>>10, align);
986 FragmentPagingCache(KCacheSize);
987 TInt r = Ldd.DoConsumeContiguousRamTest(align, size);
990 test.Printf(_L("failed at D_DEMANPAGING.CPP line %d\n"),r);
995 DPTest::SetCacheSize(0,0); // back to defaults
999 void TestReadHoldingMutex()
1001 TUint8 localBuf[16];
1002 TUint8* localPtr = localBuf;
1003 if(DPTest::Attributes() & DPTest::EDataPaging) // if data paging supported...
1004 localPtr = 0; // use zero to make driver use kernel memory as data destination
1005 test(Ldd.ReadHoldingMutexTest(localPtr) == KErrNone);
1008 #if 0 // rom dump code...
1009 #include <f32file.h>
1012 test(KErrNone==fs.Connect());
1013 test(KErrNone==file.Replace(fs, _L("d:\\ROMDUMP"),EFileWrite));
1014 TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
1015 TPtrC8 rom((TUint8*)romHeader,romHeader->iRomSize);
1016 test(KErrNone==file.Write(rom));
1023 class RMySession : public RSessionBase
1026 TInt Connect(RServer2 aSrv,TRequestStatus& aStat)
1028 TInt r=CreateSession(aSrv,TVersion(),-1,EIpcSession_Sharable,NULL,&aStat);
1029 if(!r) ShareAuto(); return r;
1031 TInt Send(TInt function,const TIpcArgs& args)
1032 {return SendReceive(function,args);}
1036 TUint8* TestBuffer = 0;
1037 RMySession MySession;
1039 LOCAL_C TInt TestServerThread(TAny* aSize)
1041 TInt r = TestServer.CreateGlobal(KNullDesC, EIpcSession_GlobalSharable);
1044 TestBuffer = (TUint8*)User::Alloc(KMaxIPCSize);
1048 TPtr8 buffer(TestBuffer,KMaxIPCSize);
1049 RThread::Rendezvous(r);
1054 TestServer.Receive(m);
1055 m.Complete(KErrNone); // connect message
1057 TBool running = ETrue;
1060 TestServer.Receive(m);
1061 RDebug::Printf("Server received: %d", m.Function());
1064 switch(m.Function())
1072 buffer.Set(SharedBuffer,KMaxIPCSize,KMaxIPCSize);
1075 // Perform CRC of data passed
1077 DPTest::FlushCache();
1082 Mem::Crc32(crc,buffer.Ptr(),buffer.Size());
1088 buffer.Set(SharedBuffer,KMaxIPCSize,KMaxIPCSize);
1091 // Write data to client descriptor
1093 DPTest::FlushCache();
1094 RDebug::Printf("Server writing %08x+%x", m.Int1(), m.Int2());
1095 TPtrC8 ptr((TUint8*)m.Int1(),m.Int2());
1101 // Just complete anything else
1107 RDebug::Printf("Server exiting");
1108 User::Free(TestBuffer);
1118 const TUint8* start = LargeBuffer + 0x3df; // make range not page aligned
1119 const TUint8* end = start + Min(LargeBufferSize, KMaxIPCSize * 10) - 0x130; // make range not page aligned
1122 test.Start(_L("Create server"));
1124 TInt r=t.Create(KNullDesC,TestServerThread,0x1000,KMaxIPCSize+0x1000,KMaxIPCSize+0x1000,(void*)0);
1126 t.SetPriority(EPriorityMore);
1130 User::WaitForRequest(s);
1131 test(TestServer.Handle() != KNullHandle);
1133 test(MySession.Connect(TestServer,s) == KErrNone);
1134 User::WaitForRequest(s); // connected
1136 TInt bufferType; // 0=server uses heap, 1=server uses SharedBuffer
1137 for(bufferType=0; bufferType<=1; ++bufferType)
1139 test.Next(_L("IPC read from ROM"));
1143 TInt size = end-pos;
1144 if(size>KMaxIPCSize)
1146 RDebug::Printf("read %x+%x",pos,size);
1147 TPtrC8 ptr(pos,size);
1148 TInt r = MySession.Send(1+bufferType,TIpcArgs(&ptr));
1149 DPTest::FlushCache();
1151 Mem::Crc32(crc,pos,size);
1152 RDebug::Printf("crc %08x %08x",r,crc);
1155 RDebug::Printf("FAIL");
1156 DPTest::FlushCache();
1158 for(TInt i=0; i<size; i+=4)
1161 TUint32 b = TestBuffer[i];
1163 RDebug::Printf("%08x %02x!=%02x",pos+i,a,b);
1168 test((TUint32)r==crc);
1172 test.Next(_L("IPC write from ROM"));
1176 TInt size = end-pos;
1177 if(size>KMaxIPCSize)
1179 RDebug::Printf("write %x+%x",pos,size);
1180 memclr(TestBuffer, KMaxIPCSize);
1181 TPtr8 ptr(TestBuffer,KMaxIPCSize); // reuse the server's buffer
1182 TInt r = MySession.Send(3+bufferType,TIpcArgs(&ptr,pos,size));
1184 DPTest::FlushCache();
1186 Mem::Crc32(crc,pos,size);
1188 Mem::Crc32(crc2,TestBuffer,size);
1189 RDebug::Printf("crc %08x %08x",crc,crc2);
1190 if((TUint32)crc!=crc2)
1192 RDebug::Printf("FAIL");
1193 DPTest::FlushCache();
1195 for(TInt i=0; i<size; i+=4)
1198 TUint32 b = TestBuffer[i];
1200 RDebug::Printf("%08x %02x!=%02x",pos+i,a,b);
1205 test((TUint32)crc==crc2);
1210 if (DPTest::Attributes() & DPTest::ERomPaging)
1212 test.Next(_L("Test passing descriptor headers in paged-out memory"));
1215 DPTest::FlushCache();
1216 TInt r = MySession.Send(5,TIpcArgs(PagedHeaderDes));
1217 test_Equal(KErrNone, r);
1219 UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
1223 test.Next(_L("Stop server"));
1224 MySession.Send(0,TIpcArgs(0));
1227 User::WaitForRequest(s);
1228 test_Equal(EExitKill, t.ExitType());
1229 test_Equal(KErrNone, t.ExitReason());
1233 UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
1242 test_KErrNone(UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&PageSize,0));
1244 if (DPTest::Attributes() & DPTest::ERomPaging)
1245 test.Printf(_L("Rom paging supported\n"));
1246 if (DPTest::Attributes() & DPTest::ECodePaging)
1247 test.Printf(_L("Code paging supported\n"));
1248 if (DPTest::Attributes() & DPTest::EDataPaging)
1250 test.Printf(_L("Data paging supported\n"));
1251 DataPagingSupported = ETrue;
1252 TChunkCreateInfo createInfo;
1253 createInfo.SetNormal(KMinBufferSize, KMinBufferSize);
1254 createInfo.SetPaging(TChunkCreateInfo::EPaged);
1255 createInfo.SetOwner(EOwnerProcess);
1256 createInfo.SetGlobal(KChunkName);
1257 test_KErrNone(DataPagedChunk.Create(createInfo));
1258 test(DataPagedChunk.IsPaged()); // this is only ever called if data paging is supported
1259 DataPagedBuffer = (TUint8*)DataPagedChunk.Base();
1262 test.Start(_L("Test HAL interface"));
1265 if (DPTest::Attributes() & DPTest::ERomPaging)
1267 // Use paged part of rom for testing
1268 TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
1269 test(romHeader->iPageableRomStart);
1270 // todo: for some reason the first part of page of paged rom doesn't seem to get paged out
1271 // when we flush the paging cache, hence LargeBuffer starts some way into this
1272 LargeBuffer = (TUint8*)romHeader + romHeader->iPageableRomStart + 64 * PageSize;
1273 LargeBufferSize = romHeader->iPageableRomSize - 64 * PageSize;
1274 test(LargeBufferSize > 0);
1275 // Find a zero word in rom to set PagedHeaderDes to
1276 TUint* ptr = (TUint*)LargeBuffer;
1277 TUint* end = (TUint*)(LargeBuffer + LargeBufferSize);
1278 while (*ptr && ptr < end)
1281 test.Printf(_L("Found zero word at %08x\n"), ptr);
1282 PagedHeaderDes = (TDesC8*)ptr;
1284 else if (DPTest::Attributes() & DPTest::ECodePaging)
1286 // Use code paged DLL for testing
1287 test_KErrNone(PagedLibrary.Load(KTCodePagingDll4));
1288 TGetAddressOfDataFunction func = (TGetAddressOfDataFunction)PagedLibrary.Lookup(KGetAddressOfDataFunctionOrdinal);
1289 LargeBuffer = (TUint8*)func(LargeBufferSize);
1290 test_NotNull(LargeBuffer);
1291 PagedHeaderDes = (TDesC8*)LargeBuffer + 4;
1293 else if (DPTest::Attributes() & DPTest::EDataPaging)
1295 // Use data paged chunk for testing
1296 LargeBuffer = DataPagedBuffer;
1297 LargeBufferSize = KMinBufferSize;
1301 test.Printf(_L("Demand Paging not supported\n"));
1306 test(LargeBufferSize >= KMinBufferSize);
1307 SmallBuffer = LargeBuffer;
1308 SmallBufferSize = KMinBufferSize;
1310 test.Next(_L("Loading test drivers"));
1311 TInt r = User::LoadLogicalDevice(KDemandPagingTestLddName);
1312 test(r==KErrNone || r==KErrAlreadyExists);
1313 test(Ldd.Open()==KErrNone);
1315 test_KErrNone(Ldd.CreatePlatHwChunk(SharedBufferSize, SharedBufferAddr));
1316 SharedBuffer = (TUint8*)SharedBufferAddr;
1318 RDebug::Printf("SmallBuffer=%x, LargeBuffer=%x, SharedBuffer=%x\n",
1319 SmallBuffer, LargeBuffer, SharedBuffer);
1321 test.Next(_L("Gobble RAM"));
1322 r = User::LoadLogicalDevice(KGobblerLddFileName);
1323 test(r==KErrNone || r==KErrAlreadyExists);
1327 TUint32 taken = gobbler.GobbleRAM(64*1024*1024); // leave 64MB of free RAM
1328 test.Printf(_L("Gobbled: %dK\n"), taken/1024);
1329 test.Printf(_L("Free RAM 0x%08X bytes\n"),FreeRam());
1331 test.Next(_L("Test contiguous RAM allocation reclaims paged memory"));
1332 TestContiguousRamAlloc();
1334 test.Next(_L("Test thread realtime state"));
1335 TestRealtimeState();
1337 test.Next(_L("Lock Test"));
1340 test.Next(_L("Test writing to paged area"));
1341 TestWriteToPagedArea();
1343 test.Next(_L("Test IPC read from paged memory"));
1346 test.Next(_L("Test no kernel faults when copying data from unpaged rom with mutex held"));
1347 TestReadHoldingMutex();
1349 test.Next(_L("Close test driver"));
1350 Ldd.DestroyPlatHwChunk();
1353 test.Next(_L("Test setting publish and subscribe properties from paged area"));
1354 TestPublishAndSubscribe();
1356 if (DPTest::Attributes() & DPTest::ERomPaging)
1358 test.Next(_L("Rom Paging Benchmark"));
1359 RomPagingBenchmark();
1362 PagedLibrary.Close();