First public contribution.
1 // Copyright (c) 1995-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\buffer\t_bma.cpp
16 // Test the bitmap allocation abilities of the CBitMapAllocator class.
20 // - Create an instance of CBitMapAllocator class with positive size using New and NewL methods,
21 // verify that object is created and deleted successfully, test the heap allocation failure.
22 // - Verify that the heap has not been corrupted by the test.
23 // - Test Alloc, AllocFromTop, AllocAt, Free, and AllocFromTopFrom methods of
24 // CBitMapAllocator class are as expected.
25 // - Allocate all available memory using Alloc, AllocFromTop, AllocFromTopFrom
26 // and check that available free space is zero.
27 // - Allocate more than available memory using Alloc, AllocFromTop,
28 // AllocFromTopFrom and check the return value is KErrorNoMemory.
29 // - Free the memory and check that available free space is equal to the size.
30 // - Allocate at specified blocks, check the allocation and available free block
32 // - Free the block and check the available space is as expected.
33 // - Check the alignment of blocks after allocation is as expected.
34 // - Perform all of the above tests for CBitMapAllocator size of 1, 4, 32, 33, 68, 96, 64, 65 and 63 bits.
35 // - Allocate some contiguous pages of RAM from the kernel's free page pool with pattern of
36 // increasingly large gaps and test that the pages are allocated as specified.
37 // - Check KErrorNoMemory is returned when extracting a page beyond the available space.
38 // - Perform a test specifically for defect EXT-5AMDKP, Alloc, Free and ExtractRamPages. Test for
40 // - Test whether the heap has been corrupted by any of the tests.
41 // Platforms/Drives/Compatibility:
43 // Assumptions/Requirement/Pre-requisites:
44 // Failures and causes:
45 // Base Port information:
51 #include <e32base_private.h>
53 #include <e32def_private.h>
55 const TInt KMaxAllocations=50;
57 LOCAL_D RTest test(_L("T_BMA"));
59 LOCAL_C void testNew(TInt aSize)
65 test.Start(_L("New"));
67 CBitMapAllocator* pBitMapAllocator=CBitMapAllocator::New(aSize);
68 test(pBitMapAllocator!=NULL);
69 test(pBitMapAllocator->Size()==pBitMapAllocator->Avail());
70 delete pBitMapAllocator;
72 for (TInt i=1;i<KMaxAllocations;i++)
74 test.Printf(_L("Try %d\n"),i);
75 __UHEAP_SETFAIL(RHeap::EDeterministic,i);
76 pBitMapAllocator=CBitMapAllocator::New(aSize);
77 if (pBitMapAllocator!=NULL)
81 delete pBitMapAllocator;
87 LOCAL_C void testNewL(TInt aSize)
93 test.Start(_L("NewL"));
95 CBitMapAllocator* pBitMapAllocator=CBitMapAllocator::NewL(aSize);
96 test(pBitMapAllocator!=NULL);
97 test(pBitMapAllocator->Size()==pBitMapAllocator->Avail());
98 delete pBitMapAllocator;
100 test.Next(_L("Repetitive NewL"));
101 for (TInt i=1;i<KMaxAllocations;i++)
103 test.Printf(_L("Try %d\n"),i);
104 __UHEAP_SETFAIL(RHeap::EDeterministic,i);
105 TRAPD(r,pBitMapAllocator=CBitMapAllocator::NewL(aSize));
110 delete pBitMapAllocator;
116 LOCAL_C void testAlloc(TInt aSize)
118 // Test Alloc, AllocFromTop, AllocAt, and Free, and AllocFromTopFrom
122 CBitMapAllocator* pBitMapAllocator=CBitMapAllocator::New(aSize);
123 test(pBitMapAllocator!=NULL);
124 test.Start(_L("Alloc all available"));
125 TInt available=pBitMapAllocator->Avail();
127 for (;i<available;i++)
129 TInt j=pBitMapAllocator->Alloc();
132 test(pBitMapAllocator->Avail()==0);
134 test.Next(_L("Try to alloc more than available"));
135 i=pBitMapAllocator->Alloc();
136 test(i==KErrNoMemory);
138 test.Next(_L("Free"));
139 for (i=0;i<available;i++)
140 pBitMapAllocator->Free(i);
141 test(pBitMapAllocator->Avail()==pBitMapAllocator->Size());
143 test.Next(_L("AllocFromTop"));
144 for (i=available-1;i>=0;i--)
146 TInt j=pBitMapAllocator->AllocFromTop();
149 test(pBitMapAllocator->Avail()==0);
151 test.Next(_L("Try to AllocFromTop more than available"));
152 i=pBitMapAllocator->AllocFromTop();
153 test(i==KErrNoMemory);
155 test.Next(_L("Free (again)"));
156 for (i=0;i<available;i++)
157 pBitMapAllocator->Free(i);
158 test(pBitMapAllocator->Avail()==pBitMapAllocator->Size());
160 test.Next(_L("AllocAt"));
161 pBitMapAllocator->AllocAt(aSize-1);
162 test(pBitMapAllocator->Avail()==pBitMapAllocator->Size()-1);
164 // test.Next(_L("AllocAt an already allocated cell")); // this test should cause a Panic.
165 // pBitMapAllocator->AllocAt(aSize-1);
166 // test(pBitMapAllocator->Avail()==pBitMapAllocator->Size()-1);
168 test.Next(_L("Free (again)"));
169 pBitMapAllocator->Free(aSize-1);
170 test(pBitMapAllocator->Avail()==pBitMapAllocator->Size());
172 test.Next(_L("AllocFromTopFrom"));
174 for (x=available-1;x>0;x--)
178 TInt j=pBitMapAllocator->AllocFromTopFrom(x);
180 test(!pBitMapAllocator->IsFree(j));
182 test(pBitMapAllocator->Avail()==available-x-1);
184 test.Next(_L("Try to AllocFromTopFrom more than available"));
185 i=pBitMapAllocator->AllocFromTopFrom(x);
186 test(i==KErrNoMemory);
193 if (pBitMapAllocator->Avail()<=available-x-1)
194 pBitMapAllocator->Free(y);
195 TInt j=pBitMapAllocator->AllocFromTopFrom(i);
197 test(j==KErrNoMemory);
201 test(!pBitMapAllocator->IsFree(j));
207 test.Next(_L("Free (again)"));
209 pBitMapAllocator->Free(i);
210 test(pBitMapAllocator->Avail()==pBitMapAllocator->Size());
213 for (x=available-1;x>0;x--)
217 TInt j=pBitMapAllocator->AllocFromTopFrom(x);
220 test(pBitMapAllocator->Avail()==available-x-1);
222 test.Next(_L("Try to AllocFromTopFrom more than available"));
223 i=pBitMapAllocator->AllocFromTopFrom(x);
224 test(i==KErrNoMemory);
226 test.Next(_L("Free (again)"));
228 pBitMapAllocator->Free(i);
229 test(pBitMapAllocator->Avail()==pBitMapAllocator->Size());
232 delete pBitMapAllocator;
235 LOCAL_C void testBlock(TInt aSize)
237 // Test Alloc(TInt, TInt&), AllocAligned, AllocAlignedBlock, AllocAt(TInt, TInt),
238 // IsFree(TInt, TInt), Free(TInt, TInt)
241 CBitMapAllocator* pB=CBitMapAllocator::New(aSize);
243 test.Start(_L("AllocAt block, Free block, IsFree block"));
244 TInt available=pB->Avail();
245 test(available==aSize);
247 for(start=0; start<available; start++)
249 for(len=1; len<=available-start; len++)
251 pB->AllocAt(start,len);
252 test(pB->Avail()==available-len);
253 for(TInt i=0; i<available; i++)
255 if (i>=start && i<start+len)
267 test(pB->IsFree(0,start));
268 test(!pB->IsFree(0,start+1));
269 if (start+len<available)
271 test(pB->IsFree(start+len,available-(start+len)));
272 test(!pB->IsFree(start+len-1,available-(start+len-1)));
275 test(pB->Avail()==available);
276 test(pB->IsFree(start,len));
277 test(pB->IsFree(0,available));
281 test.Start(_L("Alloc consecutive block"));
282 TInt askfor, init, pos, consec;
283 for(askfor=1; askfor<=available; askfor++)
285 test.Printf(_L("Ask for %d\n"),askfor);
286 for(init=0; init<available; init++)
290 for(pos=init+1; pos<available; pos++)
293 TInt firstfree=pB->Alloc(askfor, consec);
296 TInt number=(pos-init>askfor)?askfor:pos-init;
301 firstfree=pB->Alloc(pos-init-number,consec);
302 if(firstfree!=init+number)
304 if(consec!=pos-init-number)
307 test(pB->Avail()==available-pos-1);
308 TInt freeto=available;
311 firstfree=pB->Alloc(askfor,consec);
312 number=(available-pos-1>askfor)?askfor:available-pos-1;
313 if (firstfree!=pos+1)
319 test(pB->Avail()==available-freeto);
320 if (available==freeto)
322 firstfree=pB->Alloc(1,consec);
323 if (firstfree!=KErrNoMemory)
328 pB->Free(init,freeto-init);
332 test(pB->Avail()==available);
336 test.Start(_L("AllocAligned"));
337 TInt alignment, alignstep;
338 for(alignment=0, alignstep=1; alignstep<available; alignment++, alignstep<<=1 )
340 TInt numaligned=(available+alignstep-1)/alignstep;
344 r=pB->AllocAligned(alignment);
351 else if (r!=KErrNoMemory)
354 if (pB->Avail()!=available-numaligned)
356 for(TInt i=0; i<available; i++)
358 if (i==((i>>alignment)<<alignment) )
370 test(pB->Avail()==available);
373 test.Start(_L("AllocAlignedBlock"));
374 for(alignment=0, alignstep=1; alignstep<available; alignment++, alignstep<<=1 )
376 TInt numalignedblocks=available/alignstep;
380 r=pB->AllocAlignedBlock(alignment);
387 else if (r!=KErrNoMemory)
390 if (pB->Avail()!=available-numalignedblocks*alignstep)
394 if ( !pB->IsFree(numalignedblocks*alignstep,pB->Avail()) )
397 if (r!=numalignedblocks*alignstep)
401 pB->Free(0,numalignedblocks*alignstep);
402 if (pB->Avail()!=available)
404 TInt freepos, blockpos, c;
405 for (freepos=0; freepos<available; freepos+=alignstep)
407 for (blockpos=0; blockpos<alignstep; blockpos++)
410 for(TInt i=blockpos; i<freepos; i+=alignstep)
415 if (pB->Avail()!=available-c)
417 r=pB->AllocAlignedBlock(alignment);
418 if (available-freepos<alignstep)
422 if (pB->Avail()!=available-c)
429 if (pB->Avail()!=available-c-alignstep)
431 pB->Free(freepos,alignstep);
432 if (pB->Avail()!=available-c)
435 for(TInt j=blockpos; j<freepos; j+=alignstep)
437 if (pB->Avail()!=available)
446 LOCAL_C void testContiguousAllocation(TInt aSize)
447 {//test RemoveRamPages()
448 //set up bitmap with pattern of increasingly large gaps -
449 //page 1 - in use,page 2 - free
450 //pages 3,4 - in use,pages 5,6 - free
451 //pages 7,8,9 - in use,pages 10,11,12 - free ...etc
452 test.Start(_L("Create swiss cheese effect..."));
454 CBitMapAllocator* pB=CBitMapAllocator::New(aSize);
457 TInt available=pB->Avail();
458 test(available==aSize);
468 test(!pB->IsFree(i+j));
478 ret=pB->ExtractRamPages(i,pageNo); //look for a gap of size i pages and allocate it
479 test(pageNo==i*i); //test the right page no is returned
480 test.Printf(_L("OK -pageNo is :%d\r\n"),pageNo);
481 for(j=i*i;j<i*i + i;j++) //test that the pages are actually allocated
482 test(!pB->IsFree(j));
485 ret=pB->ExtractRamPages(45,pageNo);//there's not a big enough space in the bitmap for this to succeed
486 test(ret==KErrNoMemory);
491 LOCAL_C void testAll(TInt aSize)
493 // Test all BMA functions using a BMA of size aSize
498 b.Format(_L("BitMapAllocator size = %d"),aSize);
509 GLDEF_C TInt E32Main()
511 // Test bitmap allocator
517 test.Start(_L("1 bit"));
520 test.Next(_L("4 bit"));
523 test.Next(_L("32 bit"));
526 test.Next(_L("33 bit"));
529 test.Next(_L("68 bit"));
532 test.Next(_L("96 bit"));
535 test.Next(_L("64 bit"));
538 test.Next(_L("65 bit"));
541 test.Next(_L("63 bit"));
544 testContiguousAllocation(2048);
546 test.Next(_L("test defect EXT-5AMDKP"));
548 CBitMapAllocator* pB = CBitMapAllocator::New(64);
557 pB->ExtractRamPages(3, page);
559 pB->ExtractRamPages(4, page);
561 pB->ExtractRamPages(1, page);
563 pB->ExtractRamPages(5, page);
565 pB->ExtractRamPages(2, page);