diff -r 000000000000 -r a41df078684a kernel/eka/euser/cbase/ub_bma.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/euser/cbase/ub_bma.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,571 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32\euser\cbase\ub_bma.cpp +// +// + +#include "ub_std.h" + +const TInt KBitsPerInt=32; +const TInt KBitsPerIntMask=(KBitsPerInt-1); +const TInt KBitsPerIntShift=5; + + +inline TInt FindLeastSignificantZero(register TUint n) + { + register TInt i=0; + n=~n; + if (n<<16==0) n>>=16, i+=16; + if (n<<24==0) n>>=8, i+=8; + if (n<<28==0) n>>=4, i+=4; + if (n<<30==0) n>>=2, i+=2; + if (n<<31==0) n>>=1, i+=1; + return i; + } + +inline TInt FindLeastSignificantZero(register TUint n, TUint aFrom) + { + n |= ((1<>=16, i+=16; + if (n<<24==0) n>>=8, i+=8; + if (n<<28==0) n>>=4, i+=4; + if (n<<30==0) n>>=2, i+=2; + if (n<<31==0) n>>=1, i+=1; + return i; + } + +inline TInt FindMostSignificantZero(register TUint n) + { + register TInt i=31; + n=~n; + if (n<0x00010000) n<<=16, i-=16; + if (n<0x01000000) n<<=8, i-=8; + if (n<0x10000000) n<<=4, i-=4; + if (n<0x40000000) n<<=2, i-=2; + if (n<0x80000000) n<<=1, i-=1; + return i; + } + +EXPORT_C CBitMapAllocator::CBitMapAllocator(TInt aSize,TInt aLength) +// +// Constructor +// + : iAvail(aSize),iSize(aSize),iLength(aLength) + { + TInt rem=aSize&KBitsPerIntMask; + if (rem) + { + TInt last=(aSize-1)>>KBitsPerIntShift; + iMap[last]=0xFFFFFFFFu<0,Panic(EBmaSizeLessOrEqualToZero)); + TInt sz=((aSize+KBitsPerIntMask)>>KBitsPerIntShift)-1; + return(new(sz*sizeof(TUint)) CBitMapAllocator(aSize,sz+1)); + } + +EXPORT_C CBitMapAllocator *CBitMapAllocator::NewL(TInt aSize) +// +// Create a new bit map allocator. Leave on any error. +// + { + CBitMapAllocator *pA=New(aSize); + User::LeaveIfNull(pA); + return(pA); + } + +EXPORT_C TInt CBitMapAllocator::Alloc() +// +// Allocate the next position. +// + { + if (iAvail) + { + TUint *pS=iMap; + TUint *pE=pS+iLength; + do { + register TUint n=*pS++; + if (n!=0xFFFFFFFFu) + { + iAvail--; + TInt bit=FindLeastSignificantZero(n); + *--pS=n|(1<=0 && aPos>KBitsPerIntShift); + TUint *pE=iMap+iLength; + TInt start=aPos&KBitsPerIntMask; + register TUint n; + if (start) + { + n=*pS++ | ~(0xFFFFFFFFu<pS); + Panic(EBmaInconsistentState); + } + return(KErrNoMemory); + } + +EXPORT_C TInt CBitMapAllocator::AllocFromTopFrom(TInt aPos) +// +// Allocate the next position after aPos. +// + { + __ASSERT_ALWAYS((aPos>=0 && aPos>KBitsPerIntShift); + TInt start=(aPos+1)&KBitsPerIntMask; + register TUint n; + if (start) + { + n=*pE | (0xFFFFFFFFu<pS) + { + n=*--pE; + if (n!=0xFFFFFFFFu) + { +found: + iAvail--; + TInt bit=FindMostSignificantZero(n); + *pE|=(1<0),Panic(EBmaAllocCountNegative)); + TInt initPos; + if (iAvail) + { + TUint *pS=iMap; + TUint *pE=pS+iLength; + register TUint n; + do { + n=*pS++; + if (n!=0xFFFFFFFFu) + goto found; + } while(pS>=bit; + if (n) + { + c=FindLeastSignificantOne(n); + if (aCount=aCount) + { + c=aCount; + if (c=KBitsPerInt) + *pS=0xFFFFFFFFu, c-=KBitsPerInt; + if (c && pSc) bit=c; + *pS |= ~(0xFFFFFFFFu<=0 && anAlignment<32),Panic(EBmaAllAlgnOutOfRange)); + if (iAvail==0) + return KErrNoMemory; + TUint mask; + TInt step; + if (anAlignment>=KBitsPerIntShift) + { + mask=0xFFFFFFFEu; + step=1<<(anAlignment-KBitsPerIntShift); + } + else + { + mask=AlignedSearchMask[anAlignment]; + step=1; + } + TUint *pM=iMap; + TUint *pE=pM+iLength; + do { + register TUint n=*pM | mask; + if (n!=0xFFFFFFFFu) + { + iAvail--; + TInt bit=(mask==0xFFFFFFFEu)?0:FindLeastSignificantZero(n); + *pM |= (1<=0 && anAlignment<32),Panic(EBmaAllAlgnBOutOfRange)); + if (iAvail==0) + return KErrNoMemory; + TInt blocksz=1<=KBitsPerIntShift) + { + mask=0xFFFFFFFEu; + step=1<<(anAlignment-KBitsPerIntShift); + block=0xFFFFFFFFu; + } + else + { + mask=AlignedSearchMask[anAlignment]; + step=1; + block=~(0xFFFFFFFFu<=KBitsPerInt) + { + n=0; + TUint *pS=pM+step; + if (pS<=pE) + { + do n|=*pM++; while(pM=0 && aPos>KBitsPerIntShift); + TUint mask=1<<(aPos&KBitsPerIntMask); + __ASSERT_ALWAYS(!(*pM&mask),Panic(EBmaAllocAtAlreadyAllocated)); + *pM |= mask; + iAvail--; + } + +EXPORT_C void CBitMapAllocator::AllocAt(TInt aPos, TInt aCount) + { + __ASSERT_ALWAYS((aPos>=0 && (aPos+aCount)<=iSize),Panic(EBmaAllocBlkOutOfRange)); + TUint *pM=iMap+(aPos>>KBitsPerIntShift); + TInt c=aPos&KBitsPerIntMask; + TUint m; + if (aCount<(KBitsPerInt-c)) + { + m=~(0xFFFFFFFFu<=KBitsPerInt) + { + if (*pM) + Panic(EBmaAllocBlkNotFree); + *pM++=0xFFFFFFFFu; + c-=KBitsPerInt; + } + if (c) + { + m=0xFFFFFFFFu>>(KBitsPerInt-c); + if (*pM & m) + Panic(EBmaAllocBlkNotFree); + *pM++ |= m; + } + iAvail-=aCount; + } + +EXPORT_C TInt CBitMapAllocator::ExtractRamPages(TInt aConsecutive,TInt& aPageNo) + { + if(iAvail iSize) + return KErrNoMemory; + if(IsFree(pos,aConsecutive)) + { + AllocAt(pos,aConsecutive); + aPageNo=pos; + return KErrNone; + } + else + { + x = bit+2; + } + } + while (x < KBitsPerInt); + } + } while(pS=0 && aPos>KBitsPerIntShift]; + return !(n>>(aPos&KBitsPerIntMask)&1); + } + +EXPORT_C TBool CBitMapAllocator::IsFree(TInt aPos, TInt aCount) + { + __ASSERT_ALWAYS((aPos>=0 && (aPos+aCount)<=iSize),Panic(EBmaChkBlkOutOfRange)); + TUint *pM=iMap+(aPos>>KBitsPerIntShift); + TUint m=*pM++; + TInt c=aPos&KBitsPerIntMask; + m>>=c; + if (aCount<(KBitsPerInt-c)) + { + return !(m&~(0xFFFFFFFFu<=KBitsPerInt) + { + m |= *pM++; + aCount-=KBitsPerInt; + } + if (aCount) + { + m|=(*pM<<(KBitsPerInt-aCount)); + } + return(!m); + } + +EXPORT_C void CBitMapAllocator::Free(TInt aPos) +// +// Free a position. +// + { + __ASSERT_ALWAYS(aPos>=0 && aPos>KBitsPerIntShift); + TUint mask=1<<(aPos&KBitsPerIntMask); + __ASSERT_ALWAYS((*pM&mask),Panic(EBmaFreeNotAllocated)); + *pM &= ~mask; + iAvail++; + } + +EXPORT_C void CBitMapAllocator::Free(TInt aPos, TInt aCount) + { + __ASSERT_ALWAYS((aPos>=0 && (aPos+aCount)<=iSize),Panic(EBmaFreeBlkOutOfRange)); + TUint *pM=iMap+(aPos>>KBitsPerIntShift); + TInt c=aPos&KBitsPerIntMask; + TUint m; + if (aCount<(KBitsPerInt-c)) + { + m=~(0xFFFFFFFFu<=KBitsPerInt) + { + if (*pM!=0xFFFFFFFF) + Panic(EBmaFreeBlkNotAllocated); + *pM++=0; + c-=KBitsPerInt; + } + if (c) + { + m=0xFFFFFFFFu>>(KBitsPerInt-c); + if ((*pM & m)!=m) + Panic(EBmaFreeBlkNotAllocated); + *pM++ &= ~m; + } + iAvail+=aCount; + } + +EXPORT_C TInt CBitMapAllocator::Avail() +// +// Get the available blocks count. +// + { + return(iAvail); + } + +EXPORT_C TInt CBitMapAllocator::Size() +// +// Get the size of all available blocks. +// + { + return(iSize); + } +