sl@0: // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test\mmu\t_chunk4.cpp sl@0: // Overview: sl@0: // Test disconnected chunks sl@0: // API Information: sl@0: // RChunk, CBase sl@0: // Details: sl@0: // - Check Allocate/Commit/Decommit methods on local disconnected chunk and write/read sl@0: // access to both committed and uncommitted regions. sl@0: // - Check IPC that involves local disconnected chunk and verify results are as expected. sl@0: // Platforms/Drives/Compatibility: sl@0: // All. sl@0: // Assumptions/Requirement/Pre-requisites: sl@0: // Failures and causes: sl@0: // Base Port information: sl@0: // sl@0: // sl@0: sl@0: #define __E32TEST_EXTENSION__ sl@0: #include sl@0: #include "u32std.h" sl@0: #include "mmudetect.h" sl@0: #include "../misc/prbs.h" sl@0: #include "d_memorytest.h" sl@0: #include "freeram.h" sl@0: sl@0: RTest test(_L("T_CHUNK4")); sl@0: sl@0: RMemoryTestLdd TestLdd; sl@0: sl@0: TUint RndSeed[2]; sl@0: sl@0: class CChunk : public CBase sl@0: { sl@0: public: sl@0: static CChunk* New(TInt aMaxSize); sl@0: public: sl@0: virtual ~CChunk(); sl@0: TInt Verify(); sl@0: TInt Commit(TInt anOffset, TInt aSize); sl@0: TInt Allocate(TInt aSize); sl@0: TInt Decommit(TInt anOffset, TInt aSize); sl@0: void CheckL(volatile TUint* aPtr); sl@0: TInt AddPages(TInt anOffset, TInt aSize); sl@0: TInt RemovePages(TInt anOffset, TInt aSize); sl@0: public: sl@0: RChunk iChunk; sl@0: TUint8* iPageInfo; sl@0: TInt iPageSize; sl@0: TInt iMaxSize; sl@0: TInt iNumPages; sl@0: }; sl@0: sl@0: CChunk* CChunk::New(TInt aMaxSize) sl@0: { sl@0: CChunk* pC=new CChunk; sl@0: if (pC) sl@0: { sl@0: TInt p; sl@0: UserHal::PageSizeInBytes(p); sl@0: pC->iPageSize=p; sl@0: pC->iMaxSize=aMaxSize; sl@0: TInt n=aMaxSize/p; sl@0: pC->iNumPages=n; sl@0: TInt r=pC->iChunk.CreateDisconnectedLocal(0,0,aMaxSize); sl@0: if (r==KErrNone) sl@0: { sl@0: TUint8* pI=(TUint8*)User::Alloc(n); sl@0: if (pI) sl@0: { sl@0: pC->iPageInfo=pI; sl@0: Mem::FillZ(pI,n); sl@0: } sl@0: else sl@0: r=KErrNoMemory; sl@0: } sl@0: if (r!=KErrNone) sl@0: { sl@0: delete pC; sl@0: pC=NULL; sl@0: } sl@0: } sl@0: return pC; sl@0: } sl@0: sl@0: CChunk::~CChunk() sl@0: { sl@0: delete iPageInfo; sl@0: iChunk.Close(); sl@0: } sl@0: sl@0: void CChunk::CheckL(volatile TUint* aPtr) sl@0: { sl@0: TUint x=*aPtr; sl@0: *aPtr=x; sl@0: } sl@0: sl@0: TInt CChunk::Verify() sl@0: { sl@0: // test.Getch(); sl@0: TInt i; sl@0: TUint8* base=iChunk.Base(); sl@0: for (i=0; i=0) sl@0: { sl@0: AddPages(r,aSize); sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: TInt CChunk::Decommit(TInt anOffset, TInt aSize) sl@0: { sl@0: TInt r=iChunk.Decommit(anOffset,aSize); sl@0: if (r==KErrNone) sl@0: { sl@0: RemovePages(anOffset,aSize); sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: // Stuff to test remote writes sl@0: _LIT(KServerName, "Chunk4Test"); sl@0: sl@0: class CTestSession : public CSession2 sl@0: { sl@0: public: sl@0: CTestSession(); sl@0: virtual void ServiceL(const RMessage2& aMessage); sl@0: }; sl@0: sl@0: class CTestServer : public CServer2 sl@0: { sl@0: public: sl@0: CTestServer(); sl@0: virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const; sl@0: }; sl@0: sl@0: class RTestSession : public RSessionBase sl@0: { sl@0: public: sl@0: enum {ETestIpc, ETestStop}; sl@0: TInt Connect(); sl@0: void Stop(); sl@0: TInt TestRemoteWrite(TInt aLength, TInt anOffset1, TInt anOffset2, TInt anOffset3, TInt anOffset4); sl@0: TInt IpcWrite(TDes8* aRemoteDest, const TAny* aLocalSrc, TInt aOffset); sl@0: }; sl@0: sl@0: CTestSession::CTestSession() sl@0: { sl@0: } sl@0: sl@0: void CTestSession::ServiceL(const RMessage2& aMessage) sl@0: { sl@0: switch (aMessage.Function()) sl@0: { sl@0: case RTestSession::ETestIpc: sl@0: { sl@0: const TDesC8& localSrc = *(const TDesC8*)aMessage.Ptr1(); sl@0: TInt offset = aMessage.Int2(); sl@0: TInt r = aMessage.Write(0, localSrc, offset); sl@0: aMessage.Complete(r); sl@0: break; sl@0: } sl@0: case RTestSession::ETestStop: sl@0: CActiveScheduler::Stop(); sl@0: break; sl@0: default: sl@0: User::Invariant(); sl@0: } sl@0: } sl@0: sl@0: CTestServer::CTestServer() sl@0: : CServer2(0) sl@0: { sl@0: } sl@0: sl@0: CSession2* CTestServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const sl@0: { sl@0: return new (ELeave) CTestSession; sl@0: } sl@0: sl@0: TInt ServerThread(TAny*) sl@0: { sl@0: CActiveScheduler* pA = new CActiveScheduler; sl@0: CTestServer* pS = new CTestServer; sl@0: if (!pA || !pS) sl@0: return KErrNoMemory; sl@0: CActiveScheduler::Install(pA); sl@0: TInt r = pS->Start(KServerName); sl@0: if (r!=KErrNone) sl@0: return r; sl@0: RThread::Rendezvous(KErrNone); sl@0: CActiveScheduler::Start(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt RTestSession::Connect() sl@0: { sl@0: RThread t; sl@0: TInt r = t.Create(KServerName, ServerThread, 0x1000, 0x1000, 0x10000, NULL); sl@0: test(r==KErrNone); sl@0: t.SetPriority(EPriorityMore); sl@0: TRequestStatus s; sl@0: t.Rendezvous(s); sl@0: test(s==KRequestPending); sl@0: t.Resume(); sl@0: User::WaitForRequest(s); sl@0: test(t.ExitType()==EExitPending); sl@0: test(s==KErrNone); sl@0: t.Close(); sl@0: r = CreateSession(KServerName, TVersion()); sl@0: return r; sl@0: } sl@0: sl@0: void RTestSession::Stop() sl@0: { sl@0: TInt r = SendReceive(ETestStop); sl@0: test(r==KErrServerTerminated); sl@0: Close(); sl@0: } sl@0: sl@0: TInt RTestSession::IpcWrite(TDes8* aRemoteDest, const TAny* aLocalSrc, TInt aOffset) sl@0: { sl@0: return SendReceive(ETestIpc, TIpcArgs(aRemoteDest, aLocalSrc, aOffset)); sl@0: } sl@0: sl@0: TInt RTestSession::TestRemoteWrite(TInt aLength, TInt anOffset1, TInt anOffset2, TInt anOffset3, TInt anOffset4) sl@0: { sl@0: test.Printf(_L("%x %x %x %x %x\n"),aLength,anOffset1,anOffset2,anOffset3,anOffset4); sl@0: sl@0: TBool ptr=(anOffset1>=0); sl@0: TDes8* pDes; sl@0: TUint8* pData; sl@0: RChunk c; sl@0: TInt r=c.CreateDisconnectedLocal(0,0,0x800000); sl@0: test(r==KErrNone); sl@0: TUint8* base=c.Base(); sl@0: if (ptr) sl@0: { sl@0: r=c.Commit(anOffset1,(TInt)sizeof(TPtr8)); sl@0: test(r==KErrNone); sl@0: pDes=(TDes8*)(base+anOffset1); sl@0: Mem::FillZ(pDes,(TInt)sizeof(TPtr8)); sl@0: r=c.Commit(anOffset2,aLength); sl@0: test(r==KErrNone); sl@0: pData=base+anOffset2; sl@0: Mem::FillZ(pData,aLength); sl@0: new(pDes) TPtr8(pData,0,aLength); sl@0: test(pDes->Length()==0); sl@0: test(pDes->MaxLength()==aLength); sl@0: test(pDes->Ptr()==pData); sl@0: } sl@0: else sl@0: { sl@0: TInt len=(TInt)sizeof(TDes8)+aLength; sl@0: r=c.Commit(anOffset2,len); sl@0: test(r==KErrNone); sl@0: pDes=(TDes8*)(base+anOffset2); sl@0: Mem::FillZ(pDes,len); sl@0: pData=base+anOffset2+(TInt)sizeof(TDes8); sl@0: new(pDes) TBuf8<1>; sl@0: ((TInt*)pDes)[1]=aLength; sl@0: test(pDes->Length()==0); sl@0: test(pDes->MaxLength()==aLength); sl@0: test(pDes->Ptr()==pData); sl@0: } sl@0: TInt slen=aLength-anOffset3; sl@0: TUint8* pS=(TUint8*)User::Alloc(aLength); sl@0: test(pS!=NULL); sl@0: Mem::FillZ(pS,aLength); sl@0: TPtrC8 src(pS+anOffset3,slen); sl@0: TInt i; sl@0: for (i=anOffset3; i=0) sl@0: c.Decommit(anOffset4,0x1000); sl@0: r = IpcWrite(pDes, &src, anOffset3); sl@0: if (r==KErrNone) sl@0: { sl@0: TPtrC8 tsrc(pS,aLength); sl@0: if (*pDes!=tsrc) sl@0: r=KErrCorrupt; sl@0: } sl@0: User::Free(pS); sl@0: c.Close(); sl@0: test.Printf(_L("Return value %d\n"),r); sl@0: return r; sl@0: } sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: RndSeed[0]=0xddb3d743; sl@0: RndSeed[1]=0; sl@0: sl@0: test.Title(); sl@0: if (!HaveVirtMem()) sl@0: { sl@0: test.Printf(_L("This test requires an MMU\n")); sl@0: return KErrNone; sl@0: } sl@0: test.Start(_L("Testing Disconnected Chunks")); sl@0: sl@0: test.Printf(_L("Load test LDD\n")); sl@0: test(TestLdd.Open()==KErrNone); sl@0: sl@0: CChunk* pC=CChunk::New(0x800000); sl@0: test(pC!=NULL); sl@0: TInt free=FreeRam(); sl@0: test.Printf(_L("Free RAM %08x\n"),free); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Commit 0+0x1000\n")); sl@0: test(pC->Commit(0,0x1000)==KErrNone); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Commit 0+0x1000 (again)\n")); sl@0: test(pC->Commit(0,0x1000)==KErrAlreadyExists); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Commit 0x3000+0x1000\n")); sl@0: test(pC->Commit(0x3000,0x1000)==KErrNone); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Commit 0x2000+0x3000 (overlaps previous)\n")); sl@0: test(pC->Commit(0x2000,0x3000)==KErrAlreadyExists); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Allocate 0x5000\n")); sl@0: test(pC->Allocate(0x5000)==0x4000); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Allocate 0x1000\n")); sl@0: test(pC->Allocate(0x1000)==0x1000); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Decommit 0+0x4000\n")); sl@0: test(pC->Decommit(0,0x4000)==KErrNone); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Decommit 0+0x4000 (again)\n")); sl@0: test(pC->Decommit(0,0x4000)==KErrNone); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Allocate 0x4000\n")); sl@0: test(pC->Allocate(0x4000)==0x0000); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Decommit 0+0x10000\n")); sl@0: test(pC->Decommit(0,0x10000)==KErrNone); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Check Free RAM\n")); sl@0: test(FreeRam()==free); sl@0: sl@0: test.Printf(_L("Commit 0x700000+0x10000\n")); sl@0: test(pC->Commit(0x700000,0x10000)==KErrNone); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Allocate 0x4000\n")); sl@0: test(pC->Allocate(0x4000)==0x0000); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Decommit 0+0x800000\n")); sl@0: test(pC->Decommit(0,0x800000)==KErrNone); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Check Free RAM\n")); sl@0: test(FreeRam()==free); sl@0: sl@0: delete pC; sl@0: sl@0: // Test decommiting from a chunk which has no memory commited sl@0: // in the first megabyte. On the moving memory model, such sl@0: // chunks have a non-zero iHomeRegionOffset value and has been sl@0: // the cause of defects (DEF121857) sl@0: test.Printf(_L("Create new chunk\n")); sl@0: pC=CChunk::New(0x800000); sl@0: test(pC!=NULL); sl@0: test.Printf(_L("Commit 0x100000+0x3000\n")); sl@0: test(pC->Commit(0x100000,0x3000)==KErrNone); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Decommit 0+0x101000\n")); sl@0: test(pC->Decommit(0,0x101000)==KErrNone); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Decommit 0x101000+0x1000\n")); sl@0: test(pC->Decommit(0x101000,0x1000)==KErrNone); sl@0: test(pC->Verify()==KErrNone); sl@0: test.Printf(_L("Decommit 0x100000+0x100000\n")); sl@0: test(pC->Decommit(0x100000,0x100000)==KErrNone); sl@0: test(pC->Verify()==KErrNone); sl@0: delete pC; sl@0: sl@0: test.Next(_L("Testing RThread::Write to disconnected chunks")); sl@0: RTestSession ts; sl@0: TInt r = ts.Connect(); sl@0: test(r==KErrNone); sl@0: test(ts.TestRemoteWrite(64,0,0x3000,0,-1)==KErrNone); sl@0: test(ts.TestRemoteWrite(64,0xffc,0x8000,0,-1)==KErrNone); sl@0: test(ts.TestRemoteWrite(256,0xffc,0x7f80,0,-1)==KErrNone); sl@0: test(ts.TestRemoteWrite(256,0xffc,0x7f80,128,-1)==KErrNone); sl@0: test(ts.TestRemoteWrite(0x10000,0xffc,0x707f80,0,-1)==KErrNone); sl@0: test(ts.TestRemoteWrite(0x10000,0xffc,0x707f80,0x2000,-1)==KErrNone); sl@0: test(ts.TestRemoteWrite(64,-1,0x3000,0,-1)==KErrNone); sl@0: test(ts.TestRemoteWrite(0x10000,-1,0xfff00,0x2000,-1)==KErrNone); sl@0: test(ts.TestRemoteWrite(256,0xffc,0x7f80,16,0)==KErrBadDescriptor); sl@0: test(ts.TestRemoteWrite(256,0xffc,0x7f80,16,0x1000)==KErrBadDescriptor); sl@0: test(ts.TestRemoteWrite(256,0xffc,0x7f80,16,0x7000)==KErrBadDescriptor); sl@0: test(ts.TestRemoteWrite(256,0xffc,0x7f80,16,0x8000)==KErrBadDescriptor); sl@0: test(ts.TestRemoteWrite(0x10000,0xffc,0x707f80,0x2000,0x710000)==KErrBadDescriptor); sl@0: test(ts.TestRemoteWrite(0x10000,-1,0xfff00,0x1000,0x100000)==KErrBadDescriptor); sl@0: ts.Stop(); sl@0: sl@0: test.End(); sl@0: return 0; sl@0: }