diff -r 000000000000 -r a41df078684a kerneltest/e32test/buffer/t_bma.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/buffer/t_bma.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,573 @@ +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\buffer\t_bma.cpp +// Overview: +// Test the bitmap allocation abilities of the CBitMapAllocator class. +// API Information: +// CBitMapAllocator. +// Details: +// - Create an instance of CBitMapAllocator class with positive size using New and NewL methods, +// verify that object is created and deleted successfully, test the heap allocation failure. +// - Verify that the heap has not been corrupted by the test. +// - Test Alloc, AllocFromTop, AllocAt, Free, and AllocFromTopFrom methods of +// CBitMapAllocator class are as expected. +// - Allocate all available memory using Alloc, AllocFromTop, AllocFromTopFrom +// and check that available free space is zero. +// - Allocate more than available memory using Alloc, AllocFromTop, +// AllocFromTopFrom and check the return value is KErrorNoMemory. +// - Free the memory and check that available free space is equal to the size. +// - Allocate at specified blocks, check the allocation and available free block +// is as expected. +// - Free the block and check the available space is as expected. +// - Check the alignment of blocks after allocation is as expected. +// - Perform all of the above tests for CBitMapAllocator size of 1, 4, 32, 33, 68, 96, 64, 65 and 63 bits. +// - Allocate some contiguous pages of RAM from the kernel's free page pool with pattern of +// increasingly large gaps and test that the pages are allocated as specified. +// - Check KErrorNoMemory is returned when extracting a page beyond the available space. +// - Perform a test specifically for defect EXT-5AMDKP, Alloc, Free and ExtractRamPages. Test for +// expected results. +// - Test whether the heap has been corrupted by any of the tests. +// Platforms/Drives/Compatibility: +// All +// Assumptions/Requirement/Pre-requisites: +// Failures and causes: +// Base Port information: +// +// + +#include +#include +#include +#include +#include + +const TInt KMaxAllocations=50; + +LOCAL_D RTest test(_L("T_BMA")); + +LOCAL_C void testNew(TInt aSize) +// +// Test New +// + { + + test.Start(_L("New")); + __UHEAP_MARK; + CBitMapAllocator* pBitMapAllocator=CBitMapAllocator::New(aSize); + test(pBitMapAllocator!=NULL); + test(pBitMapAllocator->Size()==pBitMapAllocator->Avail()); + delete pBitMapAllocator; + __UHEAP_CHECK(0); + for (TInt i=1;iSize()==pBitMapAllocator->Avail()); + delete pBitMapAllocator; + __UHEAP_CHECK(0); + test.Next(_L("Repetitive NewL")); + for (TInt i=1;iAvail(); + TInt i=0; + for (;iAlloc(); + test(j==i); + } + test(pBitMapAllocator->Avail()==0); +// + test.Next(_L("Try to alloc more than available")); + i=pBitMapAllocator->Alloc(); + test(i==KErrNoMemory); +// + test.Next(_L("Free")); + for (i=0;iFree(i); + test(pBitMapAllocator->Avail()==pBitMapAllocator->Size()); +// + test.Next(_L("AllocFromTop")); + for (i=available-1;i>=0;i--) + { + TInt j=pBitMapAllocator->AllocFromTop(); + test(j==i); + } + test(pBitMapAllocator->Avail()==0); +// + test.Next(_L("Try to AllocFromTop more than available")); + i=pBitMapAllocator->AllocFromTop(); + test(i==KErrNoMemory); +// + test.Next(_L("Free (again)")); + for (i=0;iFree(i); + test(pBitMapAllocator->Avail()==pBitMapAllocator->Size()); +// + test.Next(_L("AllocAt")); + pBitMapAllocator->AllocAt(aSize-1); + test(pBitMapAllocator->Avail()==pBitMapAllocator->Size()-1); +// +// test.Next(_L("AllocAt an already allocated cell")); // this test should cause a Panic. +// pBitMapAllocator->AllocAt(aSize-1); +// test(pBitMapAllocator->Avail()==pBitMapAllocator->Size()-1); +// + test.Next(_L("Free (again)")); + pBitMapAllocator->Free(aSize-1); + test(pBitMapAllocator->Avail()==pBitMapAllocator->Size()); +// + test.Next(_L("AllocFromTopFrom")); + TInt x; + for (x=available-1;x>0;x--) + { + for (i=x;i>=0;i--) + { + TInt j=pBitMapAllocator->AllocFromTopFrom(x); + test(j==i); + test(!pBitMapAllocator->IsFree(j)); + } + test(pBitMapAllocator->Avail()==available-x-1); + + test.Next(_L("Try to AllocFromTopFrom more than available")); + i=pBitMapAllocator->AllocFromTopFrom(x); + test(i==KErrNoMemory); +// + TInt y; + for (y=0;y<=x;y++) + { + for (i=0;i<=x;i++) + { + if (pBitMapAllocator->Avail()<=available-x-1) + pBitMapAllocator->Free(y); + TInt j=pBitMapAllocator->AllocFromTopFrom(i); + if (iIsFree(j)); + } + } + } + +// + test.Next(_L("Free (again)")); + for (i=0;i<=x;i++) + pBitMapAllocator->Free(i); + test(pBitMapAllocator->Avail()==pBitMapAllocator->Size()); + } +// + for (x=available-1;x>0;x--) + { + for (i=x;i>=0;i--) + { + TInt j=pBitMapAllocator->AllocFromTopFrom(x); + test(j==i); + } + test(pBitMapAllocator->Avail()==available-x-1); + + test.Next(_L("Try to AllocFromTopFrom more than available")); + i=pBitMapAllocator->AllocFromTopFrom(x); + test(i==KErrNoMemory); + // + test.Next(_L("Free (again)")); + for (i=0;i<=x;i++) + pBitMapAllocator->Free(i); + test(pBitMapAllocator->Avail()==pBitMapAllocator->Size()); + } + test.End(); + delete pBitMapAllocator; + } + +LOCAL_C void testBlock(TInt aSize) +// +// Test Alloc(TInt, TInt&), AllocAligned, AllocAlignedBlock, AllocAt(TInt, TInt), +// IsFree(TInt, TInt), Free(TInt, TInt) +// + { + CBitMapAllocator* pB=CBitMapAllocator::New(aSize); + test(pB!=NULL); + test.Start(_L("AllocAt block, Free block, IsFree block")); + TInt available=pB->Avail(); + test(available==aSize); + TInt start, len; + for(start=0; startAllocAt(start,len); + test(pB->Avail()==available-len); + for(TInt i=0; i=start && iIsFree(i)) + test(0); + } + else + { + if(!pB->IsFree(i)) + test(0); + } + } + if (start) + test(pB->IsFree(0,start)); + test(!pB->IsFree(0,start+1)); + if (start+lenIsFree(start+len,available-(start+len))); + test(!pB->IsFree(start+len-1,available-(start+len-1))); + } + pB->Free(start,len); + test(pB->Avail()==available); + test(pB->IsFree(start,len)); + test(pB->IsFree(0,available)); + } + } + test.End(); + test.Start(_L("Alloc consecutive block")); + TInt askfor, init, pos, consec; + for(askfor=1; askfor<=available; askfor++) + { + test.Printf(_L("Ask for %d\n"),askfor); + for(init=0; initAllocAt(0,init); + for(pos=init+1; posAllocAt(pos); + TInt firstfree=pB->Alloc(askfor, consec); + if (firstfree!=init) + test(0); + TInt number=(pos-init>askfor)?askfor:pos-init; + if (consec!=number) + test(0); + if (numberAlloc(pos-init-number,consec); + if(firstfree!=init+number) + test(0); + if(consec!=pos-init-number) + test(0); + } + test(pB->Avail()==available-pos-1); + TInt freeto=available; + if (posAlloc(askfor,consec); + number=(available-pos-1>askfor)?askfor:available-pos-1; + if (firstfree!=pos+1) + test(0); + if (consec!=number) + test(0); + freeto=pos+1+number; + } + test(pB->Avail()==available-freeto); + if (available==freeto) + { + firstfree=pB->Alloc(1,consec); + if (firstfree!=KErrNoMemory) + test(0); + if (consec!=0) + test(0); + } + pB->Free(init,freeto-init); + } + if (init) + pB->Free(0,init); + test(pB->Avail()==available); + } + } + test.End(); + test.Start(_L("AllocAligned")); + TInt alignment, alignstep; + for(alignment=0, alignstep=1; alignstepAllocAligned(alignment); + if (r>=0) + { + if (r!=next) + test(0); + next+=alignstep; + } + else if (r!=KErrNoMemory) + test(0); + } while(r>=0); + if (pB->Avail()!=available-numaligned) + test(0); + for(TInt i=0; i>alignment)<IsFree(i)) + test(0); + pB->Free(i); + } + else + { + if (!pB->IsFree(i)) + test(0); + } + } + test(pB->Avail()==available); + } + test.End(); + test.Start(_L("AllocAlignedBlock")); + for(alignment=0, alignstep=1; alignstepAllocAlignedBlock(alignment); + if (r>=0) + { + if (r!=next) + test(0); + next+=alignstep; + } + else if (r!=KErrNoMemory) + test(0); + } while(r>=0); + if (pB->Avail()!=available-numalignedblocks*alignstep) + test(0); + if (pB->Avail()!=0) + { + if ( !pB->IsFree(numalignedblocks*alignstep,pB->Avail()) ) + test(0); + r=pB->Alloc(); + if (r!=numalignedblocks*alignstep) + test(0); + pB->Free(r); + } + pB->Free(0,numalignedblocks*alignstep); + if (pB->Avail()!=available) + test(0); + TInt freepos, blockpos, c; + for (freepos=0; freeposAllocAt(i); + c++; + } + if (pB->Avail()!=available-c) + test(0); + r=pB->AllocAlignedBlock(alignment); + if (available-freeposAvail()!=available-c) + test(0); + } + else + { + if (r!=freepos) + test(0); + if (pB->Avail()!=available-c-alignstep) + test(0); + pB->Free(freepos,alignstep); + if (pB->Avail()!=available-c) + test(0); + } + for(TInt j=blockpos; jFree(j); + if (pB->Avail()!=available) + test(0); + } + } + } + delete pB; + test.End(); + } + +LOCAL_C void testContiguousAllocation(TInt aSize) + {//test RemoveRamPages() + //set up bitmap with pattern of increasingly large gaps - + //page 1 - in use,page 2 - free + //pages 3,4 - in use,pages 5,6 - free + //pages 7,8,9 - in use,pages 10,11,12 - free ...etc + test.Start(_L("Create swiss cheese effect...")); + + CBitMapAllocator* pB=CBitMapAllocator::New(aSize); + test(pB!=NULL); + + TInt available=pB->Avail(); + test(available==aSize); + + TInt i=0; + TInt j=0; + TInt k=1; + while(k<46) + { + for(j=0;jAllocAt(i+j); + test(!pB->IsFree(i+j)); + } + i+=2*k; + k++; + } + + TInt ret=KErrNone; + TInt pageNo=0; + for(i=1;i<45;i++) + { + ret=pB->ExtractRamPages(i,pageNo); //look for a gap of size i pages and allocate it + test(pageNo==i*i); //test the right page no is returned + test.Printf(_L("OK -pageNo is :%d\r\n"),pageNo); + for(j=i*i;jIsFree(j)); + } + + ret=pB->ExtractRamPages(45,pageNo);//there's not a big enough space in the bitmap for this to succeed + test(ret==KErrNoMemory); + delete pB; + test.End(); + } + +LOCAL_C void testAll(TInt aSize) +// +// Test all BMA functions using a BMA of size aSize +// + { + + TBuf<0x40> b; + b.Format(_L("BitMapAllocator size = %d"),aSize); + test.Start(b); +// + testNew(aSize); + testNewL(aSize); + testAlloc(aSize); + testBlock(aSize); +// + test.End(); + } + +GLDEF_C TInt E32Main() +// +// Test bitmap allocator +// + { + test.Title(); + __UHEAP_MARK; +// + test.Start(_L("1 bit")); + testAll(1); + + test.Next(_L("4 bit")); + testAll(4); +// + test.Next(_L("32 bit")); + testAll(32); +// + test.Next(_L("33 bit")); + testAll(33); +// + test.Next(_L("68 bit")); + testAll(68); +// + test.Next(_L("96 bit")); + testAll(96); +// + test.Next(_L("64 bit")); + testAll(64); +// + test.Next(_L("65 bit")); + testAll(65); +// + test.Next(_L("63 bit")); + testAll(63); + + testContiguousAllocation(2048); + + test.Next(_L("test defect EXT-5AMDKP")); + + CBitMapAllocator* pB = CBitMapAllocator::New(64); + test(pB != NULL); + pB->AllocAt(0, 32); + pB->Free(2, 2); + pB->Free(5, 2); + pB->Free(8, 2); + pB->Free(12, 3); + pB->Free(30, 2); + TInt page = -1; + pB->ExtractRamPages(3, page); + test(page == 12); + pB->ExtractRamPages(4, page); + test(page == 30); + pB->ExtractRamPages(1, page); + test(page == 2); + pB->ExtractRamPages(5, page); + test(page == 34); + pB->ExtractRamPages(2, page); + test(page == 5); + delete pB; + + __UHEAP_MARKEND; + test.End(); + return(KErrNone); + } +