kerneltest/e32test/buffer/t_tbma.cpp
changeset 9 96e5fb8b040d
child 26 c734af59ce98
equal deleted inserted replaced
-1:000000000000 9:96e5fb8b040d
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32test\buffer\t_tbma.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #define __E32TEST_EXTENSION__
       
    19 #include "t_tbma.h"
       
    20 #include <cpudefs.h>
       
    21 #include <e32atomics.h>
       
    22 
       
    23 RTest test(_L("T_TBMA"));
       
    24 
       
    25 
       
    26 /**************************************
       
    27  * class TBmaList
       
    28  **************************************/
       
    29 
       
    30 TBmaList* TBmaList::New(TInt aNumBmas)
       
    31 	{
       
    32 	TBmaList* pL=new TBmaList;
       
    33 	if (pL)
       
    34 		{
       
    35 		pL->iNumBmas=aNumBmas;
       
    36 		pL->iBmaList=(TBitMapAllocator**)User::Alloc(aNumBmas*sizeof(TBitMapAllocator*));
       
    37 		if (pL->iBmaList)
       
    38 			Mem::FillZ(pL->iBmaList, aNumBmas*sizeof(TBitMapAllocator*));
       
    39 		pL->iBaseList=(TInt*)User::Alloc((aNumBmas+1)*sizeof(TInt));
       
    40 		if (!pL->iBmaList || !pL->iBaseList)
       
    41 			{
       
    42 			delete pL;
       
    43 			pL=NULL;
       
    44 			}
       
    45 		}
       
    46 	return pL;
       
    47 	}
       
    48 
       
    49 TBmaList* TBmaList::New(const TBitMapAllocator& aBma, TInt aNumSplits, VA_LIST aList)
       
    50 	{
       
    51 	TBmaList* pL=TBmaList::New(aNumSplits+1);
       
    52 	if (!pL)
       
    53 		return NULL;
       
    54 	TInt i;
       
    55 	pL->iBaseList[0]=0;
       
    56 	for (i=1; i<=aNumSplits; ++i)
       
    57 		pL->iBaseList[i]=VA_ARG(aList,TInt);
       
    58 	pL->iBaseList[aNumSplits+1]=aBma.iSize;
       
    59 	for (i=0; i<=aNumSplits; ++i)
       
    60 		{
       
    61 		TInt sz=pL->iBaseList[i+1]-pL->iBaseList[i];
       
    62 		__ASSERT_ALWAYS(sz>0, TBMA_FAULT());
       
    63 		pL->iBmaList[i]=TBitMapAllocator::New(sz,EFalse);
       
    64 		if (!pL->iBmaList[i])
       
    65 			{
       
    66 			delete pL;
       
    67 			return NULL;
       
    68 			}
       
    69 		TInt j;
       
    70 		for (j=0; j<sz; ++j)
       
    71 			{
       
    72 			if (aBma.NotAllocated(j+pL->iBaseList[i],1))
       
    73 				pL->iBmaList[i]->Free(j);
       
    74 			}
       
    75 		}
       
    76 	return pL;
       
    77 	}
       
    78 
       
    79 TBmaList::TBmaList()
       
    80 	{
       
    81 	iNumBmas=0;
       
    82 	iBmaList=NULL;
       
    83 	iBaseList=NULL;
       
    84 	}
       
    85 
       
    86 TBmaList::~TBmaList()
       
    87 	{
       
    88 	TInt i;
       
    89 	for (i=0; i<iNumBmas; ++i)
       
    90 		delete iBmaList[i];
       
    91 	User::Free(iBmaList);
       
    92 	User::Free(iBaseList);
       
    93 	}
       
    94 /*
       
    95  * Extended first fit allocator
       
    96  */
       
    97 TInt TBmaList::AllocConsecutiveFF(TInt aLength)
       
    98 	{
       
    99 	TInt base=KErrNotFound;
       
   100 	TInt bmalen=0;
       
   101 	TInt carry=0;
       
   102 	TBitMapAllocator** ppA=iBmaList;		// pointer to list of TBitMapAllocator*
       
   103 	TBitMapAllocator** pE=ppA+iNumBmas;
       
   104 	TInt* pB=iBaseList;
       
   105 	for (; ppA<pE; ++ppA, ++pB)
       
   106 		{
       
   107 		TBitMapAllocator* pA=*ppA;
       
   108 		if (*pB!=base+bmalen)
       
   109 			{
       
   110 			// this BMA is not contiguous with previous one
       
   111 			carry=0;
       
   112 			}
       
   113 		base=*pB;
       
   114 		bmalen=pA->iSize;
       
   115 		TInt l;
       
   116 		TInt r=pA->AllocAligned(aLength,0,0,EFalse,carry,l);
       
   117 		if (r>=0)
       
   118 			return base+r-carry;
       
   119 		}
       
   120 	return KErrNotFound;
       
   121 	}
       
   122 
       
   123 /*
       
   124  * Extended best fit allocator
       
   125  */
       
   126 TInt TBmaList::AllocConsecutiveBF(TInt aLength)
       
   127 	{
       
   128 	TInt bmalen=0;
       
   129 	TInt carry=0;
       
   130 	TInt minrun=KMaxTInt;
       
   131 	TInt minrunpos=KErrNotFound;
       
   132 	TBitMapAllocator** ppA=iBmaList;		// pointer to list of TBitMapAllocator*
       
   133 	TBitMapAllocator** pE=ppA+iNumBmas;
       
   134 	TInt* pB=iBaseList;
       
   135 	TInt base=*pB;
       
   136 	for (; ppA<pE; ++ppA, ++pB)
       
   137 		{
       
   138 		TBitMapAllocator* pA=*ppA;
       
   139 		if (*pB!=base+bmalen)
       
   140 			{
       
   141 			// this BMA is not contiguous with previous one
       
   142 			// check final run of previous BMA
       
   143 			if (carry<minrun)
       
   144 				{
       
   145 				minrun=carry;
       
   146 				minrunpos=base+bmalen-carry;
       
   147 				}
       
   148 			carry=0;
       
   149 			}
       
   150 		base=*pB;
       
   151 		bmalen=pA->iSize;
       
   152 		TInt l=KMaxTInt;
       
   153 		TInt oldc=carry;
       
   154 		TInt r=pA->AllocAligned(aLength,0,0,ETrue,carry,l);
       
   155 		if (r>=0)
       
   156 			{
       
   157 			// check shortest run in this BMA
       
   158 			if (l<minrun)
       
   159 				{
       
   160 				minrun=l;
       
   161 				minrunpos=r ? (base+r) : (base-oldc);
       
   162 				if (minrun==aLength)
       
   163 					break;				// exact match so finish
       
   164 				}
       
   165 			}
       
   166 		}
       
   167 	// check final run of last BMA
       
   168 	if (ppA==pE && carry>=aLength && carry<minrun)
       
   169 		minrunpos=base+bmalen-carry;
       
   170 	return minrunpos;
       
   171 	}
       
   172 
       
   173 /*
       
   174  * Extended first fit aligned allocator
       
   175  */
       
   176 TInt TBmaList::AllocAlignedFF(TInt aLength, TInt aAlign)
       
   177 	{
       
   178 	TUint32 alignsize=1<<aAlign;
       
   179 	TUint32 alignmask=alignsize-1;
       
   180 	TInt base=KErrNotFound;
       
   181 	TInt bmalen=0;
       
   182 	TInt carry=0;
       
   183 	TBitMapAllocator** ppA=iBmaList;		// pointer to list of TBitMapAllocator*
       
   184 	TBitMapAllocator** pE=ppA+iNumBmas;
       
   185 	TInt* pB=iBaseList;
       
   186 	for (; ppA<pE; ++ppA, ++pB)
       
   187 		{
       
   188 		TBitMapAllocator* pA=*ppA;
       
   189 		if (*pB!=base+bmalen)
       
   190 			{
       
   191 			// this BMA is not contiguous with previous one
       
   192 			carry=0;
       
   193 			}
       
   194 		base=*pB;
       
   195 		bmalen=pA->iSize;
       
   196 		TInt l;
       
   197 		TInt r=pA->AllocAligned(aLength,aAlign,base,EFalse,carry,l);
       
   198 		if (r>=0)
       
   199 			return (base+r-carry+alignmask)&~alignmask;
       
   200 		}
       
   201 	return KErrNotFound;
       
   202 	}
       
   203 
       
   204 /*
       
   205  * Extended best fit aligned allocator
       
   206  */
       
   207 TInt TBmaList::AllocAlignedBF(TInt aLength, TInt aAlign)
       
   208 	{
       
   209 	TInt bmalen=0;
       
   210 	TInt carry=0;
       
   211 	TInt minrun=KMaxTInt;
       
   212 	TInt minrunpos=KErrNotFound;
       
   213 	TUint32 alignsize=1<<aAlign;
       
   214 	TUint32 alignmask=alignsize-1;
       
   215 	TBitMapAllocator** ppA=iBmaList;		// pointer to list of TBitMapAllocator*
       
   216 	TBitMapAllocator** pE=ppA+iNumBmas;
       
   217 	TInt* pB=iBaseList;
       
   218 	TInt base=*pB;
       
   219 	for (; ppA<pE; ++ppA, ++pB)
       
   220 		{
       
   221 		TBitMapAllocator* pA=*ppA;
       
   222 		if (*pB!=base+bmalen)
       
   223 			{
       
   224 			// this BMA is not contiguous with previous one
       
   225 			// check final run of previous BMA
       
   226 			if (carry<minrun)
       
   227 				{
       
   228 				TInt fpos=base+bmalen-carry;
       
   229 				TInt lost=((fpos+base+alignmask)&~alignmask)-base-fpos;
       
   230 				if (carry-lost>=aLength)
       
   231 					{
       
   232 					minrun=carry;
       
   233 					minrunpos=fpos;
       
   234 					}
       
   235 				}
       
   236 			carry=0;
       
   237 			}
       
   238 		base=*pB;
       
   239 		bmalen=pA->iSize;
       
   240 		TInt l=KMaxTInt;
       
   241 		TInt oldc=carry;
       
   242 		TInt r=pA->AllocAligned(aLength,aAlign,base,ETrue,carry,l);
       
   243 		if (r>=0)
       
   244 			{
       
   245 			// check shortest run in this BMA
       
   246 			if (l<minrun)
       
   247 				{
       
   248 				minrun=l;
       
   249 				minrunpos=r ? (base+r) : (base-oldc);
       
   250 				if (minrun==aLength)
       
   251 					break;				// exact match so finish
       
   252 				}
       
   253 			}
       
   254 		}
       
   255 	// check final run of last BMA
       
   256 	if (ppA==pE && carry<minrun)
       
   257 		{
       
   258 		TInt fpos=base+bmalen-carry;
       
   259 		TInt lost=((fpos+alignmask)&~alignmask)-fpos;
       
   260 		if (carry-lost>=aLength)
       
   261 			{
       
   262 			minrun=carry;
       
   263 			minrunpos=fpos;
       
   264 			}
       
   265 		}
       
   266 	return (minrunpos<0) ? minrunpos : ((minrunpos+alignmask)&~alignmask);
       
   267 	}
       
   268 
       
   269 
       
   270 
       
   271 
       
   272 
       
   273 
       
   274 
       
   275 
       
   276 void Display(TBitMapAllocator* aBma)
       
   277 	{
       
   278 	test.Printf(_L("Free %d FirstCheck %08x Size %d Map %08x\n"),aBma->iAvail,aBma->iCheckFirst,aBma->iSize,aBma->iMap);
       
   279 	TInt i;
       
   280 	TInt l=0;
       
   281 	for (i=0; i<((aBma->iSize+31)>>5); i++)
       
   282 		{
       
   283 		if (++l==10)
       
   284 			{
       
   285 			l=0;
       
   286 //			test.Getch();
       
   287 			}
       
   288 		TUint32 x=aBma->iMap[i];
       
   289 		TBuf<80> buf;
       
   290 		buf.NumFixedWidth(x,EBinary,32);
       
   291 		buf.Append(_L("\n"));
       
   292 		test.Printf(buf);
       
   293 		}
       
   294 	test.Getch();
       
   295 	}
       
   296 
       
   297 void Check(TBitMapAllocator& a)
       
   298 	{
       
   299 	TInt l=a.iSize;
       
   300 	l=(l+31)>>5;
       
   301 	TInt n=0;
       
   302 	TInt i;
       
   303 	TUint32* first=NULL;
       
   304 	for (i=0; i<l; ++i)
       
   305 		{
       
   306 		TUint32 w=a.iMap[i];
       
   307 		if (w && !first)
       
   308 			first=a.iMap+i;
       
   309 		n+=__e32_bit_count_32(w);
       
   310 		}
       
   311 	test(a.Avail()==n);
       
   312 	test(first?(a.iCheckFirst<=first):(a.iCheckFirst>=a.iMap && a.iCheckFirst<=a.iMap+l));
       
   313 	}
       
   314 
       
   315 void TestConstruct(TInt aSize)
       
   316 	{
       
   317 	test.Printf(_L("TestConstruct %d\n"),aSize);
       
   318 	TBitMapAllocator* pA;
       
   319 	pA=TBitMapAllocator::New(aSize, EFalse);
       
   320 	test(pA!=NULL);
       
   321 	test(pA->Avail()==0);
       
   322 	Check(*pA);
       
   323 	delete pA;
       
   324 	pA=TBitMapAllocator::New(aSize, ETrue);
       
   325 	test(pA!=NULL);
       
   326 	test(pA->Avail()==aSize);
       
   327 	Check(*pA);
       
   328 	delete pA;
       
   329 	}
       
   330 
       
   331 void TestAlloc1(TInt aSize)
       
   332 	{
       
   333 	test.Printf(_L("TestAlloc1 %d\n"),aSize);
       
   334 	TBitMapAllocator* pA=TBitMapAllocator::New(aSize, ETrue);
       
   335 	test(pA!=NULL);
       
   336 	test(pA->Avail()==aSize);
       
   337 	Check(*pA);
       
   338 	TInt i;
       
   339 	for (i=0; i<aSize; ++i)
       
   340 		{
       
   341 		TInt r=pA->Alloc();
       
   342 		test(r==i);
       
   343 		test(pA->Avail()==aSize-i-1);
       
   344 		test(pA->iCheckFirst==pA->iMap+i/32);
       
   345 		Check(*pA);
       
   346 		}
       
   347 	test(pA->Alloc()<0);
       
   348 	delete pA;
       
   349 	}
       
   350 
       
   351 void TestFree1(TInt aSize)
       
   352 	{
       
   353 	test.Printf(_L("TestFree1 %d\n"),aSize);
       
   354 	TBitMapAllocator* pA=TBitMapAllocator::New(aSize, EFalse);
       
   355 	test(pA!=NULL);
       
   356 	test(pA->Avail()==0);
       
   357 	TInt i;
       
   358 	for (i=aSize-1; i>=0; --i)
       
   359 		{
       
   360 		pA->Free(i);
       
   361 		test(pA->Avail()==aSize-i);
       
   362 		test(pA->Alloc()==i);
       
   363 		pA->Free(i);
       
   364 		test(pA->iCheckFirst==pA->iMap+i/32);
       
   365 		Check(*pA);
       
   366 		}
       
   367 	delete pA;
       
   368 	}
       
   369 
       
   370 void TestBlockAlloc(TInt aSize)
       
   371 	{
       
   372 	test.Printf(_L("TestBlockAlloc %d\n"),aSize);
       
   373 	const TInt begin[]={0,1,2,7,16,29,31,32,33,63,64,65,83,128};
       
   374 	TBitMapAllocator* pA=TBitMapAllocator::New(aSize, ETrue);
       
   375 	test(pA!=NULL);
       
   376 	test(pA->Avail()==aSize);
       
   377 	pA->Alloc(0,aSize);
       
   378 	test(pA->Avail()==0);
       
   379 	Check(*pA);
       
   380 	pA->Free(0,aSize);
       
   381 	test(pA->Avail()==aSize);
       
   382 	Check(*pA);
       
   383 	TInt i;
       
   384 	for (i=0; i<(TInt)(sizeof(begin)/sizeof(TInt)); ++i)
       
   385 		{
       
   386 		TInt j=begin[i];
       
   387 		if (j>aSize)
       
   388 			break;
       
   389 		TInt l;
       
   390 		for (l=1; l<=aSize-j; ++l)
       
   391 			{
       
   392 //			test.Printf(_L("j=%d, l=%d, s=%d\n"),j,l,aSize);
       
   393 			pA->Alloc(j,l);
       
   394 			test(pA->Avail()==aSize-l);
       
   395 			test(!pA->NotAllocated(j,l));
       
   396 			if (j+l<aSize)
       
   397 				test(pA->NotAllocated(j,l+1));
       
   398 			if (j>0)
       
   399 				test(pA->NotAllocated(j-1,l));
       
   400 			TInt r=pA->Alloc();
       
   401 			if (j==0)
       
   402 				{
       
   403 				if (l<aSize)
       
   404 					test(r==l);
       
   405 				else
       
   406 					test(r<0);
       
   407 				}
       
   408 			else
       
   409 				test(r==0);
       
   410 			if (r==0)
       
   411 				{
       
   412 				pA->Free(r);
       
   413 				pA->Free(j,l);
       
   414 				}
       
   415 			else if (r>0)
       
   416 				pA->Free(j,l+1);
       
   417 			else
       
   418 				pA->Free(j,l);
       
   419 			test(pA->Avail()==aSize);
       
   420 			Check(*pA);
       
   421 			}
       
   422 		}
       
   423 	delete pA;
       
   424 	}
       
   425 
       
   426 void TestBlockFree(TInt aSize)
       
   427 	{
       
   428 	test.Printf(_L("TestBlockFree %d\n"),aSize);
       
   429 	const TInt begin[]={0,1,2,7,16,29,31,32,33,63,64,65,83,128};
       
   430 	TBitMapAllocator* pA=TBitMapAllocator::New(aSize, EFalse);
       
   431 	test(pA!=NULL);
       
   432 	test(pA->Avail()==0);
       
   433 	TInt i;
       
   434 	for (i=0; i<(TInt)(sizeof(begin)/sizeof(TInt)); ++i)
       
   435 		{
       
   436 		TInt j=begin[i];
       
   437 		if (j>aSize)
       
   438 			break;
       
   439 		TInt l;
       
   440 		for (l=1; l<=aSize-j; ++l)
       
   441 			{
       
   442 //			test.Printf(_L("j=%d, l=%d, s=%d\n"),j,l,aSize);
       
   443 			pA->Free(j,l);
       
   444 			test(pA->Avail()==l);
       
   445 			test(!pA->NotFree(j,l));
       
   446 			if (j+l<aSize)
       
   447 				test(pA->NotFree(j,l+1));
       
   448 			if (j>0)
       
   449 				test(pA->NotFree(j-1,l));
       
   450 			TInt r=pA->Alloc();
       
   451 			test(r==j);
       
   452 			if (l>1)
       
   453 				pA->Alloc(j+1,l-1);
       
   454 			test(pA->Avail()==0);
       
   455 			Check(*pA);
       
   456 			}
       
   457 		}
       
   458 	delete pA;
       
   459 	}
       
   460 
       
   461 void TestNotFree(TInt aSize)
       
   462 	{
       
   463 	test.Printf(_L("TestNotFree %d\n"),aSize);
       
   464 	TBitMapAllocator* pA=TBitMapAllocator::New(aSize, ETrue);
       
   465 	test(pA!=NULL);
       
   466 	test(pA->Avail()==aSize);
       
   467 	test(!pA->NotFree(0,aSize));
       
   468 	TInt i;
       
   469 	for (i=0; i<aSize; ++i)
       
   470 		{
       
   471 		pA->Alloc(i,1);
       
   472 		test(pA->NotFree(0,aSize));
       
   473 		TInt j;
       
   474 		for (j=1; j*j<=i || j*j+i<=aSize; ++j)
       
   475 			{
       
   476 			TInt a=Max(i-j*j,0);
       
   477 			TInt b=Min(i+j*j,aSize);
       
   478 			test(pA->NotFree(a,b-a));
       
   479 			}
       
   480 		pA->Free(i);
       
   481 		test(!pA->NotFree(0,aSize));
       
   482 		}
       
   483 	const TInt begin[]={0,1,2,7,16,29,31,32,33,63,64,65,83,128};
       
   484 	const TInt size[]={2,3,7,16,23,31,32,33,63,64,65,89,128};
       
   485 	const TInt* pB=begin;
       
   486 	const TInt* pBE=pB+sizeof(begin)/sizeof(TInt);
       
   487 	const TInt* pS=size;
       
   488 	const TInt* pSE=pS+sizeof(size)/sizeof(TInt);
       
   489 	for (; pB<pBE; ++pB)
       
   490 		{
       
   491 		TInt b=*pB;
       
   492 		if (b>=aSize)
       
   493 			continue;
       
   494 		for (; pS<pSE; ++pS)
       
   495 			{
       
   496 			TInt l=*pS;
       
   497 			if (b+l>aSize)
       
   498 				continue;
       
   499 			pA->Alloc(b,l);
       
   500 			TInt j;
       
   501 			for (j=1; j<aSize; ++j)
       
   502 				{
       
   503 				if (j<=b)
       
   504 					test(!pA->NotFree(0,j));
       
   505 				else
       
   506 					test(pA->NotFree(0,j));
       
   507 				if (aSize-j>=b+l)
       
   508 					test(!pA->NotFree(aSize-j,j));
       
   509 				else
       
   510 					test(pA->NotFree(aSize-j,j));
       
   511 				}
       
   512 			pA->Free(b,l);
       
   513 			}
       
   514 		}
       
   515 	delete pA;
       
   516 	}
       
   517 
       
   518 void TestNotAllocated(TInt aSize)
       
   519 	{
       
   520 	test.Printf(_L("TestNotAllocated %d\n"),aSize);
       
   521 	TBitMapAllocator* pA=TBitMapAllocator::New(aSize, EFalse);
       
   522 	test(pA!=NULL);
       
   523 	test(pA->Avail()==0);
       
   524 	test(!pA->NotAllocated(0,aSize));
       
   525 	TInt i;
       
   526 	for (i=0; i<aSize; ++i)
       
   527 		{
       
   528 		pA->Free(i);
       
   529 		test(pA->NotAllocated(0,aSize));
       
   530 		TInt j;
       
   531 		for (j=1; j*j<=i || j*j+i<=aSize; ++j)
       
   532 			{
       
   533 			TInt a=Max(i-j*j,0);
       
   534 			TInt b=Min(i+j*j,aSize);
       
   535 			test(pA->NotAllocated(a,b-a));
       
   536 			}
       
   537 		pA->Alloc(i,1);
       
   538 		test(!pA->NotAllocated(0,aSize));
       
   539 		}
       
   540 	const TInt begin[]={0,1,2,7,16,29,31,32,33,63,64,65,83,128};
       
   541 	const TInt size[]={2,3,7,16,23,31,32,33,63,64,65,89,128};
       
   542 	const TInt* pB=begin;
       
   543 	const TInt* pBE=pB+sizeof(begin)/sizeof(TInt);
       
   544 	const TInt* pS=size;
       
   545 	const TInt* pSE=pS+sizeof(size)/sizeof(TInt);
       
   546 	for (; pB<pBE; ++pB)
       
   547 		{
       
   548 		TInt b=*pB;
       
   549 		if (b>=aSize)
       
   550 			continue;
       
   551 		for (; pS<pSE; ++pS)
       
   552 			{
       
   553 			TInt l=*pS;
       
   554 			if (b+l>aSize)
       
   555 				continue;
       
   556 			pA->Free(b,l);
       
   557 			TInt j;
       
   558 			for (j=1; j<aSize; ++j)
       
   559 				{
       
   560 				if (j<=b)
       
   561 					test(!pA->NotAllocated(0,j));
       
   562 				else
       
   563 					test(pA->NotAllocated(0,j));
       
   564 				if (aSize-j>=b+l)
       
   565 					test(!pA->NotAllocated(aSize-j,j));
       
   566 				else
       
   567 					test(pA->NotAllocated(aSize-j,j));
       
   568 				}
       
   569 			pA->Alloc(b,l);
       
   570 			}
       
   571 		}
       
   572 	delete pA;
       
   573 	}
       
   574 
       
   575 void TestAllocList(TInt aSize)
       
   576 	{
       
   577 	test.Printf(_L("TestAllocList %d\n"),aSize);
       
   578 	TBitMapAllocator* pA=TBitMapAllocator::New(aSize, EFalse);
       
   579 	test(pA!=NULL);
       
   580 	test(pA->Avail()==0);
       
   581 	TInt i;
       
   582 	TInt list[256];
       
   583 	for (i=0; i<aSize; ++i)
       
   584 		{
       
   585 		pA->Free(i);
       
   586 		test(pA->AllocList(128,list)==1);
       
   587 		test(list[0]==i);
       
   588 		test(pA->Avail()==0);
       
   589 		}
       
   590 	TInt j;
       
   591 	for (i=0; i<aSize-1; ++i)
       
   592 		{
       
   593 		for (j=i+1; j<aSize; ++j)
       
   594 			{
       
   595 			pA->Free(i);
       
   596 			pA->Free(j);
       
   597 			test(pA->AllocList(1,list)==1);
       
   598 			test(list[0]==i);
       
   599 			test(pA->Avail()==1);
       
   600 			pA->Free(i);
       
   601 			test(pA->AllocList(128,list)==2);
       
   602 			test(list[0]==i && list[1]==j);
       
   603 			test(pA->Avail()==0);
       
   604 			}
       
   605 		}
       
   606 	TInt l;
       
   607 	for (l=1; l<80; ++l)
       
   608 		{
       
   609 		if (2*l+1>aSize)
       
   610 			break;
       
   611 		for (i=l+1; i<=aSize-l; ++i)
       
   612 			{
       
   613 			pA->Free(0,l);
       
   614 			pA->Free(i,l);
       
   615 			test(pA->Avail()==2*l);
       
   616 			TInt l2;
       
   617 			for (l2=Max(l-1,1); l2<=2*l; ++l2)
       
   618 				{
       
   619 				TInt r=pA->AllocList(l2,list);
       
   620 //				test.Printf(_L("l2=%d r=%d\n"),l2,r);
       
   621 				test(r==l2);
       
   622 				for (j=0; j<Min(l2,l); j++)
       
   623 					test(list[j]==j);
       
   624 				for (j=l; j<l2; j++)
       
   625 					test(list[j]==j-l+i);
       
   626 				for (j=0; j<l2; ++j)
       
   627 					pA->Free(list[j]);
       
   628 				pA->SelectiveFree(0,l);
       
   629 				pA->SelectiveFree(i,l);
       
   630 				test(pA->Avail()==2*l);
       
   631 				}
       
   632 			pA->Alloc(0,l);
       
   633 			pA->Alloc(i,l);
       
   634 			Check(*pA);
       
   635 			}
       
   636 		}
       
   637 	delete pA;
       
   638 	}
       
   639 
       
   640 void TestSelectiveFree(TInt aSize)
       
   641 	{
       
   642 	test.Printf(_L("TestSelectiveFree %d\n"),aSize);
       
   643 	TBitMapAllocator* pA=TBitMapAllocator::New(aSize, ETrue);
       
   644 	test(pA!=NULL);
       
   645 	test(pA->Avail()==aSize);
       
   646 	TInt i;
       
   647 	TInt j;
       
   648 	TInt l;
       
   649 	for (i=2; i<8; ++i)
       
   650 		{
       
   651 		for (l=1; l<=aSize; ++l)
       
   652 			{
       
   653 			new (pA) TBitMapAllocator(aSize, ETrue);
       
   654 			for (j=0; j<aSize; j+=i)
       
   655 				pA->Alloc(j,1);
       
   656 			TInt orig=pA->Avail();
       
   657 			test(orig==aSize-(aSize+i-1)/i);
       
   658 			pA->SelectiveFree(0,l);
       
   659 			TInt freed=pA->Avail()-orig;
       
   660 			test(freed==(l+i-1)/i);
       
   661 			Check(*pA);
       
   662 			}
       
   663 		}
       
   664 	for (i=0; i<=Min(32,aSize-1); ++i)
       
   665 		{
       
   666 		for (l=1; l<=aSize-i; ++l)
       
   667 			{
       
   668 			for (j=1; j<=aSize; ++j)
       
   669 				{
       
   670 				new (pA) TBitMapAllocator(aSize, ETrue);
       
   671 				pA->Alloc(i,l);
       
   672 				test(pA->Avail()==aSize-l);
       
   673 				pA->SelectiveFree(0,j);
       
   674 				test(pA->Avail()==aSize-l+Max(0,Min(i+l,j)-i));
       
   675 				test(!pA->NotFree(0,j));
       
   676 				if (j>=i && j<i+l)
       
   677 					test(pA->NotFree(0,j+1));
       
   678 				Check(*pA);
       
   679 				}
       
   680 			}
       
   681 		}
       
   682 	delete pA;
       
   683 	}
       
   684 
       
   685 TBitMapAllocator* DoSetupBMA(TInt aSize, VA_LIST aList)
       
   686 	{
       
   687 	TBitMapAllocator* pA=TBitMapAllocator::New(aSize, EFalse);
       
   688 	test(pA!=NULL);
       
   689 	test(pA->Avail()==0);
       
   690 	TInt totalfree=0;
       
   691 	FOREVER
       
   692 		{
       
   693 		TInt i=VA_ARG(aList,TInt);
       
   694 		if (i<0)
       
   695 			break;
       
   696 		TInt l=VA_ARG(aList,TInt);
       
   697 		pA->Free(i,l);
       
   698 		totalfree+=l;
       
   699 		}
       
   700 	test(pA->Avail()==totalfree);
       
   701 	return pA;
       
   702 	}
       
   703 
       
   704 TBitMapAllocator* SetupBMA(TInt aSize, ...)
       
   705 	{
       
   706 	VA_LIST list;
       
   707 	VA_START(list,aSize);
       
   708 	return DoSetupBMA(aSize,list);
       
   709 	}
       
   710 
       
   711 void PopulateRangeArray(RArray<SRange>& aArray, VA_LIST aList)
       
   712 	{
       
   713 	aArray.Reset();
       
   714 	TInt n=0;
       
   715 	FOREVER
       
   716 		{
       
   717 		SRange rng;
       
   718 		rng.iBase=VA_ARG(aList,TInt);
       
   719 		if (rng.iBase<0)
       
   720 			break;
       
   721 		rng.iLength=VA_ARG(aList,TInt);
       
   722 		rng.iLength<<=8;
       
   723 		rng.iLength+=n;
       
   724 		++n;
       
   725 		test(aArray.Append(rng)==KErrNone);
       
   726 		}
       
   727 	}
       
   728 
       
   729 TInt FirstFitPos(RArray<SRange>& aArray, TInt aLength)
       
   730 	{
       
   731 	TInt c=aArray.Count();
       
   732 	SRange* pR=&aArray[0];
       
   733 	SRange* pE=pR+c;
       
   734 	for (; pR<pE; ++pR)
       
   735 		{
       
   736 		TInt l=pR->iLength>>8;
       
   737 		if (l>=aLength)
       
   738 			{
       
   739 //			test.Printf(_L("FFP %d = %d\n"),aLength,pR->iBase);
       
   740 			return pR->iBase;
       
   741 			}
       
   742 		}
       
   743 //	test.Printf(_L("FFP %d = -1\n"),aLength);
       
   744 	return -1;
       
   745 	}
       
   746 
       
   747 TInt AlignedFirstFitPos(RArray<SRange>& aArray, TInt aSize, TInt aLength, TInt aAlign, TInt aBase, TInt aOffset=0, TBool aBestFit=EFalse)
       
   748 	{
       
   749 	TInt alignSize=1<<aAlign;
       
   750 	TInt alignMask=alignSize-1;
       
   751 	TInt minRun=0;
       
   752 	TInt minRunStart=0;
       
   753 	TBool runFound = EFalse;
       
   754 	TInt c=aArray.Count();
       
   755 	SRange* pR=&aArray[0];
       
   756 	// Best fit mode should ignore any final run TBitMapAllocator will 
       
   757 	// always ignore the final run in best fit mode and rely on carry being
       
   758 	// checked by the caller.
       
   759 	SRange* pE = pR + c - 1;
       
   760 	if (!aBestFit || aSize > pE->iBase + (pE->iLength >> 8))
       
   761 		pE++;
       
   762 
       
   763 	for (; pR<pE; ++pR)
       
   764 		{
       
   765 		TInt l=pR->iLength>>8;
       
   766 		TInt b=pR->iBase;
       
   767 		if (aOffset != 0)
       
   768 			{
       
   769 			aOffset = ((aOffset + aBase + alignMask) & ~alignMask) - aBase;
       
   770 			if (aOffset + aLength - 1 >= b + l)
       
   771 				{// The offset is after the end of this region.
       
   772 				continue;
       
   773 				}
       
   774 			l -= (aOffset <= b)? 0 : aOffset - b;
       
   775 			b += (aOffset <= b)? 0 : aOffset - b;	// Start the search from aOffset
       
   776 			}
       
   777 		TInt ab=((b+aBase+alignMask)&~alignMask)-aBase;
       
   778 		TInt al = l + b - ab;
       
   779 		if (al >= aLength)
       
   780 			{
       
   781 			if (!aBestFit || l == aLength)
       
   782 				{
       
   783 //				test.Printf(_L("AFFP %d %d %d = %d\n"),aLength,aAlign,aBase,ab);
       
   784 				return ab;
       
   785 				}
       
   786 			if (!runFound || minRun > l)
       
   787 				{ 
       
   788 				minRun = l;
       
   789 				minRunStart = ab;
       
   790 				runFound = ETrue;
       
   791 				}
       
   792 			}
       
   793 		}
       
   794 	if (runFound)
       
   795 		{
       
   796 		return minRunStart;
       
   797 		}
       
   798 //	test.Printf(_L("AFFP %d %d %d = -1\n"),aLength,aAlign,aBase);
       
   799 	return -1;
       
   800 	}
       
   801 
       
   802 void DoConsecTest(TInt aSize, ...)
       
   803 	{
       
   804 	test.Printf(_L("DoConsecTest %d\n"),aSize);
       
   805 	VA_LIST list;
       
   806 	VA_LIST list2;
       
   807 	VA_START(list,aSize);
       
   808 	VA_START(list2,aSize);
       
   809 	TBitMapAllocator* pA=DoSetupBMA(aSize,list2);
       
   810 	RArray<SRange> rangeArray(8,_FOFF(SRange,iLength));
       
   811 	PopulateRangeArray(rangeArray, list);
       
   812 	TInt n;
       
   813 	for (n=1; n<=aSize; ++n)
       
   814 		{
       
   815 		TInt r1=pA->AllocConsecutive(n,EFalse);
       
   816 		TInt r2=FirstFitPos(rangeArray,n);
       
   817 //		test.Printf(_L("ALC(%d,0) = %d [%d]\n"),n,r1,r2);
       
   818 		test_Equal(r2, r1);
       
   819 		}
       
   820 	rangeArray.SortUnsigned();	// sort array in ascending order of length
       
   821 	for (n=1; n<=aSize; ++n)
       
   822 		{
       
   823 		TInt r1=pA->AllocConsecutive(n,ETrue);
       
   824 		TInt r2=FirstFitPos(rangeArray,n);
       
   825 //		test.Printf(_L("ALC(%d,1) = %d [%d]\n"),n,r1,r2);
       
   826 		test_Equal(r2, r1);
       
   827 		}
       
   828 	rangeArray.Close();
       
   829 	delete pA;
       
   830 	}
       
   831 
       
   832 void DoAlignedTest(TInt aSize, ...)
       
   833 	{
       
   834 	test.Printf(_L("DoAlignedTest %d\n"),aSize);
       
   835 	VA_LIST list;
       
   836 	VA_LIST list2;
       
   837 	VA_START(list,aSize);
       
   838 	VA_START(list2,aSize);
       
   839 	TBitMapAllocator* pA=DoSetupBMA(aSize,list2);
       
   840 	RArray<SRange> rangeArray(8,_FOFF(SRange,iLength));
       
   841 	PopulateRangeArray(rangeArray, list);
       
   842 	TInt finalRunLength = 0;
       
   843 	SRange& lastRun = rangeArray[rangeArray.Count() - 1];
       
   844 	if (lastRun.iBase + (lastRun.iLength>>8) == aSize)
       
   845 		{// The last run is at the end of the bma.
       
   846 		finalRunLength = lastRun.iLength >> 8;
       
   847 		}
       
   848 	TInt a;
       
   849 	TInt b;
       
   850 	TInt n;
       
   851 	TUint offset;
       
   852 	for (a=0; ((1<<a)<=aSize); ++a)
       
   853 		{
       
   854 		TInt alignsize=1<<a;
       
   855 		TInt alignmask=alignsize-1;
       
   856 		for (b=0; b<(1<<a); ++b)
       
   857 			{
       
   858 //			test.Printf(_L("size %d a=%d b=%d First\n"),aSize,a,b);
       
   859 			for (n=1; n<=aSize; ++n)
       
   860 				{
       
   861 				for (offset = 1; offset < (TUint)aSize; offset <<= 1)
       
   862 					{
       
   863 					TInt carry = 0;
       
   864 					TInt runLength;
       
   865 					TInt r1=pA->AllocAligned(n,a,b,EFalse, carry, runLength, offset);
       
   866 					TInt r2=AlignedFirstFitPos(rangeArray,aSize, n,a,b, offset);
       
   867 					if (r2 < 0 && pA->iSize == pA->iAvail)
       
   868 						{// Totally empty bmas return KErrOverflow on failure.
       
   869 						r2 = KErrOverflow;
       
   870 						}
       
   871 //					test.Printf(_L("ALA %d %d %d %d 0 = %d [%d]\n"),n,a,b,offset,r1,r2);
       
   872 					test( (r1<0) || ((r1+b)&alignmask)==0 );
       
   873 					test( (r1<0) || !pA->NotFree(r1,n));
       
   874 					test( (r1<0) || runLength >= n);
       
   875 					test_Equal(r2, r1);
       
   876 					}
       
   877 				}
       
   878 			}
       
   879 		}
       
   880 	for (a=0; ((1<<a)<=aSize); ++a)
       
   881 		{
       
   882 		TInt alignsize=1<<a;
       
   883 		TInt alignmask=alignsize-1;
       
   884 		for (b=0; b<(1<<a); ++b)
       
   885 			{
       
   886 //			test.Printf(_L("size %d a=%d b=%d Best\n"),aSize,a,b);
       
   887 			for (n=1; n<=aSize; ++n)
       
   888 				{// test for with offset=0 as that has screwed best fit in past.
       
   889 				for (offset = 0; offset < (TUint)aSize; offset <<= 1)
       
   890 					{
       
   891 					TInt carry = 0;
       
   892 					TInt runLength;
       
   893 					TInt r1=pA->AllocAligned(n,a,b,ETrue, carry, runLength, offset);
       
   894 					TInt r2=AlignedFirstFitPos(rangeArray,aSize, n,a,b, offset, ETrue);
       
   895 					if (pA->iSize == pA->iAvail)
       
   896 						{// Totally empty bmas return KErrOverflow always on best fit mode.
       
   897 						r2 = KErrOverflow;
       
   898 						}
       
   899 //					test.Printf(_L("ALA %d %d %d 1 = %d [%d]\n"),n,a,b,r1,r2);
       
   900 					test( (r1<0) || ((r1+b)&alignmask)==0 );
       
   901 					test( (r1<0) || !pA->NotFree(r1,n));
       
   902 					test( (r1<0) || runLength >= n);
       
   903 					test_Equal(r2, r1);
       
   904 					// No carry in so if run found then carry should be zero.
       
   905 					// If no run found then carry should set to the length of
       
   906 					// any run at the end of the bma minus the aligned offset.
       
   907 					TInt lost = 0;
       
   908 					TInt alignOffset = ((offset + b + alignmask) & ~alignmask) - b;
       
   909 					if (finalRunLength && offset &&	lastRun.iBase < alignOffset)
       
   910 						{// This search had started past the start of the final run
       
   911 						// so the final run length found will be shorter than its 
       
   912 						// total length.
       
   913 						if (alignOffset < aSize)
       
   914 							{
       
   915 							lost = Min(alignOffset - lastRun.iBase, finalRunLength);
       
   916 							}
       
   917 						else // alignedOffset starts past end of bma.
       
   918 							lost = finalRunLength;
       
   919 						}
       
   920 					test((r1>=0 && carry == 0) || carry == finalRunLength - lost);
       
   921 					offset = (offset)? offset : 1;
       
   922 					}
       
   923 				}
       
   924 			}
       
   925 		}
       
   926 	rangeArray.Close();
       
   927 	delete pA;
       
   928 	}
       
   929 
       
   930 void Clone(TAny* aDest, const TBitMapAllocator* aSrc)
       
   931 	{
       
   932 	TInt nmapw=(aSrc->iSize+31)>>5;
       
   933 	TInt memsz=sizeof(TBitMapAllocator)+(nmapw-1)*sizeof(TUint32);
       
   934 	Mem::Move(aDest,aSrc,memsz);
       
   935 	}
       
   936 
       
   937 void TestAllocConsecutive()
       
   938 	{
       
   939 	test.Printf(_L("TestAllocConsecutive\n"));
       
   940 	DoConsecTest(256, 0,4 , 20,8 , 38,1 , 58,6 , 65,10, 78,16 , 127,72, 222,19 , 244,12 , -1);
       
   941 	DoConsecTest(255, 0,2 , 3,2 , 6,3 , 10,3 , 14,5 , 20,5 , 26,7 , 34,7 , 42,11 , 54,11 , 66,13 , 80,37,
       
   942 																	118,19 , 138,23 , 162,47 , 254,1 , -1);
       
   943 	DoConsecTest(1023, 0,2 , 32,32 , 65,31 , 99,30 , 144,64 , 256,519 , 776,1, 778,245 , -1);
       
   944 
       
   945 	DoAlignedTest(256, 0,4 , 20,8 , 38,1 , 58,6 , 65,10, 78,16 , 127,72, 222,19 , 244,12 , -1);
       
   946 	DoAlignedTest(255, 0,2 , 3,2 , 6,3 , 10,3 , 14,5 , 20,5 , 26,7 , 34,7 , 42,11 , 54,11 , 66,13 , 80,37,
       
   947 																	118,19 , 138,23 , 162,47 , 254,1 , -1);
       
   948 	DoAlignedTest(1023, 0,2 , 32,32 , 65,31 , 99,30 , 144,64 , 256,519 , 776,1, 778,245 , -1);
       
   949 	// Test some completely free bmas
       
   950 	DoAlignedTest(255, 0,255, -1);
       
   951 	DoAlignedTest(256, 0,256, -1);
       
   952 	DoAlignedTest(1023, 0,1023, -1);
       
   953 	DoAlignedTest(1024, 0,1024, -1);
       
   954 	}
       
   955 
       
   956 void DoTestChain(const TBitMapAllocator& aBma, TInt aNumSplits, ...)
       
   957 	{
       
   958 	test.Printf(_L("DoTestChain %d %d\n"),aBma.iSize,aNumSplits);
       
   959 	VA_LIST list;
       
   960 	VA_START(list,aNumSplits);
       
   961 
       
   962 	TBmaList* pL=TBmaList::New(aBma,aNumSplits,list);
       
   963 	test(pL!=NULL);
       
   964 
       
   965 	TInt n;
       
   966 	for (n=1; n<=aBma.iSize; ++n)
       
   967 		{
       
   968 		TInt r1=aBma.AllocConsecutive(n,EFalse);
       
   969 		TInt r2=pL->AllocConsecutiveFF(n);
       
   970 //		test.Printf(_L("CHAIN C FF %d: r1=%d r2=%d\n"),n,r1,r2);
       
   971 		test(r1==r2);
       
   972 		}
       
   973 	for (n=1; n<=aBma.iSize; ++n)
       
   974 		{
       
   975 		TInt r1=aBma.AllocConsecutive(n,ETrue);
       
   976 		TInt r2=pL->AllocConsecutiveBF(n);
       
   977 //		test.Printf(_L("CHAIN C BF %d: r1=%d r2=%d\n"),n,r1,r2);
       
   978 		test(r1==r2);
       
   979 		}
       
   980 
       
   981 	TInt a;
       
   982 	for (a=0; ((1<<a)<=aBma.iSize); ++a)
       
   983 		{
       
   984 		for (n=1; n<=aBma.iSize; ++n)
       
   985 			{
       
   986 			if (n==264 && a==9)
       
   987 				{
       
   988 				++n;
       
   989 				--n;
       
   990 				}
       
   991 			TInt r1=aBma.AllocAligned(n,a,0,EFalse);
       
   992 			TInt r2=pL->AllocAlignedFF(n,a);
       
   993 //			test.Printf(_L("CHAIN A FF %d,%d: r1=%d r2=%d\n"),n,a,r1,r2);
       
   994 			test(r1==r2);
       
   995 			}
       
   996 		}
       
   997 	for (a=0; ((1<<a)<=aBma.iSize); ++a)
       
   998 		{
       
   999 		for (n=1; n<=aBma.iSize; ++n)
       
  1000 			{
       
  1001 			if (n==240 && a==3)
       
  1002 				{
       
  1003 				++n;
       
  1004 				--n;
       
  1005 				}
       
  1006 			TInt r1=aBma.AllocAligned(n,a,0,ETrue);
       
  1007 			TInt r2=pL->AllocAlignedBF(n,a);
       
  1008 //			test.Printf(_L("CHAIN A BF %d,%d: r1=%d r2=%d\n"),n,a,r1,r2);
       
  1009 			test(r1==r2);
       
  1010 			}
       
  1011 		}
       
  1012 
       
  1013 	delete pL;
       
  1014 	}
       
  1015 
       
  1016 void TestChain()
       
  1017 	{
       
  1018 	test.Printf(_L("TestChain\n"));
       
  1019 	TBitMapAllocator* pA;
       
  1020 	pA=SetupBMA(1023, 0,2 , 32,32 , 65,31 , 99,30 , 144,64 , 256,519 , 776,1, 778,245 , -1);
       
  1021 	test(pA!=NULL);
       
  1022 	DoTestChain(*pA, 2, 300, 700);
       
  1023 	DoTestChain(*pA, 3, 64, 301, 702);
       
  1024 	delete pA;
       
  1025 	pA=SetupBMA(512, 0,2 , 20,10 , 32,32 , 65,31 , 144,64 , 399,113 , -1);
       
  1026 	test(pA!=NULL);
       
  1027 	DoTestChain(*pA, 2, 256, 384);
       
  1028 	DoTestChain(*pA, 3, 128, 256, 384);
       
  1029 	DoTestChain(*pA, 3, 80, 208, 384);
       
  1030 	DoTestChain(*pA, 3, 80, 208, 400);
       
  1031 	delete pA;
       
  1032 	}
       
  1033 
       
  1034 void TestBitOps()
       
  1035 	{
       
  1036 	test.Next(_L("Bit operations (32 bit)"));
       
  1037 	test(__e32_find_ls1_32(0x00000000)==-1);
       
  1038 	TInt i, j, k;
       
  1039 	TInt count = 0;
       
  1040 	for (i=0; i<=31; ++i)
       
  1041 		test(__e32_find_ls1_32(1u<<i)==i);
       
  1042 	TUint x = 0;
       
  1043 	for (i=0; i<1000; ++i)
       
  1044 		{
       
  1045 		x = 69069*x + 41;
       
  1046 		TInt bit = x&31;
       
  1047 
       
  1048 		x = 69069*x + 41;
       
  1049 		TUint y = ((x|1)<<bit);
       
  1050 
       
  1051 		test(__e32_find_ls1_32(y) == bit);
       
  1052 		}
       
  1053 
       
  1054 	test(__e32_find_ms1_32(0x00000000)==-1);
       
  1055 	for (i=0; i<=31; ++i)
       
  1056 		test(__e32_find_ms1_32(1u<<i)==i);
       
  1057 	for (i=0; i<1000; ++i)
       
  1058 		{
       
  1059 		x = 69069*x + 41;
       
  1060 		TInt bit = x&31;
       
  1061 
       
  1062 		x = 69069*x + 41;
       
  1063 		TUint y = ((x|0x80000000u)>>bit);
       
  1064 
       
  1065 		test(__e32_find_ms1_32(y) == 31-bit);
       
  1066 		}
       
  1067 
       
  1068 	test(__e32_bit_count_32(0)==0);
       
  1069 	test(__e32_bit_count_32(0xffffffff)==32);
       
  1070 	for (i=0; i<32; ++i)
       
  1071 		{
       
  1072 		TUint32 y = 0xffffffffu << i;
       
  1073 		TUint32 z = 0xffffffffu >> i;
       
  1074 		test(__e32_bit_count_32(y) == 32-i);
       
  1075 		test(__e32_bit_count_32(z) == 32-i);
       
  1076 		test(__e32_bit_count_32(~y) == i);
       
  1077 		test(__e32_bit_count_32(~z) == i);
       
  1078 		}
       
  1079 	for (i=0; i<32; ++i)
       
  1080 		for (j=0; j<32; ++j)
       
  1081 			for (k=0; k<32; ++k)
       
  1082 				{
       
  1083 				TUint32 b0 = 1u<<i;
       
  1084 				TUint32 b1 = 1u<<j;
       
  1085 				TUint32 b2 = 1u<<k;
       
  1086 				TUint32 y = b0 | b1 | b2;
       
  1087 				TInt n;
       
  1088 				if (i==j && j==k) n=1;
       
  1089 				else if (i==j || j==k || i==k) n=2;
       
  1090 				else n=3;
       
  1091 				test(__e32_bit_count_32(y) == n);
       
  1092 				test(__e32_bit_count_32(~y) == 32-n);
       
  1093 				++count;
       
  1094 				}
       
  1095 	test.Printf(_L("%d iterations done\n"), count);
       
  1096 	for (i=0; i<=31; ++i)
       
  1097 		{
       
  1098 		test(__e32_bit_count_32(0xaaaaaaaau<<i)==16-(i+1)/2);
       
  1099 		test(__e32_bit_count_32(0x55555555u<<i)==16-i/2);
       
  1100 		}
       
  1101 	test(__e32_bit_count_32(0x33333333u)==16);
       
  1102 	test(__e32_bit_count_32(0x88888888u)==8);
       
  1103 
       
  1104 	test.Next(_L("Bit operations (64 bit)"));
       
  1105 	test(__e32_find_ls1_64(0x00000000)==-1);
       
  1106 	for (i=0; i<=63; ++i)
       
  1107 		{
       
  1108 		TUint64 x = 1u;
       
  1109 		x<<=i;
       
  1110 		test(__e32_find_ls1_64(x)==i);
       
  1111 		}
       
  1112 	x = 487;
       
  1113 	for (i=0; i<1000; ++i)
       
  1114 		{
       
  1115 		x = 69069*x + 41;
       
  1116 		TInt bit = x&63;
       
  1117 
       
  1118 		x = 69069*x + 41;
       
  1119 		TUint32 xl = x|1;
       
  1120 		x = 69069*x + 41;
       
  1121 		TUint32 xh = x;
       
  1122 		TUint64 y = MAKE_TUINT64(xh,xl);
       
  1123 		y <<= bit;
       
  1124 		test(__e32_find_ls1_64(y) == bit);
       
  1125 		}
       
  1126 
       
  1127 	test(__e32_find_ms1_64(0x00000000)==-1);
       
  1128 	for (i=0; i<=63; ++i)
       
  1129 		{
       
  1130 		TUint64 x = 1u;
       
  1131 		x<<=i;
       
  1132 		test(__e32_find_ms1_64(x)==i);
       
  1133 		}
       
  1134 	x = 1039;
       
  1135 	for (i=0; i<1000; ++i)
       
  1136 		{
       
  1137 		x = 69069*x + 41;
       
  1138 		TInt bit = x&63;
       
  1139 
       
  1140 		x = 69069*x + 41;
       
  1141 		TUint32 xl = x;
       
  1142 		x = 69069*x + 41;
       
  1143 		TUint32 xh = x|0x80000000u;
       
  1144 		TUint64 y = MAKE_TUINT64(xh,xl);
       
  1145 		y >>= bit;
       
  1146 		test(__e32_find_ms1_64(y) == 63-bit);
       
  1147 		}
       
  1148 
       
  1149 	test(__e32_bit_count_64(0)==0);
       
  1150 	test(__e32_bit_count_64(MAKE_TUINT64(0x00000000,0xffffffff))==32);
       
  1151 	test(__e32_bit_count_64(MAKE_TUINT64(0xffffffff,0x00000000))==32);
       
  1152 	test(__e32_bit_count_64(MAKE_TUINT64(0xffffffff,0xffffffff))==64);
       
  1153 	for (i=0; i<64; ++i)
       
  1154 		{
       
  1155 		TUint64 y = MAKE_TUINT64(0xffffffff,0xffffffff);
       
  1156 		TUint64 z = y >> i;
       
  1157 		y <<= i;
       
  1158 		test(__e32_bit_count_64(y) == 64-i);
       
  1159 		test(__e32_bit_count_64(z) == 64-i);
       
  1160 		test(__e32_bit_count_64(~y) == i);
       
  1161 		test(__e32_bit_count_64(~z) == i);
       
  1162 		}
       
  1163 	count = 0;
       
  1164 	for (i=0; i<64; ++i)
       
  1165 		for (j=0; j<64; ++j)
       
  1166 			for (k=0; k<64; ++k)
       
  1167 				{
       
  1168 				TUint64 b0 = 1u;
       
  1169 				TUint64 b1 = 1u;
       
  1170 				TUint64 b2 = 1u;
       
  1171 				b0 <<= i;
       
  1172 				b1 <<= j;
       
  1173 				b2 <<= k;
       
  1174 				TUint64 y = b0 | b1 | b2;
       
  1175 				TUint64 z = ~y;
       
  1176 				TInt n;
       
  1177 				if (i==j && j==k) n=1;
       
  1178 				else if (i==j || j==k || i==k) n=2;
       
  1179 				else n=3;
       
  1180 				test(__e32_bit_count_64(y) == n);
       
  1181 				test(__e32_bit_count_64(z) == 64-n);
       
  1182 				++count;
       
  1183 				}
       
  1184 	test.Printf(_L("%d iterations done\n"), count);
       
  1185 	for (i=0; i<64; ++i)
       
  1186 		{
       
  1187 		TUint64 y = MAKE_TUINT64(0xaaaaaaaa,0xaaaaaaaa);
       
  1188 		TUint64 z = ~y;
       
  1189 		test(__e32_bit_count_64(y<<i)==32-(i+1)/2);
       
  1190 		test(__e32_bit_count_64(z<<i)==32-i/2);
       
  1191 		}
       
  1192 	test(__e32_bit_count_64(MAKE_TUINT64(0x33333333u,0x33333333u))==32);
       
  1193 	test(__e32_bit_count_64(MAKE_TUINT64(0x88888888u,0x88888888u))==16);
       
  1194 	}
       
  1195 
       
  1196 GLDEF_C TInt E32Main()
       
  1197 	{
       
  1198 	test.Title();
       
  1199 	__UHEAP_MARK;
       
  1200 	test.Start(_L("TBitMapAllocator tests"));
       
  1201 
       
  1202 	TestBitOps();
       
  1203 
       
  1204 	TestConstruct(3);
       
  1205 	TestConstruct(29);
       
  1206 	TestConstruct(256);
       
  1207 	TestConstruct(487);
       
  1208 
       
  1209 	TestAlloc1(3);
       
  1210 	TestAlloc1(29);
       
  1211 	TestAlloc1(256);
       
  1212 	TestAlloc1(181);
       
  1213 
       
  1214 	TestFree1(3);
       
  1215 	TestFree1(29);
       
  1216 	TestFree1(256);
       
  1217 	TestFree1(181);
       
  1218 
       
  1219 	TestBlockAlloc(3);
       
  1220 	TestBlockAlloc(29);
       
  1221 	TestBlockAlloc(256);
       
  1222 	TestBlockAlloc(179);
       
  1223 
       
  1224 	TestBlockFree(3);
       
  1225 	TestBlockFree(31);
       
  1226 	TestBlockFree(256);
       
  1227 	TestBlockFree(149);
       
  1228 
       
  1229 	TestNotFree(3);
       
  1230 	TestNotFree(31);
       
  1231 	TestNotFree(256);
       
  1232 	TestNotFree(149);
       
  1233 
       
  1234 	TestNotAllocated(3);
       
  1235 	TestNotAllocated(31);
       
  1236 	TestNotAllocated(256);
       
  1237 	TestNotAllocated(149);
       
  1238 
       
  1239 	TestAllocList(3);
       
  1240 	TestAllocList(31);
       
  1241 	TestAllocList(128);
       
  1242 	TestAllocList(149);
       
  1243 
       
  1244 	TestSelectiveFree(3);
       
  1245 	TestSelectiveFree(31);
       
  1246 	TestSelectiveFree(128);
       
  1247 	TestSelectiveFree(149);
       
  1248 
       
  1249 	TestAllocConsecutive();
       
  1250 
       
  1251 	TestChain();
       
  1252 
       
  1253 	__UHEAP_MARKEND;
       
  1254 	test.End();
       
  1255 	return 0;
       
  1256 	}