sl@0: // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test\buffer\t_tbma.cpp sl@0: // sl@0: // sl@0: sl@0: #define __E32TEST_EXTENSION__ sl@0: #include "t_tbma.h" sl@0: #include sl@0: #include sl@0: sl@0: RTest test(_L("T_TBMA")); sl@0: sl@0: sl@0: /************************************** sl@0: * class TBmaList sl@0: **************************************/ sl@0: sl@0: TBmaList* TBmaList::New(TInt aNumBmas) sl@0: { sl@0: TBmaList* pL=new TBmaList; sl@0: if (pL) sl@0: { sl@0: pL->iNumBmas=aNumBmas; sl@0: pL->iBmaList=(TBitMapAllocator**)User::Alloc(aNumBmas*sizeof(TBitMapAllocator*)); sl@0: if (pL->iBmaList) sl@0: Mem::FillZ(pL->iBmaList, aNumBmas*sizeof(TBitMapAllocator*)); sl@0: pL->iBaseList=(TInt*)User::Alloc((aNumBmas+1)*sizeof(TInt)); sl@0: if (!pL->iBmaList || !pL->iBaseList) sl@0: { sl@0: delete pL; sl@0: pL=NULL; sl@0: } sl@0: } sl@0: return pL; sl@0: } sl@0: sl@0: TBmaList* TBmaList::New(const TBitMapAllocator& aBma, TInt aNumSplits, VA_LIST aList) sl@0: { sl@0: TBmaList* pL=TBmaList::New(aNumSplits+1); sl@0: if (!pL) sl@0: return NULL; sl@0: TInt i; sl@0: pL->iBaseList[0]=0; sl@0: for (i=1; i<=aNumSplits; ++i) sl@0: pL->iBaseList[i]=VA_ARG(aList,TInt); sl@0: pL->iBaseList[aNumSplits+1]=aBma.iSize; sl@0: for (i=0; i<=aNumSplits; ++i) sl@0: { sl@0: TInt sz=pL->iBaseList[i+1]-pL->iBaseList[i]; sl@0: __ASSERT_ALWAYS(sz>0, TBMA_FAULT()); sl@0: pL->iBmaList[i]=TBitMapAllocator::New(sz,EFalse); sl@0: if (!pL->iBmaList[i]) sl@0: { sl@0: delete pL; sl@0: return NULL; sl@0: } sl@0: TInt j; sl@0: for (j=0; jiBaseList[i],1)) sl@0: pL->iBmaList[i]->Free(j); sl@0: } sl@0: } sl@0: return pL; sl@0: } sl@0: sl@0: TBmaList::TBmaList() sl@0: { sl@0: iNumBmas=0; sl@0: iBmaList=NULL; sl@0: iBaseList=NULL; sl@0: } sl@0: sl@0: TBmaList::~TBmaList() sl@0: { sl@0: TInt i; sl@0: for (i=0; iiSize; sl@0: TInt l; sl@0: TInt r=pA->AllocAligned(aLength,0,0,EFalse,carry,l); sl@0: if (r>=0) sl@0: return base+r-carry; sl@0: } sl@0: return KErrNotFound; sl@0: } sl@0: sl@0: /* sl@0: * Extended best fit allocator sl@0: */ sl@0: TInt TBmaList::AllocConsecutiveBF(TInt aLength) sl@0: { sl@0: TInt bmalen=0; sl@0: TInt carry=0; sl@0: TInt minrun=KMaxTInt; sl@0: TInt minrunpos=KErrNotFound; sl@0: TBitMapAllocator** ppA=iBmaList; // pointer to list of TBitMapAllocator* sl@0: TBitMapAllocator** pE=ppA+iNumBmas; sl@0: TInt* pB=iBaseList; sl@0: TInt base=*pB; sl@0: for (; ppAiSize; sl@0: TInt l=KMaxTInt; sl@0: TInt oldc=carry; sl@0: TInt r=pA->AllocAligned(aLength,0,0,ETrue,carry,l); sl@0: if (r>=0) sl@0: { sl@0: // check shortest run in this BMA sl@0: if (l=aLength && carryiSize; sl@0: TInt l; sl@0: TInt r=pA->AllocAligned(aLength,aAlign,base,EFalse,carry,l); sl@0: if (r>=0) sl@0: return (base+r-carry+alignmask)&~alignmask; sl@0: } sl@0: return KErrNotFound; sl@0: } sl@0: sl@0: /* sl@0: * Extended best fit aligned allocator sl@0: */ sl@0: TInt TBmaList::AllocAlignedBF(TInt aLength, TInt aAlign) sl@0: { sl@0: TInt bmalen=0; sl@0: TInt carry=0; sl@0: TInt minrun=KMaxTInt; sl@0: TInt minrunpos=KErrNotFound; sl@0: TUint32 alignsize=1<=aLength) sl@0: { sl@0: minrun=carry; sl@0: minrunpos=fpos; sl@0: } sl@0: } sl@0: carry=0; sl@0: } sl@0: base=*pB; sl@0: bmalen=pA->iSize; sl@0: TInt l=KMaxTInt; sl@0: TInt oldc=carry; sl@0: TInt r=pA->AllocAligned(aLength,aAlign,base,ETrue,carry,l); sl@0: if (r>=0) sl@0: { sl@0: // check shortest run in this BMA sl@0: if (l=aLength) sl@0: { sl@0: minrun=carry; sl@0: minrunpos=fpos; sl@0: } sl@0: } sl@0: return (minrunpos<0) ? minrunpos : ((minrunpos+alignmask)&~alignmask); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: void Display(TBitMapAllocator* aBma) sl@0: { sl@0: test.Printf(_L("Free %d FirstCheck %08x Size %d Map %08x\n"),aBma->iAvail,aBma->iCheckFirst,aBma->iSize,aBma->iMap); sl@0: TInt i; sl@0: TInt l=0; sl@0: for (i=0; i<((aBma->iSize+31)>>5); i++) sl@0: { sl@0: if (++l==10) sl@0: { sl@0: l=0; sl@0: // test.Getch(); sl@0: } sl@0: TUint32 x=aBma->iMap[i]; sl@0: TBuf<80> buf; sl@0: buf.NumFixedWidth(x,EBinary,32); sl@0: buf.Append(_L("\n")); sl@0: test.Printf(buf); sl@0: } sl@0: test.Getch(); sl@0: } sl@0: sl@0: void Check(TBitMapAllocator& a) sl@0: { sl@0: TInt l=a.iSize; sl@0: l=(l+31)>>5; sl@0: TInt n=0; sl@0: TInt i; sl@0: TUint32* first=NULL; sl@0: for (i=0; i=a.iMap && a.iCheckFirst<=a.iMap+l)); sl@0: } sl@0: sl@0: void TestConstruct(TInt aSize) sl@0: { sl@0: test.Printf(_L("TestConstruct %d\n"),aSize); sl@0: TBitMapAllocator* pA; sl@0: pA=TBitMapAllocator::New(aSize, EFalse); sl@0: test(pA!=NULL); sl@0: test(pA->Avail()==0); sl@0: Check(*pA); sl@0: delete pA; sl@0: pA=TBitMapAllocator::New(aSize, ETrue); sl@0: test(pA!=NULL); sl@0: test(pA->Avail()==aSize); sl@0: Check(*pA); sl@0: delete pA; sl@0: } sl@0: sl@0: void TestAlloc1(TInt aSize) sl@0: { sl@0: test.Printf(_L("TestAlloc1 %d\n"),aSize); sl@0: TBitMapAllocator* pA=TBitMapAllocator::New(aSize, ETrue); sl@0: test(pA!=NULL); sl@0: test(pA->Avail()==aSize); sl@0: Check(*pA); sl@0: TInt i; sl@0: for (i=0; iAlloc(); sl@0: test(r==i); sl@0: test(pA->Avail()==aSize-i-1); sl@0: test(pA->iCheckFirst==pA->iMap+i/32); sl@0: Check(*pA); sl@0: } sl@0: test(pA->Alloc()<0); sl@0: delete pA; sl@0: } sl@0: sl@0: void TestFree1(TInt aSize) sl@0: { sl@0: test.Printf(_L("TestFree1 %d\n"),aSize); sl@0: TBitMapAllocator* pA=TBitMapAllocator::New(aSize, EFalse); sl@0: test(pA!=NULL); sl@0: test(pA->Avail()==0); sl@0: TInt i; sl@0: for (i=aSize-1; i>=0; --i) sl@0: { sl@0: pA->Free(i); sl@0: test(pA->Avail()==aSize-i); sl@0: test(pA->Alloc()==i); sl@0: pA->Free(i); sl@0: test(pA->iCheckFirst==pA->iMap+i/32); sl@0: Check(*pA); sl@0: } sl@0: delete pA; sl@0: } sl@0: sl@0: void TestBlockAlloc(TInt aSize) sl@0: { sl@0: test.Printf(_L("TestBlockAlloc %d\n"),aSize); sl@0: const TInt begin[]={0,1,2,7,16,29,31,32,33,63,64,65,83,128}; sl@0: TBitMapAllocator* pA=TBitMapAllocator::New(aSize, ETrue); sl@0: test(pA!=NULL); sl@0: test(pA->Avail()==aSize); sl@0: pA->Alloc(0,aSize); sl@0: test(pA->Avail()==0); sl@0: Check(*pA); sl@0: pA->Free(0,aSize); sl@0: test(pA->Avail()==aSize); sl@0: Check(*pA); sl@0: TInt i; sl@0: for (i=0; i<(TInt)(sizeof(begin)/sizeof(TInt)); ++i) sl@0: { sl@0: TInt j=begin[i]; sl@0: if (j>aSize) sl@0: break; sl@0: TInt l; sl@0: for (l=1; l<=aSize-j; ++l) sl@0: { sl@0: // test.Printf(_L("j=%d, l=%d, s=%d\n"),j,l,aSize); sl@0: pA->Alloc(j,l); sl@0: test(pA->Avail()==aSize-l); sl@0: test(!pA->NotAllocated(j,l)); sl@0: if (j+lNotAllocated(j,l+1)); sl@0: if (j>0) sl@0: test(pA->NotAllocated(j-1,l)); sl@0: TInt r=pA->Alloc(); sl@0: if (j==0) sl@0: { sl@0: if (lFree(r); sl@0: pA->Free(j,l); sl@0: } sl@0: else if (r>0) sl@0: pA->Free(j,l+1); sl@0: else sl@0: pA->Free(j,l); sl@0: test(pA->Avail()==aSize); sl@0: Check(*pA); sl@0: } sl@0: } sl@0: delete pA; sl@0: } sl@0: sl@0: void TestBlockFree(TInt aSize) sl@0: { sl@0: test.Printf(_L("TestBlockFree %d\n"),aSize); sl@0: const TInt begin[]={0,1,2,7,16,29,31,32,33,63,64,65,83,128}; sl@0: TBitMapAllocator* pA=TBitMapAllocator::New(aSize, EFalse); sl@0: test(pA!=NULL); sl@0: test(pA->Avail()==0); sl@0: TInt i; sl@0: for (i=0; i<(TInt)(sizeof(begin)/sizeof(TInt)); ++i) sl@0: { sl@0: TInt j=begin[i]; sl@0: if (j>aSize) sl@0: break; sl@0: TInt l; sl@0: for (l=1; l<=aSize-j; ++l) sl@0: { sl@0: // test.Printf(_L("j=%d, l=%d, s=%d\n"),j,l,aSize); sl@0: pA->Free(j,l); sl@0: test(pA->Avail()==l); sl@0: test(!pA->NotFree(j,l)); sl@0: if (j+lNotFree(j,l+1)); sl@0: if (j>0) sl@0: test(pA->NotFree(j-1,l)); sl@0: TInt r=pA->Alloc(); sl@0: test(r==j); sl@0: if (l>1) sl@0: pA->Alloc(j+1,l-1); sl@0: test(pA->Avail()==0); sl@0: Check(*pA); sl@0: } sl@0: } sl@0: delete pA; sl@0: } sl@0: sl@0: void TestNotFree(TInt aSize) sl@0: { sl@0: test.Printf(_L("TestNotFree %d\n"),aSize); sl@0: TBitMapAllocator* pA=TBitMapAllocator::New(aSize, ETrue); sl@0: test(pA!=NULL); sl@0: test(pA->Avail()==aSize); sl@0: test(!pA->NotFree(0,aSize)); sl@0: TInt i; sl@0: for (i=0; iAlloc(i,1); sl@0: test(pA->NotFree(0,aSize)); sl@0: TInt j; sl@0: for (j=1; j*j<=i || j*j+i<=aSize; ++j) sl@0: { sl@0: TInt a=Max(i-j*j,0); sl@0: TInt b=Min(i+j*j,aSize); sl@0: test(pA->NotFree(a,b-a)); sl@0: } sl@0: pA->Free(i); sl@0: test(!pA->NotFree(0,aSize)); sl@0: } sl@0: const TInt begin[]={0,1,2,7,16,29,31,32,33,63,64,65,83,128}; sl@0: const TInt size[]={2,3,7,16,23,31,32,33,63,64,65,89,128}; sl@0: const TInt* pB=begin; sl@0: const TInt* pBE=pB+sizeof(begin)/sizeof(TInt); sl@0: const TInt* pS=size; sl@0: const TInt* pSE=pS+sizeof(size)/sizeof(TInt); sl@0: for (; pB=aSize) sl@0: continue; sl@0: for (; pSaSize) sl@0: continue; sl@0: pA->Alloc(b,l); sl@0: TInt j; sl@0: for (j=1; jNotFree(0,j)); sl@0: else sl@0: test(pA->NotFree(0,j)); sl@0: if (aSize-j>=b+l) sl@0: test(!pA->NotFree(aSize-j,j)); sl@0: else sl@0: test(pA->NotFree(aSize-j,j)); sl@0: } sl@0: pA->Free(b,l); sl@0: } sl@0: } sl@0: delete pA; sl@0: } sl@0: sl@0: void TestNotAllocated(TInt aSize) sl@0: { sl@0: test.Printf(_L("TestNotAllocated %d\n"),aSize); sl@0: TBitMapAllocator* pA=TBitMapAllocator::New(aSize, EFalse); sl@0: test(pA!=NULL); sl@0: test(pA->Avail()==0); sl@0: test(!pA->NotAllocated(0,aSize)); sl@0: TInt i; sl@0: for (i=0; iFree(i); sl@0: test(pA->NotAllocated(0,aSize)); sl@0: TInt j; sl@0: for (j=1; j*j<=i || j*j+i<=aSize; ++j) sl@0: { sl@0: TInt a=Max(i-j*j,0); sl@0: TInt b=Min(i+j*j,aSize); sl@0: test(pA->NotAllocated(a,b-a)); sl@0: } sl@0: pA->Alloc(i,1); sl@0: test(!pA->NotAllocated(0,aSize)); sl@0: } sl@0: const TInt begin[]={0,1,2,7,16,29,31,32,33,63,64,65,83,128}; sl@0: const TInt size[]={2,3,7,16,23,31,32,33,63,64,65,89,128}; sl@0: const TInt* pB=begin; sl@0: const TInt* pBE=pB+sizeof(begin)/sizeof(TInt); sl@0: const TInt* pS=size; sl@0: const TInt* pSE=pS+sizeof(size)/sizeof(TInt); sl@0: for (; pB=aSize) sl@0: continue; sl@0: for (; pSaSize) sl@0: continue; sl@0: pA->Free(b,l); sl@0: TInt j; sl@0: for (j=1; jNotAllocated(0,j)); sl@0: else sl@0: test(pA->NotAllocated(0,j)); sl@0: if (aSize-j>=b+l) sl@0: test(!pA->NotAllocated(aSize-j,j)); sl@0: else sl@0: test(pA->NotAllocated(aSize-j,j)); sl@0: } sl@0: pA->Alloc(b,l); sl@0: } sl@0: } sl@0: delete pA; sl@0: } sl@0: sl@0: void TestAllocList(TInt aSize) sl@0: { sl@0: test.Printf(_L("TestAllocList %d\n"),aSize); sl@0: TBitMapAllocator* pA=TBitMapAllocator::New(aSize, EFalse); sl@0: test(pA!=NULL); sl@0: test(pA->Avail()==0); sl@0: TInt i; sl@0: TInt list[256]; sl@0: for (i=0; iFree(i); sl@0: test(pA->AllocList(128,list)==1); sl@0: test(list[0]==i); sl@0: test(pA->Avail()==0); sl@0: } sl@0: TInt j; sl@0: for (i=0; iFree(i); sl@0: pA->Free(j); sl@0: test(pA->AllocList(1,list)==1); sl@0: test(list[0]==i); sl@0: test(pA->Avail()==1); sl@0: pA->Free(i); sl@0: test(pA->AllocList(128,list)==2); sl@0: test(list[0]==i && list[1]==j); sl@0: test(pA->Avail()==0); sl@0: } sl@0: } sl@0: TInt l; sl@0: for (l=1; l<80; ++l) sl@0: { sl@0: if (2*l+1>aSize) sl@0: break; sl@0: for (i=l+1; i<=aSize-l; ++i) sl@0: { sl@0: pA->Free(0,l); sl@0: pA->Free(i,l); sl@0: test(pA->Avail()==2*l); sl@0: TInt l2; sl@0: for (l2=Max(l-1,1); l2<=2*l; ++l2) sl@0: { sl@0: TInt r=pA->AllocList(l2,list); sl@0: // test.Printf(_L("l2=%d r=%d\n"),l2,r); sl@0: test(r==l2); sl@0: for (j=0; jFree(list[j]); sl@0: pA->SelectiveFree(0,l); sl@0: pA->SelectiveFree(i,l); sl@0: test(pA->Avail()==2*l); sl@0: } sl@0: pA->Alloc(0,l); sl@0: pA->Alloc(i,l); sl@0: Check(*pA); sl@0: } sl@0: } sl@0: delete pA; sl@0: } sl@0: sl@0: void TestSelectiveFree(TInt aSize) sl@0: { sl@0: test.Printf(_L("TestSelectiveFree %d\n"),aSize); sl@0: TBitMapAllocator* pA=TBitMapAllocator::New(aSize, ETrue); sl@0: test(pA!=NULL); sl@0: test(pA->Avail()==aSize); sl@0: TInt i; sl@0: TInt j; sl@0: TInt l; sl@0: for (i=2; i<8; ++i) sl@0: { sl@0: for (l=1; l<=aSize; ++l) sl@0: { sl@0: new (pA) TBitMapAllocator(aSize, ETrue); sl@0: for (j=0; jAlloc(j,1); sl@0: TInt orig=pA->Avail(); sl@0: test(orig==aSize-(aSize+i-1)/i); sl@0: pA->SelectiveFree(0,l); sl@0: TInt freed=pA->Avail()-orig; sl@0: test(freed==(l+i-1)/i); sl@0: Check(*pA); sl@0: } sl@0: } sl@0: for (i=0; i<=Min(32,aSize-1); ++i) sl@0: { sl@0: for (l=1; l<=aSize-i; ++l) sl@0: { sl@0: for (j=1; j<=aSize; ++j) sl@0: { sl@0: new (pA) TBitMapAllocator(aSize, ETrue); sl@0: pA->Alloc(i,l); sl@0: test(pA->Avail()==aSize-l); sl@0: pA->SelectiveFree(0,j); sl@0: test(pA->Avail()==aSize-l+Max(0,Min(i+l,j)-i)); sl@0: test(!pA->NotFree(0,j)); sl@0: if (j>=i && jNotFree(0,j+1)); sl@0: Check(*pA); sl@0: } sl@0: } sl@0: } sl@0: delete pA; sl@0: } sl@0: sl@0: TBitMapAllocator* DoSetupBMA(TInt aSize, VA_LIST aList) sl@0: { sl@0: TBitMapAllocator* pA=TBitMapAllocator::New(aSize, EFalse); sl@0: test(pA!=NULL); sl@0: test(pA->Avail()==0); sl@0: TInt totalfree=0; sl@0: FOREVER sl@0: { sl@0: TInt i=VA_ARG(aList,TInt); sl@0: if (i<0) sl@0: break; sl@0: TInt l=VA_ARG(aList,TInt); sl@0: pA->Free(i,l); sl@0: totalfree+=l; sl@0: } sl@0: test(pA->Avail()==totalfree); sl@0: return pA; sl@0: } sl@0: sl@0: TBitMapAllocator* SetupBMA(TInt aSize, ...) sl@0: { sl@0: VA_LIST list; sl@0: VA_START(list,aSize); sl@0: return DoSetupBMA(aSize,list); sl@0: } sl@0: sl@0: void PopulateRangeArray(RArray& aArray, VA_LIST aList) sl@0: { sl@0: aArray.Reset(); sl@0: TInt n=0; sl@0: FOREVER sl@0: { sl@0: SRange rng; sl@0: rng.iBase=VA_ARG(aList,TInt); sl@0: if (rng.iBase<0) sl@0: break; sl@0: rng.iLength=VA_ARG(aList,TInt); sl@0: rng.iLength<<=8; sl@0: rng.iLength+=n; sl@0: ++n; sl@0: test(aArray.Append(rng)==KErrNone); sl@0: } sl@0: } sl@0: sl@0: TInt FirstFitPos(RArray& aArray, TInt aLength) sl@0: { sl@0: TInt c=aArray.Count(); sl@0: SRange* pR=&aArray[0]; sl@0: SRange* pE=pR+c; sl@0: for (; pRiLength>>8; sl@0: if (l>=aLength) sl@0: { sl@0: // test.Printf(_L("FFP %d = %d\n"),aLength,pR->iBase); sl@0: return pR->iBase; sl@0: } sl@0: } sl@0: // test.Printf(_L("FFP %d = -1\n"),aLength); sl@0: return -1; sl@0: } sl@0: sl@0: TInt AlignedFirstFitPos(RArray& aArray, TInt aSize, TInt aLength, TInt aAlign, TInt aBase, TInt aOffset=0, TBool aBestFit=EFalse) sl@0: { sl@0: TInt alignSize=1< pE->iBase + (pE->iLength >> 8)) sl@0: pE++; sl@0: sl@0: for (; pRiLength>>8; sl@0: TInt b=pR->iBase; sl@0: if (aOffset != 0) sl@0: { sl@0: aOffset = ((aOffset + aBase + alignMask) & ~alignMask) - aBase; sl@0: if (aOffset + aLength - 1 >= b + l) sl@0: {// The offset is after the end of this region. sl@0: continue; sl@0: } sl@0: l -= (aOffset <= b)? 0 : aOffset - b; sl@0: b += (aOffset <= b)? 0 : aOffset - b; // Start the search from aOffset sl@0: } sl@0: TInt ab=((b+aBase+alignMask)&~alignMask)-aBase; sl@0: TInt al = l + b - ab; sl@0: if (al >= aLength) sl@0: { sl@0: if (!aBestFit || l == aLength) sl@0: { sl@0: // test.Printf(_L("AFFP %d %d %d = %d\n"),aLength,aAlign,aBase,ab); sl@0: return ab; sl@0: } sl@0: if (!runFound || minRun > l) sl@0: { sl@0: minRun = l; sl@0: minRunStart = ab; sl@0: runFound = ETrue; sl@0: } sl@0: } sl@0: } sl@0: if (runFound) sl@0: { sl@0: return minRunStart; sl@0: } sl@0: // test.Printf(_L("AFFP %d %d %d = -1\n"),aLength,aAlign,aBase); sl@0: return -1; sl@0: } sl@0: sl@0: void DoConsecTest(TInt aSize, ...) sl@0: { sl@0: test.Printf(_L("DoConsecTest %d\n"),aSize); sl@0: VA_LIST list; sl@0: VA_LIST list2; sl@0: VA_START(list,aSize); sl@0: VA_START(list2,aSize); sl@0: TBitMapAllocator* pA=DoSetupBMA(aSize,list2); sl@0: RArray rangeArray(8,_FOFF(SRange,iLength)); sl@0: PopulateRangeArray(rangeArray, list); sl@0: TInt n; sl@0: for (n=1; n<=aSize; ++n) sl@0: { sl@0: TInt r1=pA->AllocConsecutive(n,EFalse); sl@0: TInt r2=FirstFitPos(rangeArray,n); sl@0: // test.Printf(_L("ALC(%d,0) = %d [%d]\n"),n,r1,r2); sl@0: test_Equal(r2, r1); sl@0: } sl@0: rangeArray.SortUnsigned(); // sort array in ascending order of length sl@0: for (n=1; n<=aSize; ++n) sl@0: { sl@0: TInt r1=pA->AllocConsecutive(n,ETrue); sl@0: TInt r2=FirstFitPos(rangeArray,n); sl@0: // test.Printf(_L("ALC(%d,1) = %d [%d]\n"),n,r1,r2); sl@0: test_Equal(r2, r1); sl@0: } sl@0: rangeArray.Close(); sl@0: delete pA; sl@0: } sl@0: sl@0: void DoAlignedTest(TInt aSize, ...) sl@0: { sl@0: test.Printf(_L("DoAlignedTest %d\n"),aSize); sl@0: VA_LIST list; sl@0: VA_LIST list2; sl@0: VA_START(list,aSize); sl@0: VA_START(list2,aSize); sl@0: TBitMapAllocator* pA=DoSetupBMA(aSize,list2); sl@0: RArray rangeArray(8,_FOFF(SRange,iLength)); sl@0: PopulateRangeArray(rangeArray, list); sl@0: TInt finalRunLength = 0; sl@0: SRange& lastRun = rangeArray[rangeArray.Count() - 1]; sl@0: if (lastRun.iBase + (lastRun.iLength>>8) == aSize) sl@0: {// The last run is at the end of the bma. sl@0: finalRunLength = lastRun.iLength >> 8; sl@0: } sl@0: TInt a; sl@0: TInt b; sl@0: TInt n; sl@0: TUint offset; sl@0: for (a=0; ((1<AllocAligned(n,a,b,EFalse, carry, runLength, offset); sl@0: TInt r2=AlignedFirstFitPos(rangeArray,aSize, n,a,b, offset); sl@0: if (r2 < 0 && pA->iSize == pA->iAvail) sl@0: {// Totally empty bmas return KErrOverflow on failure. sl@0: r2 = KErrOverflow; sl@0: } sl@0: // test.Printf(_L("ALA %d %d %d %d 0 = %d [%d]\n"),n,a,b,offset,r1,r2); sl@0: test( (r1<0) || ((r1+b)&alignmask)==0 ); sl@0: test( (r1<0) || !pA->NotFree(r1,n)); sl@0: test( (r1<0) || runLength >= n); sl@0: test_Equal(r2, r1); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: for (a=0; ((1<AllocAligned(n,a,b,ETrue, carry, runLength, offset); sl@0: TInt r2=AlignedFirstFitPos(rangeArray,aSize, n,a,b, offset, ETrue); sl@0: if (pA->iSize == pA->iAvail) sl@0: {// Totally empty bmas return KErrOverflow always on best fit mode. sl@0: r2 = KErrOverflow; sl@0: } sl@0: // test.Printf(_L("ALA %d %d %d 1 = %d [%d]\n"),n,a,b,r1,r2); sl@0: test( (r1<0) || ((r1+b)&alignmask)==0 ); sl@0: test( (r1<0) || !pA->NotFree(r1,n)); sl@0: test( (r1<0) || runLength >= n); sl@0: test_Equal(r2, r1); sl@0: // No carry in so if run found then carry should be zero. sl@0: // If no run found then carry should set to the length of sl@0: // any run at the end of the bma minus the aligned offset. sl@0: TInt lost = 0; sl@0: TInt alignOffset = ((offset + b + alignmask) & ~alignmask) - b; sl@0: if (finalRunLength && offset && lastRun.iBase < alignOffset) sl@0: {// This search had started past the start of the final run sl@0: // so the final run length found will be shorter than its sl@0: // total length. sl@0: if (alignOffset < aSize) sl@0: { sl@0: lost = Min(alignOffset - lastRun.iBase, finalRunLength); sl@0: } sl@0: else // alignedOffset starts past end of bma. sl@0: lost = finalRunLength; sl@0: } sl@0: test((r1>=0 && carry == 0) || carry == finalRunLength - lost); sl@0: offset = (offset)? offset : 1; sl@0: } sl@0: } sl@0: } sl@0: } sl@0: rangeArray.Close(); sl@0: delete pA; sl@0: } sl@0: sl@0: void Clone(TAny* aDest, const TBitMapAllocator* aSrc) sl@0: { sl@0: TInt nmapw=(aSrc->iSize+31)>>5; sl@0: TInt memsz=sizeof(TBitMapAllocator)+(nmapw-1)*sizeof(TUint32); sl@0: Mem::Move(aDest,aSrc,memsz); sl@0: } sl@0: sl@0: void TestAllocConsecutive() sl@0: { sl@0: test.Printf(_L("TestAllocConsecutive\n")); sl@0: DoConsecTest(256, 0,4 , 20,8 , 38,1 , 58,6 , 65,10, 78,16 , 127,72, 222,19 , 244,12 , -1); sl@0: 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, sl@0: 118,19 , 138,23 , 162,47 , 254,1 , -1); sl@0: DoConsecTest(1023, 0,2 , 32,32 , 65,31 , 99,30 , 144,64 , 256,519 , 776,1, 778,245 , -1); sl@0: sl@0: DoAlignedTest(256, 0,4 , 20,8 , 38,1 , 58,6 , 65,10, 78,16 , 127,72, 222,19 , 244,12 , -1); sl@0: 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, sl@0: 118,19 , 138,23 , 162,47 , 254,1 , -1); sl@0: DoAlignedTest(1023, 0,2 , 32,32 , 65,31 , 99,30 , 144,64 , 256,519 , 776,1, 778,245 , -1); sl@0: // Test some completely free bmas sl@0: DoAlignedTest(255, 0,255, -1); sl@0: DoAlignedTest(256, 0,256, -1); sl@0: DoAlignedTest(1023, 0,1023, -1); sl@0: DoAlignedTest(1024, 0,1024, -1); sl@0: } sl@0: sl@0: void DoTestChain(const TBitMapAllocator& aBma, TInt aNumSplits, ...) sl@0: { sl@0: test.Printf(_L("DoTestChain %d %d\n"),aBma.iSize,aNumSplits); sl@0: VA_LIST list; sl@0: VA_START(list,aNumSplits); sl@0: sl@0: TBmaList* pL=TBmaList::New(aBma,aNumSplits,list); sl@0: test(pL!=NULL); sl@0: sl@0: TInt n; sl@0: for (n=1; n<=aBma.iSize; ++n) sl@0: { sl@0: TInt r1=aBma.AllocConsecutive(n,EFalse); sl@0: TInt r2=pL->AllocConsecutiveFF(n); sl@0: // test.Printf(_L("CHAIN C FF %d: r1=%d r2=%d\n"),n,r1,r2); sl@0: test(r1==r2); sl@0: } sl@0: for (n=1; n<=aBma.iSize; ++n) sl@0: { sl@0: TInt r1=aBma.AllocConsecutive(n,ETrue); sl@0: TInt r2=pL->AllocConsecutiveBF(n); sl@0: // test.Printf(_L("CHAIN C BF %d: r1=%d r2=%d\n"),n,r1,r2); sl@0: test(r1==r2); sl@0: } sl@0: sl@0: TInt a; sl@0: for (a=0; ((1<AllocAlignedFF(n,a); sl@0: // test.Printf(_L("CHAIN A FF %d,%d: r1=%d r2=%d\n"),n,a,r1,r2); sl@0: test(r1==r2); sl@0: } sl@0: } sl@0: for (a=0; ((1<AllocAlignedBF(n,a); sl@0: // test.Printf(_L("CHAIN A BF %d,%d: r1=%d r2=%d\n"),n,a,r1,r2); sl@0: test(r1==r2); sl@0: } sl@0: } sl@0: sl@0: delete pL; sl@0: } sl@0: sl@0: void TestChain() sl@0: { sl@0: test.Printf(_L("TestChain\n")); sl@0: TBitMapAllocator* pA; sl@0: pA=SetupBMA(1023, 0,2 , 32,32 , 65,31 , 99,30 , 144,64 , 256,519 , 776,1, 778,245 , -1); sl@0: test(pA!=NULL); sl@0: DoTestChain(*pA, 2, 300, 700); sl@0: DoTestChain(*pA, 3, 64, 301, 702); sl@0: delete pA; sl@0: pA=SetupBMA(512, 0,2 , 20,10 , 32,32 , 65,31 , 144,64 , 399,113 , -1); sl@0: test(pA!=NULL); sl@0: DoTestChain(*pA, 2, 256, 384); sl@0: DoTestChain(*pA, 3, 128, 256, 384); sl@0: DoTestChain(*pA, 3, 80, 208, 384); sl@0: DoTestChain(*pA, 3, 80, 208, 400); sl@0: delete pA; sl@0: } sl@0: sl@0: void TestBitOps() sl@0: { sl@0: test.Next(_L("Bit operations (32 bit)")); sl@0: test(__e32_find_ls1_32(0x00000000)==-1); sl@0: TInt i, j, k; sl@0: TInt count = 0; sl@0: for (i=0; i<=31; ++i) sl@0: test(__e32_find_ls1_32(1u<>bit); sl@0: sl@0: test(__e32_find_ms1_32(y) == 31-bit); sl@0: } sl@0: sl@0: test(__e32_bit_count_32(0)==0); sl@0: test(__e32_bit_count_32(0xffffffff)==32); sl@0: for (i=0; i<32; ++i) sl@0: { sl@0: TUint32 y = 0xffffffffu << i; sl@0: TUint32 z = 0xffffffffu >> i; sl@0: test(__e32_bit_count_32(y) == 32-i); sl@0: test(__e32_bit_count_32(z) == 32-i); sl@0: test(__e32_bit_count_32(~y) == i); sl@0: test(__e32_bit_count_32(~z) == i); sl@0: } sl@0: for (i=0; i<32; ++i) sl@0: for (j=0; j<32; ++j) sl@0: for (k=0; k<32; ++k) sl@0: { sl@0: TUint32 b0 = 1u<>= bit; sl@0: test(__e32_find_ms1_64(y) == 63-bit); sl@0: } sl@0: sl@0: test(__e32_bit_count_64(0)==0); sl@0: test(__e32_bit_count_64(MAKE_TUINT64(0x00000000,0xffffffff))==32); sl@0: test(__e32_bit_count_64(MAKE_TUINT64(0xffffffff,0x00000000))==32); sl@0: test(__e32_bit_count_64(MAKE_TUINT64(0xffffffff,0xffffffff))==64); sl@0: for (i=0; i<64; ++i) sl@0: { sl@0: TUint64 y = MAKE_TUINT64(0xffffffff,0xffffffff); sl@0: TUint64 z = y >> i; sl@0: y <<= i; sl@0: test(__e32_bit_count_64(y) == 64-i); sl@0: test(__e32_bit_count_64(z) == 64-i); sl@0: test(__e32_bit_count_64(~y) == i); sl@0: test(__e32_bit_count_64(~z) == i); sl@0: } sl@0: count = 0; sl@0: for (i=0; i<64; ++i) sl@0: for (j=0; j<64; ++j) sl@0: for (k=0; k<64; ++k) sl@0: { sl@0: TUint64 b0 = 1u; sl@0: TUint64 b1 = 1u; sl@0: TUint64 b2 = 1u; sl@0: b0 <<= i; sl@0: b1 <<= j; sl@0: b2 <<= k; sl@0: TUint64 y = b0 | b1 | b2; sl@0: TUint64 z = ~y; sl@0: TInt n; sl@0: if (i==j && j==k) n=1; sl@0: else if (i==j || j==k || i==k) n=2; sl@0: else n=3; sl@0: test(__e32_bit_count_64(y) == n); sl@0: test(__e32_bit_count_64(z) == 64-n); sl@0: ++count; sl@0: } sl@0: test.Printf(_L("%d iterations done\n"), count); sl@0: for (i=0; i<64; ++i) sl@0: { sl@0: TUint64 y = MAKE_TUINT64(0xaaaaaaaa,0xaaaaaaaa); sl@0: TUint64 z = ~y; sl@0: test(__e32_bit_count_64(y<