webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp
changeset 0 dd21522fd290
child 1 7c90e6132015
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,428 @@
+/*
+* Copyright (c) 2006 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:  
+*
+*
+*/
+
+
+// INCLUDES
+
+#include <e32base.h>
+#include <e32std.h>
+#include <e32hal.h>
+#include "MemoryPool.h"
+#include "StopScheduler.h"
+#include "fast_malloc.h"
+#include <OOMMonitorSession.h>
+
+// CONSTANTS
+
+// CLASS DECLARATIONS
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::AddCollector
+//-----------------------------------------------------------------------------
+void CMemoryPool::AddCollector( MMemoryCollector* aCollector )
+    {
+    // sort the collectors according to their priorities
+    TInt i;
+    for( i=0; i<iCollectors.Count(); ++i )
+      {
+      if( aCollector->Priority() <= iCollectors[i]->Priority() ) break;
+      }
+
+    iCollectors.Insert( aCollector, i );
+    }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::RemoveCollector
+//-----------------------------------------------------------------------------
+void CMemoryPool::RemoveCollector( MMemoryCollector* aCollector )
+    {
+    TInt idx = iCollectors.Find( aCollector );
+    if( idx != KErrNotFound )
+        iCollectors.Remove( idx );
+    }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::AddStopper
+//-----------------------------------------------------------------------------
+void CMemoryPool::AddStopper( MOOMStopper* aStopper )
+    {
+    if( !iStopScheduler )
+        iStopScheduler = new CStopScheduler(*this);
+    iStoppers.Append( aStopper );
+    }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::RemoveStopper
+//-----------------------------------------------------------------------------
+void CMemoryPool::RemoveStopper( MOOMStopper* aStopper )
+    {
+	if( !iStopScheduler ) return;
+    TInt idx = iStoppers.Find( aStopper );
+    if( idx != KErrNotFound )
+        iStoppers.Remove( idx );
+    }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::SetNotifier
+//-----------------------------------------------------------------------------
+void CMemoryPool::SetNotifier( MOOMNotifier* aNotifier )
+    {
+    iNotifier = aNotifier;
+    }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::Create()
+//-----------------------------------------------------------------------------
+TBool CMemoryPool::Create()
+    {
+    iNestedChecks = 0;
+
+    iCollectors.Reset();
+    iIsStopping = EFalse;
+    iIsCollecting = EFalse;
+    iMemStatus = ENoOOM;
+
+    // stop scheduler
+    iStopScheduler = 0;
+    iNotifier = 0;
+
+    return ETrue;
+    }
+
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::SetStopping
+//-----------------------------------------------------------------------------
+void CMemoryPool::SetStopping( TBool aStopping )
+    {
+    iIsStopping = aStopping;
+    // all operations are stopped, must have some memory available
+    if( !iIsStopping ) iMemStatus = ENoOOM;
+
+    // notify the client when stopping is done
+    if( !aStopping && iNotifier )
+        {
+        iNotifier->Notify();
+        }
+    }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::CollectMemory
+//-----------------------------------------------------------------------------
+void CMemoryPool::CollectMemory(TUint aSize)
+    {
+    if( iIsCollecting ) return;
+
+    iIsCollecting = ETrue;
+    for( TInt i=0; i<iCollectors.Count(); ++i )
+      {
+        iCollectors[i]->Collect(aSize);
+      }
+
+    User::CompressAllHeaps();
+    iIsCollecting = EFalse;
+	
+	if (iStopScheduler)
+		iStopScheduler->Start( CStopScheduler::ECheckMemory, aSize );
+    }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::RestoreCollectors
+//-----------------------------------------------------------------------------
+void CMemoryPool::RestoreCollectors( TOOMPriority aPriority )
+  {
+  if( iIsCollecting ) return;
+
+    for( TInt i=0; i<iCollectors.Count(); ++i )
+      {
+        if( iCollectors[i]->Priority() >= aPriority )
+            iCollectors[i]->Restore();
+      }
+  }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::~CMemoryPool
+//-----------------------------------------------------------------------------
+CMemoryPool::~CMemoryPool()
+    {
+    iCollectors.Reset();
+    iStoppers.Reset();
+    delete iStopScheduler;
+
+    // NOTE: remove this when UI spec has OOM notifier defined
+    delete iNotifier;
+    }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::AllocFromPool
+//-----------------------------------------------------------------------------
+TAny* CMemoryPool::AllocFromPool( TUint aSize )
+    {
+    // reset the status for next allocation
+    iMemStatus &= ~ERescueOOM;
+
+    TAny *p = DoAlloc( aSize );
+
+    // check memory manager status
+    if( !p || iMemStatus & ERescueOOM )
+        {
+        if( !iIsCollecting )
+            {
+            CollectMemory();
+            }
+
+        if( !p )
+            p = DoAlloc( aSize );
+
+        NotifyAndStop();
+        }
+
+    return p;
+    }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::SetStatus
+//-----------------------------------------------------------------------------
+void CMemoryPool::SetStatus( TOOMCheckResult aType )
+    {
+    iMemStatus |= aType;
+    }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::NotifyAndStop()
+//-----------------------------------------------------------------------------
+void CMemoryPool::NotifyAndStop()
+  {
+  if( !iIsStopping )
+    {
+        iIsStopping = ETrue;
+		if (iStopScheduler)
+			iStopScheduler->Start( CStopScheduler::EStopLoading, 0 );
+    }
+  }
+
+//-----------------------------------------------------------------------------
+// CPlainAllocator::DoAlloc
+//-----------------------------------------------------------------------------
+TUint CFastMemoryPool::FreeMemory(TFreeMem& aFree )
+    {
+    return free_memory( aFree.iPool, aFree.iHeap, aFree.iHal );
+    }
+
+//-----------------------------------------------------------------------------
+// CFastMemoryPool::DoAlloc
+//-----------------------------------------------------------------------------
+TAny* CFastMemoryPool::DoAlloc( TUint aSize )
+    {
+    return fast_malloc( aSize );
+    }
+
+//-----------------------------------------------------------------------------
+// CFastMemoryPool::ReAllocate
+//-----------------------------------------------------------------------------
+TAny* CFastMemoryPool::ReAllocate( TAny* aPtr, TUint aSize )
+    {
+    // reset the status for next allocation
+    iMemStatus &= ~ERescueOOM;
+
+    TAny* p = fast_realloc( aPtr, aSize );
+
+    // check memory manager status
+    if( !p || iMemStatus & ERescueOOM )
+        {
+        if( !iIsCollecting )
+            {
+            CollectMemory();
+            }
+
+        if( !p )
+            p = fast_realloc( aPtr, aSize );
+
+        NotifyAndStop();
+        }
+
+    return p;
+    }
+
+//-----------------------------------------------------------------------------
+// CFastMemoryPool::PreCheck
+//-----------------------------------------------------------------------------
+TBool CFastMemoryPool::PreCheck( TUint aTotalSize, TUint aMaxBufSize, const TDesC8& /*aCheckerName*/ )
+    {
+    // avoid small checkings
+    if( aTotalSize < 1024 ) return ETrue;
+
+    if( !fast_pre_check( aTotalSize, aMaxBufSize ) )
+        {
+        CollectMemory(aTotalSize);
+        ROomMonitorSession oomMs;
+        if ( oomMs.Connect() == KErrNone ) {
+            oomMs.RequestFreeMemory( aTotalSize );
+            oomMs.Close();
+        }
+        if( !fast_pre_check( aTotalSize, aMaxBufSize ) )
+            {
+            iMemStatus |= ECheckOOM;
+            NotifyAndStop();
+            return EFalse;
+            }
+        }
+
+    return ETrue;
+    }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::PostCheck
+//-----------------------------------------------------------------------------
+TUint CFastMemoryPool::PostCheck()
+    {
+    fast_post_check();
+    return iMemStatus;
+    }
+
+//-----------------------------------------------------------------------------
+// CPlainAllocator::Free
+//-----------------------------------------------------------------------------
+void CFastMemoryPool::Free( TAny* aPtr )
+    {
+    return fast_free( aPtr );
+    }
+
+//-----------------------------------------------------------------------------
+// CPlainAllocator::MemorySize
+//-----------------------------------------------------------------------------
+TUint CFastMemoryPool::MemorySize( TAny* aPtr )
+    {
+    return fast_malloc_size( aPtr );
+    }
+
+//-----------------------------------------------------------------------------
+// CPlainAllocator::SetRescueBufferSize
+//-----------------------------------------------------------------------------
+void CFastMemoryPool::SetRescueBufferSize( TInt aSize )
+    {
+    fast_set_rescue_buffer_size( aSize );
+    }
+
+void CFastMemoryPool::RestoreRescueBuffer()
+    {
+    alloc_rescue_buffer();
+    }
+
+//-----------------------------------------------------------------------------
+// CDefaultMemoryPool::~CDefaultMemoryPool
+//-----------------------------------------------------------------------------
+CDefaultMemoryPool::~CDefaultMemoryPool()
+    {
+    }
+
+//-----------------------------------------------------------------------------
+// CDefaultMemoryPool::DoAlloc
+//-----------------------------------------------------------------------------
+TAny* CDefaultMemoryPool::DoAlloc(TUint aSize)
+    {
+    return User::Alloc( aSize );
+    }
+
+//-----------------------------------------------------------------------------
+// CDefaultMemoryPool::ReAllocate
+//-----------------------------------------------------------------------------
+TAny* CDefaultMemoryPool::ReAllocate( TAny* aPtr, TUint aSize )
+    {   
+    return User::ReAlloc( aPtr, aSize );
+    }
+
+//-----------------------------------------------------------------------------
+// CDefaultMemoryPool::FreeMemory
+//-----------------------------------------------------------------------------
+TUint CDefaultMemoryPool::FreeMemory(TFreeMem& /*aFree*/)
+    {
+    // free memory in Hal
+    TMemoryInfoV1Buf info;
+    UserHal::MemoryInfo( info );
+    return info().iFreeRamInBytes;
+    }
+
+//-----------------------------------------------------------------------------
+// CDefaultMemoryPool::Free
+//-----------------------------------------------------------------------------
+void CDefaultMemoryPool::Free(TAny* aPtr)
+    {
+    User::Free( aPtr );
+    }
+
+//-----------------------------------------------------------------------------
+// CDefaultMemoryPool::MemorySize
+//-----------------------------------------------------------------------------
+TUint CDefaultMemoryPool::MemorySize(TAny* aPtr)
+    {
+    return User::AllocLen( aPtr );
+    }
+
+//-----------------------------------------------------------------------------
+// CDefaultMemoryPool::SetRescueBufferSize
+//-----------------------------------------------------------------------------
+void CDefaultMemoryPool::SetRescueBufferSize( TInt aSize )
+    {
+    iRescueBufferSize = aSize;
+    }
+
+//-----------------------------------------------------------------------------
+// CDefaultMemoryPool::PreCheck
+//-----------------------------------------------------------------------------
+TBool CDefaultMemoryPool::PreCheck( TUint aTotalSize, TUint /*aMaxBufSize*/, const TDesC8& /*aCheckerName*/ )
+    {
+    // avoid small checkings
+    if( aTotalSize < 1024 ) return ETrue;
+
+    // free memory in Hal
+    TMemoryInfoV1Buf info;
+    UserHal::MemoryInfo( info );
+    TInt sizeNeeded = aTotalSize + iRescueBufferSize;
+    if( sizeNeeded > info().iFreeRamInBytes )
+        {
+        CollectMemory(sizeNeeded);
+        
+        // check memory again
+        UserHal::MemoryInfo( info );
+
+        if(sizeNeeded > info().iFreeRamInBytes ) 
+            {
+            NotifyAndStop();
+            iMemStatus |= ECheckOOM;
+            return EFalse;
+            }
+        }
+
+    return ETrue;
+    }
+
+//-----------------------------------------------------------------------------
+// CDefaultMemoryPool::PostCheck
+//-----------------------------------------------------------------------------
+TUint CDefaultMemoryPool::PostCheck()
+    {
+    return iMemStatus;
+    }
+
+void CDefaultMemoryPool::RestoreRescueBuffer()
+    {
+    // do nothing here.
+    }
+
+// END OF FILE