webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp
branchRCL_3
changeset 49 919f36ff910f
parent 48 79859ed3eea9
--- a/webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp	Tue Aug 31 16:17:46 2010 +0300
+++ b/webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp	Wed Sep 01 12:28:30 2010 +0100
@@ -26,8 +26,13 @@
 #include "StopScheduler.h"
 #include "fast_malloc.h"
 #include "SymbianDlHeap.h"
-#include <oommonitorsession.h>
+#include <OOMMonitorSession.h>
 #include <hal.h>
+#include <avkon.hrh>
+#include <avkon.rsg>
+#include <StringLoader.h>
+#include <WebKit.rsg>
+#include "MemoryLogger.h"
 
 // CONSTANTS
 
@@ -77,6 +82,10 @@
     TInt idx = iStoppers.Find( aStopper );
     if( idx != KErrNotFound )
         iStoppers.Remove( idx );
+    
+    if(iStoppers.Count() == 0 && iStopScheduler->IsActive()) // cancel stop if nobody is interested
+        iStopScheduler->Cancel();
+        
     }
 
 //-----------------------------------------------------------------------------
@@ -128,6 +137,7 @@
 //-----------------------------------------------------------------------------
 void CMemoryPool::CollectMemory(TUint aSize)
     {
+    MEM_LOG("CMemoryPool::CollectMemory - run");
     if( iIsCollecting ) return;
 
     iIsCollecting = ETrue;
@@ -135,11 +145,9 @@
       {
         iCollectors[i]->Collect(aSize);
       }
-
-    User::CompressAllHeaps();
     iIsCollecting = EFalse;
 	
-	if (iStopScheduler)
+	if (iStopScheduler && !iIsStopping )
 		iStopScheduler->Start( CStopScheduler::ECheckMemory, aSize );
     }
 
@@ -219,6 +227,20 @@
   }
 
 //-----------------------------------------------------------------------------
+// CMemoryPool::InitOOMDialog()
+//-----------------------------------------------------------------------------
+void CMemoryPool::InitOOMDialog()
+    {
+    }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::ResetOOMDialog()
+//-----------------------------------------------------------------------------
+void CMemoryPool::ResetOOMDialog()
+    {
+    }
+
+//-----------------------------------------------------------------------------
 // CPlainAllocator::DoAlloc
 //-----------------------------------------------------------------------------
 TUint CFastMemoryPool::FreeMemory(TFreeMem& aFree )
@@ -449,11 +471,19 @@
 //-----------------------------------------------------------------------------
 // CNewSymbianHeapPool::FreeMemory
 //-----------------------------------------------------------------------------
-TUint CNewSymbianHeapPool::FreeMemory(TFreeMem& /*aFree*/ )
+TUint CNewSymbianHeapPool::FreeMemory(TFreeMem& aFree )
     {
     // TODO: implement free_memory
-    return KMaxTUint;
-//    return free_memory( aFree.iPool, aFree.iHeap, aFree.iHal );
+    aFree.iPool = 0;
+    aFree.iHeap = 0;
+    
+    TInt freeRAM; 
+    if(HAL::Get(HALData::EMemoryRAMFree, freeRAM) == KErrNone) 
+        aFree.iHal = freeRAM;
+    else
+        aFree.iHal = 0;
+    
+    return KMaxTUint; // not fully implemented
     }
 
 //-----------------------------------------------------------------------------
@@ -461,7 +491,18 @@
 //-----------------------------------------------------------------------------
 TAny* CNewSymbianHeapPool::DoAlloc( TUint aSize )
     {
-    return iAlloc->Alloc( aSize );
+    TAny *p = iAlloc->Alloc( aSize );
+    if(iAlloc->isLowSystemMemory && p) // use this a pre OOM indicator
+        {
+        if(iStopScheduler) iStopScheduler->Start( CStopScheduler::ECheckMemory, 0 );                
+        iAlloc->isLowSystemMemory = 0; // reset so that we don't check before next request for RAM
+        }
+        
+    if (!p) {
+        ShowOOMDialog();
+        MEM_LOG("CNewSymbianHeapPool::DoAlloc - failed");
+    }
+    return p;
     }
 
 //-----------------------------------------------------------------------------
@@ -473,10 +514,16 @@
     iMemStatus &= ~ERescueOOM;
 
     TAny* p = iAlloc->ReAlloc( aPtr, aSize );
