servicediscoveryandcontrol/pnp/test/upnp/chunkmgr/src/rchunkpool.cpp
changeset 0 f5a58ecadc66
--- /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 ();
+	}
+
+