--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/servicediscoveryandcontrol/pnp/test/upnp/chunkmgr/src/rchunkpool.cpp Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,141 @@
+// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// @file
+// @internalComponent
+//
+//
+
+#include <e32base.h>
+#include "cchunkmanager.h"
+#include "rmemcell.h"
+#include "cmemchunk.h"
+#include "rchunkpool.h"
+
+
+RChunkPool::RChunkPool ( TInt aBlockSize, TInt aThresholdValue, TInt aMinGrowth, CChunkManager& aChunkManager )
+ : iBlockSize ( aBlockSize ),
+ iChunkManager ( aChunkManager ),
+ iThresholdValue ( aThresholdValue ),
+ iMinGrowth ( aMinGrowth )
+ {
+ iFreeBlocks.Init ();
+ iFreeSpace = 0;
+ }
+
+RChunkPool::RChunkPool ( CChunkManager& aChunkManager, TInt aBlockSize )
+ : iBlockSize ( aBlockSize ),
+ iChunkManager ( aChunkManager )
+ {
+ }
+
+void RChunkPool::OpenL ()
+ {
+ User::LeaveIfError ( iFreeListLock.CreateLocal () );
+ }
+
+void RChunkPool::Close ()
+ {
+ iFreeListLock.Close ();
+ iAllocatedChunks.Close ();
+ }
+
+TInt RChunkPool::Compare ( const RChunkPool& aLHSPool, const RChunkPool& aRHSPool )
+ {
+ if ( aLHSPool.BlockSize () < aRHSPool.BlockSize () )
+ {
+ return -1;
+ }
+ else if ( aLHSPool.BlockSize () > aRHSPool.BlockSize () )
+ {
+ return 1;
+ }
+ return 0;
+ }
+
+void RChunkPool::AppendToFreeList ( CMemChunk* aChunk )
+ {
+ iFreeSpace += iBlockSize * aChunk->NumBlocks ();
+ iFreeBlocks.Append ( aChunk->List () );
+ }
+
+
+// transfer's blocks from free list and makes self growth if necessary
+TInt RChunkPool::Alloc ( RMemCellList& aList, TInt aSize )
+ {
+ // Lock the freelist so that
+ // Transfer of free blocks will be an atomic operation
+ iFreeListLock.Wait ();
+
+ TInt bytesTransfered = iFreeBlocks.Transfer ( aList, aSize );
+ iFreeSpace -= bytesTransfered;
+
+ TInt freeHeapSpace = iChunkManager.BytesAvailable ();
+
+ if ( freeHeapSpace ) // makes sure that heap has memory atleast for CMemChunk object, but not for its chunk
+ {
+ // check if freeblocks is down the threshold value and make self growth if necessary
+ // determine min number of blocks to allocate
+ TInt minGrowth = iThresholdValue - ( iFreeSpace / iBlockSize );
+
+ if ( minGrowth >= 0 )
+ {
+ if ( GrowPool ( iMinGrowth ) == KErrNoMemory )
+ {
+ // unable to grow the minimum value set by the client
+ if ( minGrowth < iMinGrowth )
+ {
+ // so, now try with the min value adjusted with threshold value
+ GrowPool ( minGrowth );
+ }
+ }
+ }
+ }
+
+ // free the freelistlock
+ iFreeListLock.Signal ();
+
+ return bytesTransfered;
+ }
+
+TInt RChunkPool::GrowPool ( TUint aNumBlocks )
+ {
+ return iChunkManager.AllocChunk ( *this, aNumBlocks );
+ }
+
+TInt RChunkPool::GrowAndAlloc ( RMemCellList& aList, TInt aSize, TInt aNumBlocks )
+ {
+ // Lock the freelist so that
+ // Transfer of free blocks will be an atomic operation
+ TInt bytesTransfered = 0;
+ iFreeListLock.Wait ();
+
+ if ( GrowPool ( aNumBlocks ) != KErrNoMemory )
+ {
+ bytesTransfered = iFreeBlocks.Transfer ( aList, aSize );
+ iFreeSpace -= bytesTransfered;
+ }
+
+ // free the freelistlock
+ iFreeListLock.Signal ();
+
+ return bytesTransfered;
+ }
+
+void RChunkPool::FreeToPool ( RMemCell* aMemCell )
+ {
+ iFreeBlocks.Append ( aMemCell );
+ iFreeSpace += aMemCell->Size ();
+ }
+
+