-    
+    if(iAlloc->isLowSystemMemory && p) // use this a pre OOM indicator
+        {
+        if(iStopScheduler) iStopScheduler->Start( CStopScheduler::ECheckMemory, 0 );                
+        iAlloc->isLowSystemMemory = 0; // reset so that we don't check before next request for RAM
+        }
+
     // check memory manager status
     if( !p || iMemStatus & ERescueOOM )
         {
+        ShowOOMDialog();
         if( !iIsCollecting )
             {
             CollectMemory();
@@ -488,6 +535,11 @@
         NotifyAndStop();
         }
 
+#ifdef OOM_LOGGING    
+    if(!p)
+        MEM_LOG("CNewSymbianHeapPool::ReAllocate - failed");
+#endif
+
     return p;
     }
 
@@ -551,7 +603,8 @@
 	if(req > 0)
 		return ETrue;
 	
-	// We haven't got the required amount free yet, try the browser heap.
+    // We haven't got the required amount free yet, pop an OOM dialog and then try the browser heap.
+    ShowOOMDialog();
 	CollectMemory(aTotalSize);
 	// ask the system how much is free now...
 	HAL::Get(HALData::EMemoryRAMFree, systemFreeMemory);
@@ -562,6 +615,11 @@
 		{
 		iMemStatus |= ECheckOOM;
 		NotifyAndStop();
+
+#ifdef OOM_LOGGING		
+		MEM_LOG("CNewSymbianHeapPool::PreCheck - failed !!");
+		DumpHeapLogs(aTotalSize);
+#endif		
 		return EFalse;
 		}
 	
@@ -610,6 +668,9 @@
 
 CNewSymbianHeapPool::CNewSymbianHeapPool() : CMemoryPool()
 	{
+    isInitted = EFalse;
+    iOOMErrorDialog = 0;
+    iOOMMessage = 0;
 	}
 
 CNewSymbianHeapPool::~CNewSymbianHeapPool()
@@ -621,7 +682,7 @@
 	}
 
 #ifdef __WINSCW__
-const TInt KMaxHeapSize = 0x2000000; // 32MB, on emulator
+const TInt KMaxHeapSize = 0x1000000; // 32MB, on emulator
 #else
 const TInt KMaxHeapSize = 0x4000000; // 64MB, on hardware
 #endif
@@ -663,10 +724,61 @@
 	return CMemoryPool::Create();
 	}
 
+/*
+ * Initialize the OOM dialog and localized message resource
+ * This should be called as soon in the startup process as possible
+ * (unfortunately it can't be called until resources are already loaded)
+ * Note: apps are responsible for showing their own oom dialog; there
+ * is no system one AFAIK; at least we can re-use the oom localized
+ * resource message from elsewhere
+ */
+void CNewSymbianHeapPool::InitOOMDialog()
+    {
+    if (!isInitted)
+        {
+        isInitted = ETrue;
+        iOOMErrorDialog = CAknGlobalNote::NewL();
+        iOOMErrorDialog->SetSoftkeys(R_AVKON_SOFTKEYS_OK_EMPTY);
+        iOOMMessage = StringLoader::LoadL(R_QTN_BROWSER_DIALOG_OOM);
+        iOOMDisplayed = EFalse;
+        }
+    }
+
+void CNewSymbianHeapPool::ShowOOMDialog()
+    {
+    MEM_LOG("CNewSymbianHeapPool::ShowOOMDialog - called");
+    
+    // Don't show it if we did once already
+    if (iOOMDisplayed)
+        return;
+
+    // If we got OOM, show a dialog (if the dialog was initted properly to begin with)
+    if (iOOMErrorDialog)
+        {
+        // If we couldn't load the message resource when we first initted, 
+        // try again now; this shouldn't ever happen
+        if (!iOOMMessage)
+            {
+            iOOMMessage = StringLoader::LoadL(R_QTN_BROWSER_DIALOG_OOM);
+            }
+        // If we have no dialog or message we unfortunately cannot display it!
+        if (iOOMMessage) 
+            {
+            iOOMErrorDialog->ShowNoteL(EAknGlobalWarningNote,iOOMMessage->Des());
+            iOOMDisplayed = ETrue;
+            }
+        }
+    }
+
+void CNewSymbianHeapPool::ResetOOMDialog()
+    {
+    iOOMDisplayed = EFalse;
+    }
+
 #ifdef OOM_LOGGING   
-void CNewSymbianHeapPool::DumpHeapLogs()
+void CNewSymbianHeapPool::DumpHeapLogs(TInt aFailSize)
     {
-    iAlloc->dump_heap_logs(0);
+    iAlloc->dump_heap_logs(aFailSize);
     iAlloc->dump_dl_free_chunks();
     }
 #endif