Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// 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 <e32test.h>
#include <e32base.h>
#include <e32base_private.h>
#include <e32def.h>
#include <e32def_private.h>
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;i<KMaxAllocations;i++)
{
test.Printf(_L("Try %d\n"),i);
__UHEAP_SETFAIL(RHeap::EDeterministic,i);
pBitMapAllocator=CBitMapAllocator::New(aSize);
if (pBitMapAllocator!=NULL)
break;
__UHEAP_CHECK(0);
}
delete pBitMapAllocator;
__UHEAP_MARKEND;
__UHEAP_RESET;
test.End();
}
LOCAL_C void testNewL(TInt aSize)
//
// Test NewL
//
{
test.Start(_L("NewL"));
__UHEAP_MARK;
CBitMapAllocator* pBitMapAllocator=CBitMapAllocator::NewL(aSize);
test(pBitMapAllocator!=NULL);
test(pBitMapAllocator->Size()==pBitMapAllocator->Avail());
delete pBitMapAllocator;
__UHEAP_CHECK(0);
test.Next(_L("Repetitive NewL"));
for (TInt i=1;i<KMaxAllocations;i++)
{
test.Printf(_L("Try %d\n"),i);
__UHEAP_SETFAIL(RHeap::EDeterministic,i);
TRAPD(r,pBitMapAllocator=CBitMapAllocator::NewL(aSize));
if (r==KErrNone)
break;
__UHEAP_CHECK(0);
}
delete pBitMapAllocator;
__UHEAP_MARKEND;
__UHEAP_RESET;
test.End();
}
LOCAL_C void testAlloc(TInt aSize)
//
// Test Alloc, AllocFromTop, AllocAt, and Free, and AllocFromTopFrom
//
{
CBitMapAllocator* pBitMapAllocator=CBitMapAllocator::New(aSize);
test(pBitMapAllocator!=NULL);
test.Start(_L("Alloc all available"));
TInt available=pBitMapAllocator->Avail();
TInt i=0;
for (;i<available;i++)
{
TInt j=pBitMapAllocator->Alloc();
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;i<available;i++)
pBitMapAllocator->Free(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;i<available;i++)
pBitMapAllocator->Free(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 (i<y)
test(j==KErrNoMemory);
else
{
test(j==y);
test(!pBitMapAllocator->IsFree(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; start<available; start++)
{
for(len=1; len<=available-start; len++)
{
pB->AllocAt(start,len);
test(pB->Avail()==available-len);
for(TInt i=0; i<available; i++)
{
if (i>=start && i<start+len)
{
if(pB->IsFree(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+len<available)
{
test(pB->IsFree(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; init<available; init++)
{
if (init)
pB->AllocAt(0,init);
for(pos=init+1; pos<available; pos++)
{
pB->AllocAt(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 (number<pos-init)
{
firstfree=pB->Alloc(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 (pos<available-1)
{
firstfree=pB->Alloc(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; alignstep<available; alignment++, alignstep<<=1 )
{
TInt numaligned=(available+alignstep-1)/alignstep;
TInt next=0;
TInt r;
do {
r=pB->AllocAligned(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<available; i++)
{
if (i==((i>>alignment)<<alignment) )
{
if (pB->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; alignstep<available; alignment++, alignstep<<=1 )
{
TInt numalignedblocks=available/alignstep;
TInt next=0;
TInt r;
do {
r=pB->AllocAlignedBlock(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; freepos<available; freepos+=alignstep)
{
for (blockpos=0; blockpos<alignstep; blockpos++)
{
c=0;
for(TInt i=blockpos; i<freepos; i+=alignstep)
{
pB->AllocAt(i);
c++;
}
if (pB->Avail()!=available-c)
test(0);
r=pB->AllocAlignedBlock(alignment);
if (available-freepos<alignstep)
{
if (r!=KErrNoMemory)
test(0);
if (pB->Avail()!=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; j<freepos; j+=alignstep)
pB->Free(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;j<k;j++)
{
pB->AllocAt(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;j<i*i + i;j++) //test that the pages are actually allocated
test(!pB->IsFree(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);
}