First public contribution.
1 // Copyright (c) 2004-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_sharedchunk.cpp
16 // Test sharing an RChunk with a logical device
20 // - Load and open the logical device driver ("D_SHAREDCHUNK"). Verify
22 // - Test and verify results of creating shared chunks under OOM conditions. Also verify
23 // creating a chunk with a bad type, bad size and too large all fail as
25 // - Test and verify opening and closing chunk user handles work as expected.
26 // - Test and verify thread local and process local handles work as expected
27 // - Test and verify setting restrictions on RChunk if created as shared chunk are as expected.
28 // - Test and verify memory access for multiply and singly shared chunks,
29 // is as expected. Including IPC, kernel, DFC and ISR reads & writes.
30 // - Test and verify discontinuous memory commits for multiply and singly
31 // shared chunks are as expected.
32 // - Test and verify continuous memory commits for multiply and singly shared
33 // chunks are as expected.
34 // - Test and verify discontinuous and continuous physical memory commits for
35 // multiply and singly shared chunks is as expected.
36 // - Test Kern::OpenSharedChunk for multiply and singly shared chunks. Verify
37 // results are as expected.
38 // - Test that physical memory can be freed immediately after the chunk that mapped
39 // it has been closed.
40 // Platforms/Drives/Compatibility:
42 // Assumptions/Requirement/Pre-requisites:
43 // Failures and causes:
44 // Base Port information:
49 //! @SYMTestCaseID KBASE-T_SHAREDCHUNK
51 //! @SYMTestPriority High
52 //! @SYMTestActions Check creation, memory allocation and access to Shared Chunks
53 //! @SYMTestExpectedResults Test runs until this message is emitted: RTEST: SUCCESS : T_SHAREDCHUNK test completed O.K.
55 #define __E32TEST_EXTENSION__
57 #include "d_sharedchunk.h"
66 #include <e32def_private.h>
83 TUint32 MemModelAttributes;
84 TBool PhysicalCommitSupported;
85 TBool CachingAttributesSupported;
88 const TUint ChunkSize = 0x400000; // 4 meg reserved space for test chunk
90 _LIT(KSecondProcessName,"t_sharedchunk");
91 #ifdef __T_SHAREDCHUNKF__
92 _LIT(KOtherProcessName,"t_sharedchunk");
93 LOCAL_D RTest test(_L("T_SHAREDCHUNKF"));
95 _LIT(KOtherProcessName,"t_sharedchunkf");
96 LOCAL_D RTest test(_L("T_SHAREDCHUNK"));
99 _LIT8(KTestString, "lks4b7qeyfcea5fyaifyaefyi4flwdysuxanabxa");
100 _LIT8(KTestString2,"jhfcalurnhfirlxszhrvcvduhrvndrucxnshxcsx");
101 const TUint32 KTestValue = 0x12345678;
102 const TUint32 KTestValue2 = KTestValue^0x0f0f0f0f;
105 // Utilitiies for use by tests
109 _LIT(KLitKernExec, "KERN-EXEC");
111 void CheckFailMessage(const char* n,const char* c,const char* f,TInt r)
113 TPtrC8 nn((const TUint8*)n);
114 TPtrC8 cc((const TUint8*)c);
115 TPtrC8 ff((const TUint8*)f);
117 buf.Create((nn.Size()+cc.Size()+ff.Size()+64)*2);
118 buf.AppendFormat(_L8("\nCHECK failed: %S == 0x%x but was tested for %S%S\n"),&ff,r,&cc,&nn);
119 test.Printf(buf.Expand());
123 #define CHECK(n,c,f) \
126 if(!((TInt)(n)c(_r))) \
128 CheckFailMessage(#n,#c,#f,_r); \
133 #define KCHECK_MEMORY(result,offset) \
135 /* test.Printf(_L("check offset 0x%08x\r"),offset); */ \
136 CHECK(result,==,Ldd.CheckMemory(offset)); \
139 #define KWRITE_MEMORY(offset,value) \
141 CHECK(KErrNone,==,Ldd.WriteMemory(offset,value)); \
144 #define UREAD_MEMORY(offset,value) \
146 CHECK(value,==,*(TUint*)(Base+offset)); \
149 inline TUint32 Tag(TUint32 offset)
150 { return (69069u*(offset*4+1)); }
152 TInt MemoryAccessThread(TAny* aAddress)
154 TInt r = *(volatile TUint8*)aAddress; // read from aAddress
159 TInt CheckUMemory(TAny* aAddress)
162 thread.Create(KNullDesC,MemoryAccessThread,PageSize,&User::Heap(),aAddress);
163 TRequestStatus status;
164 thread.Logon(status);
165 TBool jit = User::JustInTime();
166 User::SetJustInTime(EFalse);
168 User::WaitForRequest(status);
169 User::SetJustInTime(jit);
171 if(thread.ExitType()==EExitKill && thread.ExitReason()==0)
172 r = 1; // Memory access pass
173 else if(thread.ExitType()==EExitPanic && thread.ExitCategory()==KLitKernExec && thread.ExitReason()==3 )
174 r = 0; // Memory access failed
176 r = -1; // Unexpected result
177 CLOSE_AND_WAIT(thread);
181 #define UCHECK_MEMORY(result,offset) \
183 /* test.Printf(_L("ucheck offset 0x%08x\r"),offset); */ \
184 CHECK(result,==,CheckUMemory(Base+offset)); \
187 TInt CheckPlatSecPanic(TThreadFunction aThreadFunction,TInt aThreadArgument)
190 thread.Create(KNullDesC,aThreadFunction,PageSize,&User::Heap(),(TAny*)aThreadArgument);
191 TRequestStatus status;
192 thread.Logon(status);
193 TBool jit = User::JustInTime();
194 User::SetJustInTime(EFalse);
196 User::WaitForRequest(status);
197 User::SetJustInTime(jit);
199 if(thread.ExitType()==EExitPanic && thread.ExitCategory()==KLitKernExec && thread.ExitReason()==46 )
200 r = 1; // PlatSec panic
201 else if(thread.ExitType()==EExitKill && thread.ExitReason()==0)
202 r = 0; // Exit without error
204 r = -1; // Unexpected result
205 CLOSE_AND_WAIT(thread);
213 void CreateWithOomCheck(TInt aCreateFlags)
215 TInt failResult=KErrGeneral;
216 for(TInt failCount=1; failCount<1000; failCount++)
218 test.Printf(_L("alloc fail count = %d\n"),failCount);
219 User::__DbgSetBurstAllocFail(ETrue,RAllocator::EFailNext,failCount,1000);
221 failResult = Ldd.CreateChunk(aCreateFlags);
222 if(failResult==KErrNone)
224 CHECK(KErrNoMemory,==,failResult);
225 Ldd.IsDestroyed(); // This includes delay to let idle thread do cleanup
228 User::__DbgSetAllocFail(ETrue,RAllocator::ENone,0);
230 CHECK(KErrNone,==,failResult);
235 test.Start(_L("Creating chunk type Single,OwnsMemory"));
236 CreateWithOomCheck(ChunkSize|ESingle|EOwnsMemory);
237 CHECK(0,==,Ldd.IsDestroyed());
239 test.Next(_L("Close kernel handle"));
240 CHECK(1,==,Ldd.CloseChunk()); // 1==DObject::EObjectDeleted
241 CHECK(1,==,Ldd.IsDestroyed());
243 test.Next(_L("Creating chunk type Multiple,OwnsMemory"));
244 CreateWithOomCheck(ChunkSize|EMultiple|EOwnsMemory);
245 CHECK(0,==,Ldd.IsDestroyed());
247 test.Next(_L("Close kernel handle"));
248 CHECK(1,==,Ldd.CloseChunk()); // 1==DObject::EObjectDeleted
249 CHECK(1,==,Ldd.IsDestroyed());
251 if(PhysicalCommitSupported)
253 test.Next(_L("Creating chunk type Single,!OwnsMemory"));
254 CreateWithOomCheck(ChunkSize|ESingle);
255 CHECK(0,==,Ldd.IsDestroyed());
257 test.Next(_L("Close kernel handle"));
258 CHECK(1,==,Ldd.CloseChunk()); // 1==DObject::EObjectDeleted
259 CHECK(1,==,Ldd.IsDestroyed());
261 test.Next(_L("Creating chunk type Multiple,!OwnsMemory"));
262 CreateWithOomCheck(ChunkSize|EMultiple);
263 CHECK(0,==,Ldd.IsDestroyed());
265 test.Next(_L("Close kernel handle"));
266 CHECK(1,==,Ldd.CloseChunk()); // 1==DObject::EObjectDeleted
267 CHECK(1,==,Ldd.IsDestroyed());
271 test.Next(_L("Try creating unsupported chunk type Single,!OwnsMemory"));
272 CHECK(KErrNotSupported,==,Ldd.CreateChunk(ChunkSize|ESingle));
274 test.Next(_L("Try creating unsupported chunk type Multiple,!OwnsMemory"));
275 CHECK(KErrNotSupported,==,Ldd.CreateChunk(ChunkSize|EMultiple));
278 test.Next(_L("__KHEAP_MARK"));
281 test.Next(_L("Creating chunk (bad type)"));
282 CHECK(KErrArgument,==,Ldd.CreateChunk(EBadType|EOwnsMemory|ChunkSize));
284 test.Next(_L("Creating chunk (bad size)"));
285 CHECK(KErrArgument,==,Ldd.CreateChunk(ESingle|EOwnsMemory|0xffffff00));
287 test.Next(_L("Creating chunk (size too big)"));
288 CHECK(KErrNoMemory,==,Ldd.CreateChunk(ESingle|EOwnsMemory|0x7fffff00));
290 test.Next(_L("__KHEAP_MARKEND"));
297 void OpenWithOomCheck(RChunk& aChunk)
299 TInt failResult=KErrGeneral;
300 for(TInt failCount=1; failCount<1000; failCount++)
302 test.Printf(_L("alloc fail count = %d\n"),failCount);
303 User::__DbgSetBurstAllocFail(ETrue,RAllocator::EFailNext,failCount,1000);
305 failResult = Ldd.GetChunkHandle(aChunk);
306 if(failResult==KErrNone)
308 CHECK(KErrNoMemory,==,failResult);
309 Ldd.IsDestroyed(); // This includes delay to let idle thread do cleanup
312 User::__DbgSetAllocFail(ETrue,RAllocator::ENone,0);
314 CHECK(KErrNone,==,failResult);
319 TUint ChunkAttribs = ChunkSize|ESingle|EOwnsMemory;
321 test.Start(_L("Create chunk"));
322 CHECK(KErrNone,==,Ldd.CreateChunk(ChunkAttribs));
324 test.Next(_L("Open user handle"));
325 OpenWithOomCheck(TheChunk);
327 test.Next(_L("Close user handle"));
330 test.Next(_L("Check chunk not destroyed"));
331 CHECK(0,==,Ldd.IsDestroyed());
333 test.Next(_L("Close kernel handle"));
334 CHECK(1,==,Ldd.CloseChunk()); // 1==DObject::EObjectDeleted
336 test.Next(_L("Check chunk destroyed"));
337 CHECK(1,==,Ldd.IsDestroyed());
339 // Another chunk - closing handles in reverse order
341 test.Next(_L("Create chunk"));
342 CHECK(KErrNone,==,Ldd.CreateChunk(ChunkAttribs));
344 test.Next(_L("Open user handle"));
345 OpenWithOomCheck(TheChunk);
347 test.Next(_L("Close kernel handle"));
348 CHECK(KErrNone,==,Ldd.CloseChunk());
350 test.Next(_L("Check chunk not destroyed"));
351 CHECK(0,==,Ldd.IsDestroyed());
353 test.Next(_L("Using user handle to check chunk info"));
354 if((MemModelAttributes&EMemModelTypeMask)!=EMemModelTypeDirect)
356 CHECK(0,==,TheChunk.Size());
358 CHECK(ChunkSize,==,TheChunk.MaxSize());
360 test.Next(_L("Close user handle"));
363 test.Next(_L("Check chunk destroyed"));
364 CHECK(1,==,Ldd.IsDestroyed());
369 TInt HandleOwnershipThread(TAny* aArg)
371 // Use existing handle and attempt to read from chunk
372 TInt handle = (TInt) aArg;
374 chunk.SetHandle(handle);
375 TInt r = *(volatile TUint8*)chunk.Base();
377 CLOSE_AND_WAIT(chunk);
381 void TestHandleOwnership()
383 TUint ChunkAttribs = ChunkSize|ESingle|EOwnsMemory;
387 test.Start(_L("Create chunk"));
388 CHECK(KErrNone,==,Ldd.CreateChunk(ChunkAttribs));
390 test.Next(_L("Commit page to chunk"));
391 CHECK(KErrNone,==,Ldd.CommitMemory(EDiscontiguous,PageSize));
393 test.Next(_L("Check can access memory kernel side"));
394 KCHECK_MEMORY(ETrue, 0);
396 // Handle is thread-owned
397 test.Next(_L("Open user handle (thread-owned)"));
398 CHECK(0,<=,Ldd.GetChunkHandle(TheChunk, ETrue));
400 test.Next(_L("Get memory size info"));
401 if((MemModelAttributes&EMemModelTypeMask)!=EMemModelTypeDirect)
403 CHECK(PageSize,==,TheChunk.Size());
405 CHECK(ChunkSize,==,TheChunk.MaxSize());
406 TUint8* Base = TheChunk.Base();
409 test.Next(_L("Check can access memory user side"));
410 UCHECK_MEMORY(ETrue, 0);
412 test.Next(_L("Use handle in a new thread"));
413 CHECK(KErrNone,==,thread.Create(_L("thread1"), HandleOwnershipThread, KDefaultStackSize, KMinHeapSize, KMinHeapSize, (TAny*)TheChunk.Handle()));
416 User::WaitForRequest(rs);
417 CHECK(EExitPanic,==,thread.ExitType());
418 CHECK(0,==,thread.ExitReason()); // KERN-EXEC 0
419 CLOSE_AND_WAIT(thread);
421 test.Next(_L("Close user handle"));
424 // Handle is process-owned
425 test.Next(_L("Open user handle (process-owned"));
426 CHECK(0,<=,Ldd.GetChunkHandle(TheChunk, EFalse));
428 test.Next(_L("Check can access memory user side"));
429 UCHECK_MEMORY(ETrue, 0);
431 test.Next(_L("Close kernel handle"));
432 CHECK(KErrNone,==,Ldd.CloseChunk());
434 test.Next(_L("Check chunk destroyed"));
435 CHECK(0,==,Ldd.IsDestroyed());
437 test.Next(_L("Use handle in a new thread"));
438 CHECK(KErrNone,==,thread.Create(_L("thread2"), HandleOwnershipThread, KDefaultStackSize, KMinHeapSize, KMinHeapSize, (TAny*)TheChunk.Handle()));
441 User::WaitForRequest(rs);
442 CHECK(EExitKill,==,thread.ExitType());
443 CHECK(KErrNone,==,thread.ExitReason());
444 CLOSE_AND_WAIT(thread);
446 test.Next(_L("Check chunk destroyed"));
447 CHECK(1,==,Ldd.IsDestroyed()); // Object was deleted
452 void SetCreateFlags(TUint& aCreateFlags,TCommitType aCommitType)
454 if(!((TInt)aCommitType&EPhysicalMask))
455 aCreateFlags |= EOwnsMemory;
457 aCreateFlags &= ~EOwnsMemory;
461 void TestAccess(TUint aCreateFlags,TCommitType aCommitType)
463 const TUint32 offset = 0;
464 const TUint32 size = PageSize;
466 SetCreateFlags(aCreateFlags,aCommitType);
468 test.Start(_L("Create chunk"));
469 TUint8* kernelAddress;
470 CHECK(KErrNone,==,Ldd.CreateChunk(aCreateFlags|ChunkSize,(TAny**)&kernelAddress));
472 if((MemModelAttributes&TUint32(EMemModelAttrNonExProt)) && (MemModelAttributes&EMemModelTypeMask)!=EMemModelTypeDirect)
474 test.Next(_L("Check can't access memory"));
475 KCHECK_MEMORY(EFalse,offset);
478 test.Next(_L("Commit page to chunk"));
479 CHECK(KErrNone,==,Ldd.CommitMemory(aCommitType|offset,size));
481 test.Next(_L("Check can access memory kernel side"));
482 KCHECK_MEMORY(ETrue, offset);
484 if((MemModelAttributes&EMemModelAttrKernProt) && (MemModelAttributes&EMemModelTypeMask)!=EMemModelTypeDirect)
486 test.Next(_L("Check user side can't access kernel memory"));
487 TUint8* Base = kernelAddress;
488 UCHECK_MEMORY(EFalse, offset);
491 test.Next(_L("Open user handle"));
492 CHECK(KErrNone,==,Ldd.GetChunkHandle(TheChunk));
494 test.Next(_L("Get memory size info"));
495 if((MemModelAttributes&EMemModelTypeMask)!=EMemModelTypeDirect)
497 CHECK(PageSize,==,TheChunk.Size());
499 CHECK(ChunkSize,==,TheChunk.MaxSize());
500 TUint8* Base = TheChunk.Base();
503 test.Next(_L("Check can access memory user side"));
504 UCHECK_MEMORY(ETrue, offset);
506 test.Next(_L("Check user and kernel access same memory"));
507 KWRITE_MEMORY(offset,~Tag(offset));
508 UREAD_MEMORY(offset,~Tag(offset));
509 KWRITE_MEMORY(offset,Tag(offset));
510 UREAD_MEMORY(offset,Tag(offset));
512 test.Next(_L("Close user handle"));
513 CHECK(0,==,Ldd.CloseChunkHandle(TheChunk));
514 CHECK(0,==,Ldd.IsDestroyed());
516 if((MemModelAttributes&EMemModelAttrKernProt) && (MemModelAttributes&EMemModelTypeMask)!=EMemModelTypeDirect)
518 test.Next(_L("Check can no-longer access memory user side"));
519 UCHECK_MEMORY(EFalse,offset);
522 test.Next(_L("Check can still access memory kernel side"));
523 KCHECK_MEMORY(ETrue, offset);
525 test.Next(_L("Open user handle again"));
526 CHECK(KErrNone,==,Ldd.GetChunkHandle(TheChunk));
528 test.Next(_L("Check can access chunk user side again"));
529 CHECK(Base,==,TheChunk.Base());
530 CHECK(ChunkSize,==,TheChunk.MaxSize());
531 if((MemModelAttributes&EMemModelTypeMask)!=EMemModelTypeDirect)
533 CHECK(size,==,TheChunk.Size());
535 UREAD_MEMORY(offset,Tag(offset));
537 test.Next(_L("Close kernel handle"));
538 CHECK(0,==,Ldd.CloseChunk());
539 CHECK(0,==,Ldd.IsDestroyed());
541 test.Next(_L("Check can still access chunk user side"));
542 CHECK(Base,==,TheChunk.Base());
543 CHECK(ChunkSize,==,TheChunk.MaxSize());
544 if((MemModelAttributes&EMemModelTypeMask)!=EMemModelTypeDirect)
546 CHECK(size,==,TheChunk.Size());
548 UREAD_MEMORY(offset,Tag(offset));
550 test.Next(_L("Close user handle"));
552 CHECK(1,==,Ldd.IsDestroyed());
554 test.Next(_L("Create chunk in another process"));
556 // Create test server
559 TRequestStatus status;
560 CHECK(KErrNone,==,server.CreateGlobal(KSecondProcessName));
561 server.Receive(message,status);
563 // Launch slave process
565 CHECK(KErrNone,==,process.Create(KSecondProcessName,KNullDesC));
566 CHECK(KErrNone,==,process.SetParameter(1,ESlaveCreateChunk));
567 CHECK(KErrNone,==,process.SetParameter(2,(RBusLogicalChannel&)Ldd));
568 CHECK(KErrNone,==,process.SetParameter(3,ChunkSize|aCreateFlags));
569 CHECK(KErrNone,==,process.SetParameter(4,aCommitType));
570 CHECK(KErrNone,==,process.SetParameter(5,PageSize));
571 TRequestStatus logon;
572 process.Logon(logon);
575 // Wait for slave to connect to test server
576 User::WaitForRequest(logon,status);
577 CHECK(KRequestPending,==,logon.Int())
578 CHECK(KErrNone,==,status.Int());
579 CHECK(RMessage2::EConnect,==,message.Function());
580 message.Complete(KErrNone);
581 server.Receive(message,status);
584 User::WaitForRequest(logon,status);
585 CHECK(KRequestPending,==,logon.Int())
586 CHECK(KErrNone,==,status.Int());
587 CHECK(0,==,message.Function());
589 test.Next(_L("Check IPC read/write"));
591 buf.Create(KTestString().Size());
592 CHECK(KErrNone,==,message.Read(0,buf));
593 CHECK(ETrue,==,buf==KTestString());
594 CHECK(KErrNone,==,message.Write(0,KTestString2));
595 CHECK(KErrNone,==,message.Read(0,buf));
596 CHECK(ETrue,==,buf==KTestString2());
598 test.Next(_L("Check Kernel read/write"));
601 for(n=0; n<KTestString2().Size()-(TInt)sizeof(TInt)+1; n+=sizeof(TInt))
603 Ldd.ReadMemory(n,value);
604 CHECK(*(TInt*)&KTestString2()[n],==,value);
605 CHECK(KErrNone,==,Ldd.WriteMemory(n,*(TInt*)&KTestString()[n]));
606 Ldd.ReadMemory(n,value);
607 CHECK(*(TInt*)&KTestString()[n],==,value);
609 CHECK(KErrNone,==,message.Read(0,buf));
610 CHECK(ETrue,==,buf==KTestString());
613 test.Next(_L("Check read/write from DFC"));
614 CHECK(KErrNone,==,Ldd.WriteMemory(0,KTestValue));
616 CHECK(KErrNone,==,Ldd.DfcReadWrite(0,value));
617 CHECK(KTestValue,==,value);
618 CHECK(KErrNone,==,Ldd.ReadMemory(0,value));
619 CHECK(KTestValue2,==,value);
621 test.Next(_L("Check read/write from ISR"));
622 CHECK(KErrNone,==,Ldd.WriteMemory(0,KTestValue));
624 CHECK(KErrNone,==,Ldd.IsrReadWrite(0,value));
625 CHECK(KTestValue,==,value);
626 CHECK(KErrNone,==,Ldd.ReadMemory(0,value));
627 CHECK(KTestValue2,==,value);
629 test.Next(_L("Cleanup resources"));
631 User::WaitForRequest(logon);
632 CLOSE_AND_WAIT(process);
638 RProcess OtherProcess;
640 TInt HandleShare(TAny* aHandle)
642 TInt r=OtherProcess.Create(KOtherProcessName,KNullDesC,EOwnerProcess);
645 r = OtherProcess.SetParameter(1,(RChunk&)aHandle);
650 void TestRestrictions(TInt aAttrib)
652 TUint ChunkAttribs = ChunkSize|aAttrib|EOwnsMemory;
654 test.Start(_L("Create chunk"));
655 CHECK(KErrNone,==,Ldd.CreateChunk(ChunkAttribs));
657 test.Next(_L("Open user handle"));
658 CHECK(KErrNone,==,Ldd.GetChunkHandle(TheChunk));
660 test.Next(_L("Try changing restrictions"));
661 CHECK(KErrAccessDenied,==,TheChunk.SetRestrictions(0));
663 test.Next(_L("Check allocation restrictions"));
664 CHECK(KErrAccessDenied,==,TheChunk.Adjust(ChunkSize/2));
665 CHECK(KErrAccessDenied,==,TheChunk.AdjustDoubleEnded(PageSize,ChunkSize));
666 CHECK(KErrAccessDenied,==,TheChunk.Commit(PageSize,PageSize));
667 CHECK(KErrAccessDenied,==,TheChunk.Allocate(PageSize));
668 CHECK(KErrAccessDenied,==,TheChunk.Decommit(PageSize,PageSize));
670 test.Next(_L("Duplicate handle in same process"));
672 chunk2.SetHandle(TheChunk.Handle());
673 CHECK(KErrNone,==,chunk2.Duplicate(RThread(),EOwnerProcess));
675 test.Next(_L("Try passing handle to other process"));
676 if(aAttrib==EMultiple)
678 CHECK(0,==,CheckPlatSecPanic(HandleShare,*(TInt*)&chunk2));
682 CHECK(1,==,CheckPlatSecPanic(HandleShare,*(TInt*)&chunk2));
684 // Cleanup leftover process
685 OtherProcess.Kill(0);
686 OtherProcess.Close();
688 test.Next(_L("Close handles"));
690 CHECK(0,==,Ldd.CloseChunk());
702 TInt iExpectedResult;
705 void CheckRegion(TCommitRegion aRegion, TBool aCheckClear)
707 TUint8* Base = TheChunk.Base();
708 TInt offset = aRegion.iOffset*PageSize;
709 TInt limit = offset+aRegion.iSize*PageSize;
712 KCHECK_MEMORY(1,offset);
713 UCHECK_MEMORY(1,offset);
719 TUint32* ptr = (TUint32*)(Base+aRegion.iOffset*PageSize);
720 TUint32* end = (TUint32*)((TInt)ptr+aRegion.iSize*PageSize);
722 if(*ptr++!=0x03030303u)
724 CHECK(0x03030303u,==,*ptr);
728 void SetTags(TCommitRegion aRegion)
730 TUint8* Base = TheChunk.Base();
731 TInt offset = aRegion.iOffset*PageSize;
732 TInt limit = offset+aRegion.iSize*PageSize;
735 *(TUint*)(Base+offset) = Tag(offset);
736 offset += sizeof(TUint);
740 void CheckTags(const TCommitRegion& aRegion)
742 TUint8* Base = TheChunk.Base();
743 TInt offset = aRegion.iOffset*PageSize;
744 TInt limit = offset+aRegion.iSize*PageSize;
747 KCHECK_MEMORY(1,offset); // Check page exists
748 TInt limit2 = offset+PageSize;
751 UREAD_MEMORY(offset,Tag(offset)); // Check contents match tags we set previousely
752 offset += sizeof(TUint);
757 void CheckOldTags(const TCommitRegion& aRegion, TInt aNewOffset)
759 TUint8* Base = TheChunk.Base();
760 TInt oldOffset = aRegion.iOffset*PageSize;
761 TInt offset = aNewOffset;
762 TInt limit = offset+aRegion.iSize*PageSize;
765 KCHECK_MEMORY(1,offset); // Check page exists
766 TInt limit2 = offset+PageSize;
769 UREAD_MEMORY(offset,Tag(oldOffset)); // Check contents matched old tags
770 offset += sizeof(TUint);
771 oldOffset += sizeof(TUint);
776 // Following assumes 4k pages...
777 static const TCommitRegion CommitList[] =
779 {0,0}, // zero size commit
782 // Regions which overlap previous commit
783 {1,1,KErrAlreadyExists},
784 {0,2,KErrAlreadyExists},
785 {1,2,KErrAlreadyExists},
786 {0,3,KErrAlreadyExists},
791 {250,6}, // pages at end of chunk boundary
793 {768,256}, // whole 1meg chunk
795 {400,512,KErrAlreadyExists}, // Monster commit which overlaps previous regions
797 {256,257}, // big commit which straddles more than one 1meg chunk
799 {-1,-1} // End marker
802 void CheckCommitedContents(TInt aIndex)
805 if(CommitList[aIndex].iExpectedResult==KErrNone)
806 CheckTags(CommitList[aIndex]);
809 void CheckCommitState(TInt aIndex)
812 TInt lastPage=TheChunk.MaxSize()/PageSize;
817 if(CommitList[i].iExpectedResult==KErrNone)
818 if((TUint)(page-CommitList[i].iOffset) < (TUint)CommitList[i].iSize)
820 TInt offset = page*PageSize;
823 KCHECK_MEMORY(1,offset); // Check page exists
827 KCHECK_MEMORY(0,offset); // Check page doesn't exists
834 void TestCommit(TUint aCreateFlags,TCommitType aCommitType)
836 SetCreateFlags(aCreateFlags,aCommitType);
837 TUint ChunkAttribs = ChunkSize|aCreateFlags;
839 test.Start(_L("Create chunk"));
840 CHECK(KErrNone,==,Ldd.CreateChunk(ChunkAttribs));
842 test.Next(_L("Check wrong commit type"));
843 CHECK(KErrNotSupported,==,Ldd.CommitMemory((aCommitType^EPhysicalMask)|0,PageSize));
844 CHECK(KErrNotSupported,==,Ldd.CommitMemory((aCommitType^EPhysicalMask^EContiguous)|0,PageSize));
846 if((TInt)aCommitType&EPhysicalMask)
848 test.Next(_L("Check commit with bad pysical address"));
849 CHECK(KErrArgument,==,Ldd.CommitMemory((aCommitType|EBadPhysicalAddress)|0,PageSize));
852 test.Next(_L("Open user handle"));
853 CHECK(KErrNone,==,Ldd.GetChunkHandle(TheChunk));
855 const TCommitRegion* list = CommitList;
856 for(;list->iOffset>=0; ++list)
858 TInt offset = list->iOffset*PageSize;
859 TInt size = list->iSize*PageSize;
860 TInt expectedResult = list->iExpectedResult;
861 if((MemModelAttributes&EMemModelTypeMask)==EMemModelTypeDirect && expectedResult==KErrAlreadyExists)
864 text.AppendFormat(_L("Commit pages: offset=%08x size=%08x expectedResult=%d"),offset,size,expectedResult);
867 test.Start(_L("Do the Commit"));
868 CHECK(expectedResult,==,Ldd.CommitMemory(aCommitType|offset,size));
870 if(expectedResult==KErrNone)
872 test.Next(_L("Check new memory has been comitted"));
873 CheckRegion(*list,!(aCommitType&EPhysicalMask));
876 if((MemModelAttributes&EMemModelTypeMask)!=EMemModelTypeDirect)
878 test.Next(_L("Check commit state of all pages in chunk"));
879 CheckCommitState(list-CommitList+1);
882 test.Next(_L("Check contents of previous commited regions are unchanged"));
883 CheckCommitedContents(list-CommitList);
885 if(expectedResult==KErrNone)
887 test.Next(_L("Mark new memory"));
893 if((aCreateFlags&EMultiple) && (MemModelAttributes&EMemModelTypeMask)!=EMemModelTypeDirect)
895 test.Next(_L("Check another process sees same chunk state"));
896 TInt regionCount = list-CommitList;
898 // create another process
900 CHECK(KErrNone,==,process.Create(KOtherProcessName,KNullDesC));
901 CHECK(KErrNone,==,process.SetParameter(1,ESlaveCheckChunk));
902 CHECK(KErrNone,==,process.SetParameter(2,(RBusLogicalChannel&)Ldd));
903 CHECK(KErrNone,==,process.SetParameter(3,(RChunk&)TheChunk));
904 CHECK(KErrNone,==,process.SetParameter(4,regionCount));
905 TRequestStatus status;
906 process.Logon(status);
909 // Check chunk again in this process, concurrently with other process
910 CheckCommitedContents(regionCount);
911 CheckCommitState(regionCount);
913 // wait for other process to finish
914 User::WaitForRequest(status);
915 CHECK(EExitKill,==,process.ExitType());
916 CHECK(0,==,process.ExitReason());
917 CLOSE_AND_WAIT(process);
920 test.Next(_L("Close handles"));
922 CHECK(1,==,Ldd.CloseChunk());
924 if(aCommitType&EPhysicalMask)
926 // For Physical commit tests, check correct allocation by creating a new chunk
927 // and checking that pages comitted contain the old TAGs placed there by the
930 test.Next(_L("Check commit uses correct physical pages"));
932 test.Start(_L("Create chunk"));
933 CHECK(KErrNone,==,Ldd.CreateChunk(ChunkAttribs));
935 test.Next(_L("Open user handle"));
936 CHECK(KErrNone,==,Ldd.GetChunkHandle(TheChunk));
939 for(list=CommitList; list->iOffset>=0; ++list)
941 if(list->iExpectedResult!=KErrNone)
944 TInt size = list->iSize*PageSize;
946 text.AppendFormat(_L("Commit pages: offset=%08x size=%08x"),offset,size);
948 CHECK(KErrNone,==,Ldd.CommitMemory(aCommitType|offset,size));
950 test.Next(_L("Check RAM contents preserved from previous usage"));
951 CheckOldTags(*list,offset);
955 test.Next(_L("Close handles"));
957 CHECK(1,==,Ldd.CloseChunk());
963 // We don't do these OOM tests for Physical commit because we can't do it reliably
964 // (as only a couple of page tables come from the free pool not the whole memory
966 test.Next(_L("Check Out Of Memory conditions"));
968 // Make sure any clean up has happened otherwise the amount of free RAM may change.
969 UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
971 test.Start(_L("Gobble up most of RAM"));
972 test.Next(_L("Load gobbler LDD"));
973 TInt r = User::LoadLogicalDevice(KGobblerLddFileName);
974 test(r==KErrNone || r==KErrAlreadyExists);
978 TUint32 taken = gobbler.GobbleRAM(2*1024*1024);
979 test.Printf(_L("Gobbled: %dK\n"), taken/1024);
980 test.Printf(_L("Free RAM 0x%08X bytes\n"),FreeRam());
982 test.Next(_L("Get baseline free memory"));
984 TInt freeRam1 = FreeRam();
986 test.Next(_L("Create shared chunk"));
987 CHECK(KErrNone,==,Ldd.CreateChunk(ChunkAttribs));
988 TInt freeRam2 = FreeRam();
990 test.Next(_L("Commit memory which will causes OOM"));
991 CHECK(KErrNoMemory,==,Ldd.CommitMemory(aCommitType,4096*1024));
993 test.Next(_L("Check free RAM unchanged"));
994 CHECK(freeRam2,==,FreeRam());
996 test.Next(_L("Check OOM during ChunkCommit"));
997 TInt failResult=KErrGeneral;
998 for(TInt failCount=1; failCount<1000; failCount++)
1000 User::__DbgSetAllocFail(ETrue,RAllocator::EFailNext,failCount);
1001 failResult = Ldd.CommitMemory(aCommitType,1);
1002 if(failResult==KErrNone)
1004 CHECK(KErrNoMemory,==,failResult);
1006 User::__DbgSetAllocFail(ETrue,RAllocator::ENone,0);
1007 CHECK(KErrNone,==,failResult);
1009 test.Next(_L("Destroy shared chunk"));
1010 CHECK(1,==,Ldd.CloseChunk());
1011 CHECK(1,==,Ldd.IsDestroyed());
1013 test.Next(_L("Check free memory returns to baseline"));
1014 CHECK(freeRam1,==,FreeRam());
1017 test.Next(_L("Free gobbled RAM"));
1027 void TestOpenSharedChunk(TUint aCreateFlags,TCommitType aCommitType)
1029 SetCreateFlags(aCreateFlags,aCommitType);
1030 TUint ChunkAttribs = ChunkSize|aCreateFlags;
1032 test.Start(_L("Create chunk"));
1033 CHECK(KErrNone,==,Ldd.CreateChunk(ChunkAttribs));
1035 test.Next(_L("Open user handle"));
1036 CHECK(KErrNone,==,Ldd.GetChunkHandle(TheChunk));
1038 test.Next(_L("Commit some memory"));
1039 CHECK(KErrNone,==,Ldd.CommitMemory(aCommitType|1*PageSize,PageSize));
1040 CHECK(KErrNone,==,Ldd.CommitMemory(aCommitType|2*PageSize,PageSize));
1041 CHECK(KErrNone,==,Ldd.CommitMemory(aCommitType|4*PageSize,PageSize));
1043 test.Next(_L("Check OpenSharedChunk with handle"));
1044 CHECK(KErrNone,==,Ldd.TestOpenHandle(TheChunk.Handle()));
1046 test.Next(_L("Check OpenSharedChunk with wrong chunk handle"));
1048 CHECK(KErrNone,==,testChunk.CreateLocal(PageSize,PageSize));
1049 CHECK(KErrNotFound,==,Ldd.TestOpenHandle(testChunk.Handle()));
1052 test.Next(_L("Check OpenSharedChunk with wrong handle type"));
1053 CHECK(KErrNotFound,==,Ldd.TestOpenHandle(RThread().Handle()));
1055 test.Next(_L("Check OpenSharedChunk with bad handle"));
1056 CHECK(KErrNotFound,==,Ldd.TestOpenHandle(0));
1058 test.Next(_L("Check OpenSharedChunk with address"));
1059 TUint8* Base = TheChunk.Base();
1060 CHECK(KErrNone,==,Ldd.TestOpenAddress(Base));
1061 CHECK(KErrNone,==,Ldd.TestOpenAddress(Base+ChunkSize-1));
1063 test.Next(_L("Check OpenSharedChunk with bad address"));
1064 CHECK(KErrNotFound,==,Ldd.TestOpenAddress(Base-1));
1065 CHECK(KErrNotFound,==,Ldd.TestOpenAddress(Base+ChunkSize));
1066 CHECK(KErrNotFound,==,Ldd.TestOpenAddress(0));
1067 CHECK(KErrNotFound,==,Ldd.TestOpenAddress((TAny*)~0));
1069 test.Next(_L("Check OpenSharedChunk with stack memory address"));
1070 TUint8 stackMem[100];
1071 CHECK(KErrNotFound,==,Ldd.TestOpenAddress(stackMem));
1073 test.Next(_L("Check OpenSharedChunk with heap memory address"));
1074 TUint8* heapMem = new TUint8[100];
1075 CHECK(0,!=,heapMem);
1076 CHECK(KErrNotFound,==,Ldd.TestOpenAddress(heapMem));
1079 test.Next(_L("Check OpenSharedChunk with BSS memory address"));
1080 CHECK(KErrNotFound,==,Ldd.TestOpenAddress(BssMem));
1082 test.Next(_L("Check OpenSharedChunk with code memory address"));
1083 CHECK(KErrNotFound,==,Ldd.TestOpenAddress((TAny*)&TestOpenSharedChunk));
1085 test.Next(_L("Check OpenSharedChunk with NULL address"));
1086 CHECK(KErrNotFound,==,Ldd.TestOpenAddress(0));
1088 test.Next(_L("Check ChunkAddress for given memory region"));
1089 static const TCommitRegion regions[] =
1106 {0,10240,KErrArgument}, // too big
1107 {1,0,KErrArgument}, // bad size
1108 {1,-1,KErrArgument}, // bad size
1109 {10240,1,KErrArgument}, // bad offset
1110 {-2,2,KErrArgument}, // bad offset
1113 const TCommitRegion* region = regions;
1114 for(;region->iOffset!=-1; ++region)
1116 TUint32 offset = region->iOffset*PageSize;
1117 TUint32 size = region->iSize*PageSize;
1118 TInt expectedResult = region->iExpectedResult;
1119 if((MemModelAttributes&EMemModelTypeMask)==EMemModelTypeDirect && expectedResult==KErrNotFound)
1122 text.AppendFormat(_L("Memory region: offset=%08x size=%08x expectedResult=%d"),offset,size,expectedResult);
1124 CHECK(expectedResult,==,Ldd.TestAddress(offset,size));
1127 test.Next(_L("Close handles"));
1129 CHECK(1,==,Ldd.CloseChunk());
1135 void AccessSpeed(TCreateFlags aCreateFlags, TInt& aRead,TInt& aWrite)
1137 // test.Start(_L("Create chunk"));
1138 CHECK(KErrNone,==,Ldd.CreateChunk(ChunkSize|ESingle|EOwnsMemory|aCreateFlags));
1140 // test.Next(_L("Commit some memory"));
1141 if((MemModelAttributes&EMemModelTypeMask)==EMemModelTypeDirect)
1143 CHECK(KErrNone,==,Ldd.CommitMemory(EDiscontiguous|0*PageSize,PageSize));
1147 // Allocate contiguous memory when possible so that the
1148 // Cache::SyncMemoryBeforeXxxx calls in the test driver get exercised
1149 CHECK(KErrNone,==,Ldd.CommitMemory(EContiguous|0*PageSize,PageSize));
1152 // test.Next(_L("Open user handle"));
1153 CHECK(KErrNone,==,Ldd.GetChunkHandle(TheChunk));
1154 volatile TUint32* p = (TUint32*)TheChunk.Base();
1157 TInt itterCount=128;
1161 TUint32 lastCount=User::NTickCount();
1162 for(TInt i=itterCount; i>0; --i)
1164 TUint32 x=p[0]; x=p[1]; x=p[2]; x=p[3]; x=p[4]; x=p[5]; x=p[6]; x=p[7];
1166 time = User::NTickCount()-lastCount;
1169 aRead = itterCount*8/time;
1175 TUint32 lastCount=User::NTickCount();
1176 for(TInt i=itterCount; i>0; --i)
1178 p[0]=i; p[1]=i; p[2]=i; p[3]=i; p[4]=i; p[5]=i; p[6]=i; p[7]=i;
1180 time = User::NTickCount()-lastCount;
1183 aWrite = itterCount*8/time;
1186 text.AppendFormat(_L("Read speed=%7d Write speed=%7d\n"),aRead,aWrite);
1189 // test.Next(_L("Close handles"));
1191 CHECK(1,==,Ldd.CloseChunk());
1196 void TestMappingAttributes()
1198 test.Start(_L("Fully Blocking"));
1201 AccessSpeed(EBlocking,blockedRead,blockedWrite);
1206 test.Next(_L("Write Buffered"));
1207 AccessSpeed(EBuffered,read,write);
1208 CHECK(2*blockedRead,>,read);
1209 // CHECK(2*blockedWrite,<,write); // Write buffering doesn't seem to work when cache disabled (?)
1211 test.Next(_L("Fully Cached"));
1212 AccessSpeed(ECached,read,write);
1213 CHECK(2*blockedRead,<,read);
1214 #ifndef __X86__ // X86 seems to do always do write buffering
1215 // Following check disabled because most dev boards only seem to be a bit faster
1216 // and asserting a particular speed improvement is unreliable
1217 // CHECK(2*blockedWrite,<,write);
1223 class RSession : public RSessionBase
1226 inline TInt CreateSession(const TDesC& aServer,const TVersion& aVersion)
1227 { return RSessionBase::CreateSession(aServer,aVersion); }
1228 inline TInt SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
1229 { return RSessionBase::SendReceive(aFunction,aArgs); }
1232 TInt SlaveCommand(TSlaveCommand aCommand)
1234 RDebug::Print(_L("Slave Process - Command %d\n"),aCommand);
1235 CHECK(KErrNone,==,UserHal::PageSizeInBytes(PageSize));
1236 CHECK(KErrNone,==,((RBusLogicalChannel&)Ldd).Open(2,EOwnerProcess));
1239 case ESlaveCheckChunk:
1241 RDebug::Print(_L("Slave Process - TheChunk.Open()\n"));
1242 CHECK(KErrNone,==,TheChunk.Open(3));
1243 RDebug::Print(_L("Slave Process - Get Region Count\n"));
1245 CHECK(KErrNone,==,User::GetTIntParameter(4,regionCount));
1246 RDebug::Print(_L("Slave Process - CheckCommitedContents(%d)\n"),regionCount);
1247 CheckCommitedContents(regionCount);
1248 RDebug::Print(_L("Slave Process - CheckCommitState(%d)\n"),regionCount);
1249 CheckCommitState(regionCount);
1250 RDebug::Print(_L("Slave Process - Done\n"));
1254 case ESlaveCreateChunk:
1256 RDebug::Print(_L("Slave Process - Get parameters\n"));
1260 CHECK(KErrNone,==,User::GetTIntParameter(3,createFlags));
1261 CHECK(KErrNone,==,User::GetTIntParameter(4,commitType));
1262 CHECK(KErrNone,==,User::GetTIntParameter(5,commitSize));
1264 RDebug::Print(_L("Slave Process - Create Chunk\n"));
1265 CHECK(KErrNone,==,Ldd.CreateChunk(createFlags));
1266 CHECK(KErrNone,==,Ldd.CommitMemory(commitType,commitSize));
1267 CHECK(KErrNone,==,Ldd.GetChunkHandle(TheChunk));
1268 TUint8* chunkBase=TheChunk.Base();
1269 memcpy(chunkBase,KTestString().Ptr(),KTestString().Size());
1271 RDebug::Print(_L("Slave Process - Connecting to test server\n"));
1273 CHECK(KErrNone,==,session.CreateSession(KSecondProcessName,TVersion()));
1275 RDebug::Print(_L("Slave Process - Sending message\n"));
1276 TPtr8 ptr(chunkBase,commitSize,commitSize);
1277 session.SendReceive(0,TIpcArgs(&ptr));
1279 RDebug::Print(_L("Slave Process - Destroy Chunk\n"));
1281 CHECK(1,==,Ldd.CloseChunk()); // 1==DObject::EObjectDeleted
1282 CHECK(1,==,Ldd.IsDestroyed());
1287 RDebug::Print(_L("Slave Process - Bad Command\n"));
1288 return KErrArgument;
1292 void TestChunkUserBase()
1294 TUint ChunkAttribs = ChunkSize|ESingle|EOwnsMemory;
1296 test.Start(_L("Create chunk"));
1297 CHECK(KErrNone,==,Ldd.CreateChunk(ChunkAttribs));
1299 test.Next(_L("Open user handle"));
1300 CHECK(KErrNone,==,Ldd.GetChunkHandle(TheChunk));
1302 test.Next(_L("Commit some memory"));
1303 CHECK(KErrNone,==,Ldd.CommitMemory(EDiscontiguous|1*PageSize,PageSize));
1305 test.Next(_L("Check OpenSharedChunk with handle"));
1306 CHECK(KErrNone,==,Ldd.TestOpenHandle(TheChunk.Handle()));
1308 test.Next(_L("Get Kernel's user base"));
1309 TAny *kernelUserAddress;
1310 CHECK(KErrNone,==,Ldd.GetChunkUserBase(&kernelUserAddress));
1311 TAny *userAddress = TheChunk.Base();
1312 test(kernelUserAddress == userAddress);
1315 CHECK(1,==,Ldd.CloseChunk());
1323 // Running as slave?
1325 if(User::GetTIntParameter(1,slaveCommand)==KErrNone)
1326 return SlaveCommand((TSlaveCommand)slaveCommand);
1328 // Turn off lazy dll unloading
1330 test(l.Connect()==KErrNone);
1331 test(l.CancelLazyDllUnload()==KErrNone);
1336 MemModelAttributes=UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL);
1337 TUint mm=MemModelAttributes&EMemModelTypeMask;
1338 #ifdef __T_SHAREDCHUNKF__
1339 if(mm!=EMemModelTypeMoving)
1341 test.Start(_L("TESTS NOT RUN - Only valid on Moving Memory Model"));
1347 test.Start(_L("Initialise"));
1348 CHECK(KErrNone,==,UserHal::PageSizeInBytes(PageSize));
1349 PhysicalCommitSupported = mm!=EMemModelTypeDirect && mm!=EMemModelTypeEmul;
1350 CachingAttributesSupported = mm!=EMemModelTypeDirect && mm!=EMemModelTypeEmul;
1353 test.Next(_L("Loading test driver"));
1354 TInt r = User::LoadLogicalDevice(KSharedChunkLddName);
1355 test(r==KErrNone || r==KErrAlreadyExists);
1357 test.Next(_L("Opening channel"));
1358 CHECK(KErrNone,==,Ldd.Open());
1360 // now 'unload' test driver, however, it will remain loaded whilst
1361 // we still have a channel open with it...
1362 User::FreeLogicalDevice(KSharedChunkLddName);
1364 test.Next(_L("Test chunk create"));
1367 test.Next(_L("Test handles"));
1370 test.Next(_L("Test handle ownership"));
1371 TestHandleOwnership();
1373 test.Next(_L("Test restrictions for multiply shared chunks"));
1374 TestRestrictions(EMultiple);
1375 test.Next(_L("Test restrictions for singly shared chunks"));
1376 TestRestrictions(ESingle);
1378 test.Next(_L("Test memory access for multiply shared chunks"));
1379 TestAccess(EMultiple|EOwnsMemory,EDiscontiguous);
1380 test.Next(_L("Test memory access for singly shared chunks"));
1381 TestAccess(ESingle|EOwnsMemory,EDiscontiguous);
1383 test.Next(_L("Test Discontiguous memory commit for multiply shared chunks"));
1384 TestCommit(EMultiple,EDiscontiguous);
1385 test.Next(_L("Test Discontiguous memory commit for singly shared chunks"));
1386 TestCommit(ESingle,EDiscontiguous);
1388 if((MemModelAttributes&EMemModelTypeMask)!=EMemModelTypeDirect)
1390 test.Next(_L("Test Contiguous memory commit for multiply shared chunks"));
1391 TestCommit(EMultiple,EContiguous);
1392 test.Next(_L("Test Contiguous memory commit for singly shared chunks"));
1393 TestCommit(ESingle,EContiguous);
1396 if(PhysicalCommitSupported)
1398 test.Next(_L("Test Discontiguous Physical commit for multiply shared chunks"));
1399 TestCommit(EMultiple,EDiscontiguousPhysical);
1400 test.Next(_L("Test Discontiguous Physical commit for singly shared chunks"));
1401 TestCommit(ESingle,EDiscontiguousPhysical);
1403 test.Next(_L("Test Contiguous Physical commit for multiply shared chunks"));
1404 TestCommit(EMultiple,EContiguousPhysical);
1405 test.Next(_L("Test Contiguous Physical commit for singly shared chunks"));
1406 TestCommit(ESingle,EContiguousPhysical);
1409 test.Next(_L("Test Kern::OpenSharedChunk for multiply shared chunks"));
1410 TestOpenSharedChunk(EMultiple,EDiscontiguous);
1411 test.Next(_L("Test Kern::OpenSharedChunk for singly shared chunks"));
1412 TestOpenSharedChunk(ESingle,EDiscontiguous);
1414 if(CachingAttributesSupported)
1416 test.Next(_L("Test Mapping Attributes"));
1417 TestMappingAttributes();
1420 test.Next(_L("Testing Kern::ChunkUserBase for shared chunks"));
1421 TestChunkUserBase();
1423 if (PhysicalCommitSupported)
1425 test.Next(_L("Testing Kern::ChunkClose allows immediate freeing of physical ram"));
1426 test_KErrNone(Ldd.TestChunkCloseAndFree());
1429 test.Next(_L("Close test driver"));