1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/buffer/t_bma.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,573 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\buffer\t_bma.cpp
1.18 +// Overview:
1.19 +// Test the bitmap allocation abilities of the CBitMapAllocator class.
1.20 +// API Information:
1.21 +// CBitMapAllocator.
1.22 +// Details:
1.23 +// - Create an instance of CBitMapAllocator class with positive size using New and NewL methods,
1.24 +// verify that object is created and deleted successfully, test the heap allocation failure.
1.25 +// - Verify that the heap has not been corrupted by the test.
1.26 +// - Test Alloc, AllocFromTop, AllocAt, Free, and AllocFromTopFrom methods of
1.27 +// CBitMapAllocator class are as expected.
1.28 +// - Allocate all available memory using Alloc, AllocFromTop, AllocFromTopFrom
1.29 +// and check that available free space is zero.
1.30 +// - Allocate more than available memory using Alloc, AllocFromTop,
1.31 +// AllocFromTopFrom and check the return value is KErrorNoMemory.
1.32 +// - Free the memory and check that available free space is equal to the size.
1.33 +// - Allocate at specified blocks, check the allocation and available free block
1.34 +// is as expected.
1.35 +// - Free the block and check the available space is as expected.
1.36 +// - Check the alignment of blocks after allocation is as expected.
1.37 +// - Perform all of the above tests for CBitMapAllocator size of 1, 4, 32, 33, 68, 96, 64, 65 and 63 bits.
1.38 +// - Allocate some contiguous pages of RAM from the kernel's free page pool with pattern of
1.39 +// increasingly large gaps and test that the pages are allocated as specified.
1.40 +// - Check KErrorNoMemory is returned when extracting a page beyond the available space.
1.41 +// - Perform a test specifically for defect EXT-5AMDKP, Alloc, Free and ExtractRamPages. Test for
1.42 +// expected results.
1.43 +// - Test whether the heap has been corrupted by any of the tests.
1.44 +// Platforms/Drives/Compatibility:
1.45 +// All
1.46 +// Assumptions/Requirement/Pre-requisites:
1.47 +// Failures and causes:
1.48 +// Base Port information:
1.49 +//
1.50 +//
1.51 +
1.52 +#include <e32test.h>
1.53 +#include <e32base.h>
1.54 +#include <e32base_private.h>
1.55 +#include <e32def.h>
1.56 +#include <e32def_private.h>
1.57 +
1.58 +const TInt KMaxAllocations=50;
1.59 +
1.60 +LOCAL_D RTest test(_L("T_BMA"));
1.61 +
1.62 +LOCAL_C void testNew(TInt aSize)
1.63 +//
1.64 +// Test New
1.65 +//
1.66 + {
1.67 +
1.68 + test.Start(_L("New"));
1.69 + __UHEAP_MARK;
1.70 + CBitMapAllocator* pBitMapAllocator=CBitMapAllocator::New(aSize);
1.71 + test(pBitMapAllocator!=NULL);
1.72 + test(pBitMapAllocator->Size()==pBitMapAllocator->Avail());
1.73 + delete pBitMapAllocator;
1.74 + __UHEAP_CHECK(0);
1.75 + for (TInt i=1;i<KMaxAllocations;i++)
1.76 + {
1.77 + test.Printf(_L("Try %d\n"),i);
1.78 + __UHEAP_SETFAIL(RHeap::EDeterministic,i);
1.79 + pBitMapAllocator=CBitMapAllocator::New(aSize);
1.80 + if (pBitMapAllocator!=NULL)
1.81 + break;
1.82 + __UHEAP_CHECK(0);
1.83 + }
1.84 + delete pBitMapAllocator;
1.85 + __UHEAP_MARKEND;
1.86 + __UHEAP_RESET;
1.87 + test.End();
1.88 + }
1.89 +
1.90 +LOCAL_C void testNewL(TInt aSize)
1.91 +//
1.92 +// Test NewL
1.93 +//
1.94 + {
1.95 +
1.96 + test.Start(_L("NewL"));
1.97 + __UHEAP_MARK;
1.98 + CBitMapAllocator* pBitMapAllocator=CBitMapAllocator::NewL(aSize);
1.99 + test(pBitMapAllocator!=NULL);
1.100 + test(pBitMapAllocator->Size()==pBitMapAllocator->Avail());
1.101 + delete pBitMapAllocator;
1.102 + __UHEAP_CHECK(0);
1.103 + test.Next(_L("Repetitive NewL"));
1.104 + for (TInt i=1;i<KMaxAllocations;i++)
1.105 + {
1.106 + test.Printf(_L("Try %d\n"),i);
1.107 + __UHEAP_SETFAIL(RHeap::EDeterministic,i);
1.108 + TRAPD(r,pBitMapAllocator=CBitMapAllocator::NewL(aSize));
1.109 + if (r==KErrNone)
1.110 + break;
1.111 + __UHEAP_CHECK(0);
1.112 + }
1.113 + delete pBitMapAllocator;
1.114 + __UHEAP_MARKEND;
1.115 + __UHEAP_RESET;
1.116 + test.End();
1.117 + }
1.118 +
1.119 +LOCAL_C void testAlloc(TInt aSize)
1.120 +//
1.121 +// Test Alloc, AllocFromTop, AllocAt, and Free, and AllocFromTopFrom
1.122 +//
1.123 + {
1.124 +
1.125 + CBitMapAllocator* pBitMapAllocator=CBitMapAllocator::New(aSize);
1.126 + test(pBitMapAllocator!=NULL);
1.127 + test.Start(_L("Alloc all available"));
1.128 + TInt available=pBitMapAllocator->Avail();
1.129 + TInt i=0;
1.130 + for (;i<available;i++)
1.131 + {
1.132 + TInt j=pBitMapAllocator->Alloc();
1.133 + test(j==i);
1.134 + }
1.135 + test(pBitMapAllocator->Avail()==0);
1.136 +//
1.137 + test.Next(_L("Try to alloc more than available"));
1.138 + i=pBitMapAllocator->Alloc();
1.139 + test(i==KErrNoMemory);
1.140 +//
1.141 + test.Next(_L("Free"));
1.142 + for (i=0;i<available;i++)
1.143 + pBitMapAllocator->Free(i);
1.144 + test(pBitMapAllocator->Avail()==pBitMapAllocator->Size());
1.145 +//
1.146 + test.Next(_L("AllocFromTop"));
1.147 + for (i=available-1;i>=0;i--)
1.148 + {
1.149 + TInt j=pBitMapAllocator->AllocFromTop();
1.150 + test(j==i);
1.151 + }
1.152 + test(pBitMapAllocator->Avail()==0);
1.153 +//
1.154 + test.Next(_L("Try to AllocFromTop more than available"));
1.155 + i=pBitMapAllocator->AllocFromTop();
1.156 + test(i==KErrNoMemory);
1.157 +//
1.158 + test.Next(_L("Free (again)"));
1.159 + for (i=0;i<available;i++)
1.160 + pBitMapAllocator->Free(i);
1.161 + test(pBitMapAllocator->Avail()==pBitMapAllocator->Size());
1.162 +//
1.163 + test.Next(_L("AllocAt"));
1.164 + pBitMapAllocator->AllocAt(aSize-1);
1.165 + test(pBitMapAllocator->Avail()==pBitMapAllocator->Size()-1);
1.166 +//
1.167 +// test.Next(_L("AllocAt an already allocated cell")); // this test should cause a Panic.
1.168 +// pBitMapAllocator->AllocAt(aSize-1);
1.169 +// test(pBitMapAllocator->Avail()==pBitMapAllocator->Size()-1);
1.170 +//
1.171 + test.Next(_L("Free (again)"));
1.172 + pBitMapAllocator->Free(aSize-1);
1.173 + test(pBitMapAllocator->Avail()==pBitMapAllocator->Size());
1.174 +//
1.175 + test.Next(_L("AllocFromTopFrom"));
1.176 + TInt x;
1.177 + for (x=available-1;x>0;x--)
1.178 + {
1.179 + for (i=x;i>=0;i--)
1.180 + {
1.181 + TInt j=pBitMapAllocator->AllocFromTopFrom(x);
1.182 + test(j==i);
1.183 + test(!pBitMapAllocator->IsFree(j));
1.184 + }
1.185 + test(pBitMapAllocator->Avail()==available-x-1);
1.186 +
1.187 + test.Next(_L("Try to AllocFromTopFrom more than available"));
1.188 + i=pBitMapAllocator->AllocFromTopFrom(x);
1.189 + test(i==KErrNoMemory);
1.190 +//
1.191 + TInt y;
1.192 + for (y=0;y<=x;y++)
1.193 + {
1.194 + for (i=0;i<=x;i++)
1.195 + {
1.196 + if (pBitMapAllocator->Avail()<=available-x-1)
1.197 + pBitMapAllocator->Free(y);
1.198 + TInt j=pBitMapAllocator->AllocFromTopFrom(i);
1.199 + if (i<y)
1.200 + test(j==KErrNoMemory);
1.201 + else
1.202 + {
1.203 + test(j==y);
1.204 + test(!pBitMapAllocator->IsFree(j));
1.205 + }
1.206 + }
1.207 + }
1.208 +
1.209 +//
1.210 + test.Next(_L("Free (again)"));
1.211 + for (i=0;i<=x;i++)
1.212 + pBitMapAllocator->Free(i);
1.213 + test(pBitMapAllocator->Avail()==pBitMapAllocator->Size());
1.214 + }
1.215 +//
1.216 + for (x=available-1;x>0;x--)
1.217 + {
1.218 + for (i=x;i>=0;i--)
1.219 + {
1.220 + TInt j=pBitMapAllocator->AllocFromTopFrom(x);
1.221 + test(j==i);
1.222 + }
1.223 + test(pBitMapAllocator->Avail()==available-x-1);
1.224 +
1.225 + test.Next(_L("Try to AllocFromTopFrom more than available"));
1.226 + i=pBitMapAllocator->AllocFromTopFrom(x);
1.227 + test(i==KErrNoMemory);
1.228 + //
1.229 + test.Next(_L("Free (again)"));
1.230 + for (i=0;i<=x;i++)
1.231 + pBitMapAllocator->Free(i);
1.232 + test(pBitMapAllocator->Avail()==pBitMapAllocator->Size());
1.233 + }
1.234 + test.End();
1.235 + delete pBitMapAllocator;
1.236 + }
1.237 +
1.238 +LOCAL_C void testBlock(TInt aSize)
1.239 +//
1.240 +// Test Alloc(TInt, TInt&), AllocAligned, AllocAlignedBlock, AllocAt(TInt, TInt),
1.241 +// IsFree(TInt, TInt), Free(TInt, TInt)
1.242 +//
1.243 + {
1.244 + CBitMapAllocator* pB=CBitMapAllocator::New(aSize);
1.245 + test(pB!=NULL);
1.246 + test.Start(_L("AllocAt block, Free block, IsFree block"));
1.247 + TInt available=pB->Avail();
1.248 + test(available==aSize);
1.249 + TInt start, len;
1.250 + for(start=0; start<available; start++)
1.251 + {
1.252 + for(len=1; len<=available-start; len++)
1.253 + {
1.254 + pB->AllocAt(start,len);
1.255 + test(pB->Avail()==available-len);
1.256 + for(TInt i=0; i<available; i++)
1.257 + {
1.258 + if (i>=start && i<start+len)
1.259 + {
1.260 + if(pB->IsFree(i))
1.261 + test(0);
1.262 + }
1.263 + else
1.264 + {
1.265 + if(!pB->IsFree(i))
1.266 + test(0);
1.267 + }
1.268 + }
1.269 + if (start)
1.270 + test(pB->IsFree(0,start));
1.271 + test(!pB->IsFree(0,start+1));
1.272 + if (start+len<available)
1.273 + {
1.274 + test(pB->IsFree(start+len,available-(start+len)));
1.275 + test(!pB->IsFree(start+len-1,available-(start+len-1)));
1.276 + }
1.277 + pB->Free(start,len);
1.278 + test(pB->Avail()==available);
1.279 + test(pB->IsFree(start,len));
1.280 + test(pB->IsFree(0,available));
1.281 + }
1.282 + }
1.283 + test.End();
1.284 + test.Start(_L("Alloc consecutive block"));
1.285 + TInt askfor, init, pos, consec;
1.286 + for(askfor=1; askfor<=available; askfor++)
1.287 + {
1.288 + test.Printf(_L("Ask for %d\n"),askfor);
1.289 + for(init=0; init<available; init++)
1.290 + {
1.291 + if (init)
1.292 + pB->AllocAt(0,init);
1.293 + for(pos=init+1; pos<available; pos++)
1.294 + {
1.295 + pB->AllocAt(pos);
1.296 + TInt firstfree=pB->Alloc(askfor, consec);
1.297 + if (firstfree!=init)
1.298 + test(0);
1.299 + TInt number=(pos-init>askfor)?askfor:pos-init;
1.300 + if (consec!=number)
1.301 + test(0);
1.302 + if (number<pos-init)
1.303 + {
1.304 + firstfree=pB->Alloc(pos-init-number,consec);
1.305 + if(firstfree!=init+number)
1.306 + test(0);
1.307 + if(consec!=pos-init-number)
1.308 + test(0);
1.309 + }
1.310 + test(pB->Avail()==available-pos-1);
1.311 + TInt freeto=available;
1.312 + if (pos<available-1)
1.313 + {
1.314 + firstfree=pB->Alloc(askfor,consec);
1.315 + number=(available-pos-1>askfor)?askfor:available-pos-1;
1.316 + if (firstfree!=pos+1)
1.317 + test(0);
1.318 + if (consec!=number)
1.319 + test(0);
1.320 + freeto=pos+1+number;
1.321 + }
1.322 + test(pB->Avail()==available-freeto);
1.323 + if (available==freeto)
1.324 + {
1.325 + firstfree=pB->Alloc(1,consec);
1.326 + if (firstfree!=KErrNoMemory)
1.327 + test(0);
1.328 + if (consec!=0)
1.329 + test(0);
1.330 + }
1.331 + pB->Free(init,freeto-init);
1.332 + }
1.333 + if (init)
1.334 + pB->Free(0,init);
1.335 + test(pB->Avail()==available);
1.336 + }
1.337 + }
1.338 + test.End();
1.339 + test.Start(_L("AllocAligned"));
1.340 + TInt alignment, alignstep;
1.341 + for(alignment=0, alignstep=1; alignstep<available; alignment++, alignstep<<=1 )
1.342 + {
1.343 + TInt numaligned=(available+alignstep-1)/alignstep;
1.344 + TInt next=0;
1.345 + TInt r;
1.346 + do {
1.347 + r=pB->AllocAligned(alignment);
1.348 + if (r>=0)
1.349 + {
1.350 + if (r!=next)
1.351 + test(0);
1.352 + next+=alignstep;
1.353 + }
1.354 + else if (r!=KErrNoMemory)
1.355 + test(0);
1.356 + } while(r>=0);
1.357 + if (pB->Avail()!=available-numaligned)
1.358 + test(0);
1.359 + for(TInt i=0; i<available; i++)
1.360 + {
1.361 + if (i==((i>>alignment)<<alignment) )
1.362 + {
1.363 + if (pB->IsFree(i))
1.364 + test(0);
1.365 + pB->Free(i);
1.366 + }
1.367 + else
1.368 + {
1.369 + if (!pB->IsFree(i))
1.370 + test(0);
1.371 + }
1.372 + }
1.373 + test(pB->Avail()==available);
1.374 + }
1.375 + test.End();
1.376 + test.Start(_L("AllocAlignedBlock"));
1.377 + for(alignment=0, alignstep=1; alignstep<available; alignment++, alignstep<<=1 )
1.378 + {
1.379 + TInt numalignedblocks=available/alignstep;
1.380 + TInt next=0;
1.381 + TInt r;
1.382 + do {
1.383 + r=pB->AllocAlignedBlock(alignment);
1.384 + if (r>=0)
1.385 + {
1.386 + if (r!=next)
1.387 + test(0);
1.388 + next+=alignstep;
1.389 + }
1.390 + else if (r!=KErrNoMemory)
1.391 + test(0);
1.392 + } while(r>=0);
1.393 + if (pB->Avail()!=available-numalignedblocks*alignstep)
1.394 + test(0);
1.395 + if (pB->Avail()!=0)
1.396 + {
1.397 + if ( !pB->IsFree(numalignedblocks*alignstep,pB->Avail()) )
1.398 + test(0);
1.399 + r=pB->Alloc();
1.400 + if (r!=numalignedblocks*alignstep)
1.401 + test(0);
1.402 + pB->Free(r);
1.403 + }
1.404 + pB->Free(0,numalignedblocks*alignstep);
1.405 + if (pB->Avail()!=available)
1.406 + test(0);
1.407 + TInt freepos, blockpos, c;
1.408 + for (freepos=0; freepos<available; freepos+=alignstep)
1.409 + {
1.410 + for (blockpos=0; blockpos<alignstep; blockpos++)
1.411 + {
1.412 + c=0;
1.413 + for(TInt i=blockpos; i<freepos; i+=alignstep)
1.414 + {
1.415 + pB->AllocAt(i);
1.416 + c++;
1.417 + }
1.418 + if (pB->Avail()!=available-c)
1.419 + test(0);
1.420 + r=pB->AllocAlignedBlock(alignment);
1.421 + if (available-freepos<alignstep)
1.422 + {
1.423 + if (r!=KErrNoMemory)
1.424 + test(0);
1.425 + if (pB->Avail()!=available-c)
1.426 + test(0);
1.427 + }
1.428 + else
1.429 + {
1.430 + if (r!=freepos)
1.431 + test(0);
1.432 + if (pB->Avail()!=available-c-alignstep)
1.433 + test(0);
1.434 + pB->Free(freepos,alignstep);
1.435 + if (pB->Avail()!=available-c)
1.436 + test(0);
1.437 + }
1.438 + for(TInt j=blockpos; j<freepos; j+=alignstep)
1.439 + pB->Free(j);
1.440 + if (pB->Avail()!=available)
1.441 + test(0);
1.442 + }
1.443 + }
1.444 + }
1.445 + delete pB;
1.446 + test.End();
1.447 + }
1.448 +
1.449 +LOCAL_C void testContiguousAllocation(TInt aSize)
1.450 + {//test RemoveRamPages()
1.451 + //set up bitmap with pattern of increasingly large gaps -
1.452 + //page 1 - in use,page 2 - free
1.453 + //pages 3,4 - in use,pages 5,6 - free
1.454 + //pages 7,8,9 - in use,pages 10,11,12 - free ...etc
1.455 + test.Start(_L("Create swiss cheese effect..."));
1.456 +
1.457 + CBitMapAllocator* pB=CBitMapAllocator::New(aSize);
1.458 + test(pB!=NULL);
1.459 +
1.460 + TInt available=pB->Avail();
1.461 + test(available==aSize);
1.462 +
1.463 + TInt i=0;
1.464 + TInt j=0;
1.465 + TInt k=1;
1.466 + while(k<46)
1.467 + {
1.468 + for(j=0;j<k;j++)
1.469 + {
1.470 + pB->AllocAt(i+j);
1.471 + test(!pB->IsFree(i+j));
1.472 + }
1.473 + i+=2*k;
1.474 + k++;
1.475 + }
1.476 +
1.477 + TInt ret=KErrNone;
1.478 + TInt pageNo=0;
1.479 + for(i=1;i<45;i++)
1.480 + {
1.481 + ret=pB->ExtractRamPages(i,pageNo); //look for a gap of size i pages and allocate it
1.482 + test(pageNo==i*i); //test the right page no is returned
1.483 + test.Printf(_L("OK -pageNo is :%d\r\n"),pageNo);
1.484 + for(j=i*i;j<i*i + i;j++) //test that the pages are actually allocated
1.485 + test(!pB->IsFree(j));
1.486 + }
1.487 +
1.488 + ret=pB->ExtractRamPages(45,pageNo);//there's not a big enough space in the bitmap for this to succeed
1.489 + test(ret==KErrNoMemory);
1.490 + delete pB;
1.491 + test.End();
1.492 + }
1.493 +
1.494 +LOCAL_C void testAll(TInt aSize)
1.495 +//
1.496 +// Test all BMA functions using a BMA of size aSize
1.497 +//
1.498 + {
1.499 +
1.500 + TBuf<0x40> b;
1.501 + b.Format(_L("BitMapAllocator size = %d"),aSize);
1.502 + test.Start(b);
1.503 +//
1.504 + testNew(aSize);
1.505 + testNewL(aSize);
1.506 + testAlloc(aSize);
1.507 + testBlock(aSize);
1.508 +//
1.509 + test.End();
1.510 + }
1.511 +
1.512 +GLDEF_C TInt E32Main()
1.513 +//
1.514 +// Test bitmap allocator
1.515 +//
1.516 + {
1.517 + test.Title();
1.518 + __UHEAP_MARK;
1.519 +//
1.520 + test.Start(_L("1 bit"));
1.521 + testAll(1);
1.522 +
1.523 + test.Next(_L("4 bit"));
1.524 + testAll(4);
1.525 +//
1.526 + test.Next(_L("32 bit"));
1.527 + testAll(32);
1.528 +//
1.529 + test.Next(_L("33 bit"));
1.530 + testAll(33);
1.531 +//
1.532 + test.Next(_L("68 bit"));
1.533 + testAll(68);
1.534 +//
1.535 + test.Next(_L("96 bit"));
1.536 + testAll(96);
1.537 +//
1.538 + test.Next(_L("64 bit"));
1.539 + testAll(64);
1.540 +//
1.541 + test.Next(_L("65 bit"));
1.542 + testAll(65);
1.543 +//
1.544 + test.Next(_L("63 bit"));
1.545 + testAll(63);
1.546 +
1.547 + testContiguousAllocation(2048);
1.548 +
1.549 + test.Next(_L("test defect EXT-5AMDKP"));
1.550 +
1.551 + CBitMapAllocator* pB = CBitMapAllocator::New(64);
1.552 + test(pB != NULL);
1.553 + pB->AllocAt(0, 32);
1.554 + pB->Free(2, 2);
1.555 + pB->Free(5, 2);
1.556 + pB->Free(8, 2);
1.557 + pB->Free(12, 3);
1.558 + pB->Free(30, 2);
1.559 + TInt page = -1;
1.560 + pB->ExtractRamPages(3, page);
1.561 + test(page == 12);
1.562 + pB->ExtractRamPages(4, page);
1.563 + test(page == 30);
1.564 + pB->ExtractRamPages(1, page);
1.565 + test(page == 2);
1.566 + pB->ExtractRamPages(5, page);
1.567 + test(page == 34);
1.568 + pB->ExtractRamPages(2, page);
1.569 + test(page == 5);
1.570 + delete pB;
1.571 +
1.572 + __UHEAP_MARKEND;
1.573 + test.End();
1.574 + return(KErrNone);
1.575 + }
1.576 +