uiacceltk/hitchcock/goommonitor/src/goommemorymonitor.cpp
branchRCL_3
changeset 3 d8a3531bc6b8
parent 0 15bf7259bb7c
child 5 433cbbb6a04b
--- a/uiacceltk/hitchcock/goommonitor/src/goommemorymonitor.cpp	Tue Feb 02 07:56:43 2010 +0200
+++ b/uiacceltk/hitchcock/goommonitor/src/goommemorymonitor.cpp	Mon Feb 22 17:57:49 2010 +0200
@@ -48,6 +48,8 @@
 #include "goomthresholdcrossedao.inl"
 #endif
 
+const TInt KGoomWaitTimeToSynch = 1000000;
+
 // ======================================================================
 // class CMemoryMonitor
 // ======================================================================
@@ -81,6 +83,8 @@
 CMemoryMonitor::~CMemoryMonitor()
     {
     FUNC_LOG;
+    
+    delete iSynchTimer;
 
     delete iServer;
     delete iWservEventReceiver;
@@ -184,6 +188,8 @@
     
     iWservEventReceiver = new(ELeave) CWservEventReceiver(*this, iWs);
     iWservEventReceiver->ConstructL();
+    
+    iSynchTimer = CGOomSynchTimer::NewL(*this);
     }
 
 const CGOomGlobalConfig& CMemoryMonitor::GlobalConfig()
@@ -202,30 +208,37 @@
     FUNC_LOG;
     // keep only one notification active at a moment
 #ifdef USE_ASYNCYH_NOTIFICATIONS 
-    if (aThreshold == EGL_PROF_TOTAL_MEMORY_USAGE_GT_NOK)
-        {
-        TRACES("FreeMemThresholdCrossedL : EGL_PROF_TOTAL_MEMORY_USAGE_GT_NOK");
-        iMemAllocationsGrowing->Stop();
-        iMemAllocationsGoingDown->Continue();
-        }
-    else
-        {
-        TRACES("FreeMemThresholdCrossedL : EGL_PROF_TOTAL_MEMORY_USAGE_LT_NOK");
-        iMemAllocationsGrowing->Continue();
-        iMemAllocationsGoingDown->Stop();            
-        }    
-#endif
-
-    StartFreeSomeRamL(iGoodThreshold);
+   
     if (aThreshold == EGL_PROF_TOTAL_MEMORY_USAGE_LT_NOK)
         {
         TInt current = GetFreeMemory();
         if(current >= iGoodThreshold  && (!NeedToPostponeMemGood()))
             {
-            TRACES("FreeMemThresholdCrossedL : calling MemoryGOOD");
+            TRACES2("FreeMemThresholdCrossedL : crossed good threshold Free %d, GThresh %d, Calling MemoryGood",current, iGoodThreshold);
             iGOomActionList->MemoryGood();
+            iMemAllocationsGrowing->Continue();
+            iMemAllocationsGoingDown->Stop();
+            return;
+            }
+        else
+            {
+            TRACES3("FreeMemThresholdCrossedL : Not Calling MemoryGOOD. Free %d, GThresh %d, Handshakepending = %d",current, iGoodThreshold, NeedToPostponeMemGood()?1:0);
+            //if we remain in low mem mode, we have to wait for the same trigger i.e. free mem crossing good threshold
+            
+            if(NeedToPostponeMemGood()) //if handshake pending
+                iMemAllocationsGoingDown->Stop();   //Stop till handhsake is complete. It will be made to continue from DoPostponedMemoryGood
+            else
+                iMemAllocationsGoingDown->Continue();
             }
         }
+    else//if aThreshold == EGL_PROF_TOTAL_MEMORY_USAGE_GT_NOK
+        {
+        TRACES1("FreeMemThresholdCrossedL : crossed low threshold %d", iLowThreshold);
+        iMemAllocationsGrowing->Stop();
+        iMemAllocationsGoingDown->Continue();
+        StartFreeSomeRamL(iGoodThreshold, EGOomThresholdCrossed);
+        }
+#endif
     }
 
 void CMemoryMonitor::HandleFocusedWgChangeL(TInt aForegroundAppUid)
@@ -244,20 +257,10 @@
     RefreshThresholds(aForegroundAppUid);
     // Not very elegant, now we poll on each window group change
     // Should have better trigger e.g. from window server 
-#ifndef USE_ASYNCYH_NOTIFICATIONS  
-    TInt current = GetFreeMemory();
-    if (current < iLowThreshold)
-        {
-        StartFreeSomeRamL(iGoodThreshold);
-        }  
-    else if(current >= iGoodThreshold)
-        {
-        iGOomActionList->MemoryGood();
-        }
-#endif
+	StartFreeSomeRamL(iCurrentTarget, EGOomFocusChanged);
      }
 
-void CMemoryMonitor::StartFreeSomeRamL(TInt aTargetFree, TInt aMaxPriority) // The maximum priority of action to run
+void CMemoryMonitor::StartFreeSomeRamL(TInt aTargetFree, TInt aMaxPriority, TGOomTrigger aTrigger) // The maximum priority of action to run
     {
     FUNC_LOG;
 
@@ -299,8 +302,10 @@
     //iGOomActionList->SetCurrentTarget(aTargetFree);
     iGOomActionList->SetCurrentTarget(iCurrentTarget);
 
+    iTrigger = aTrigger;
     // Run the memory freeing actions
     iGOomActionList->FreeMemory(aMaxPriority);
+    
     }
 
 void CMemoryMonitor::RunCloseAppActions(TInt aMaxPriority)
@@ -317,18 +322,18 @@
 // of applications, and each will be given a timeout of KAPPEXITTIMEOUT.
 // ---------------------------------------------------------
 //
-void CMemoryMonitor::StartFreeSomeRamL(TInt aTargetFree)
+void CMemoryMonitor::StartFreeSomeRamL(TInt aTargetFree, TGOomTrigger aTrigger)
     {
     FUNC_LOG;
 
-    StartFreeSomeRamL(aTargetFree, KGOomPriorityInfinate - 1);
+    StartFreeSomeRamL(aTargetFree, KGOomPriorityInfinate - 1, aTrigger);
     }
 
 void CMemoryMonitor::RequestFreeMemoryL(TInt aTargetFree, TBool aUseAbsolute)
     {
     FUNC_LOG;
 
-    StartFreeSomeRamL(aUseAbsolute?aTargetFree:(aTargetFree + iLowThreshold), KGOomPriorityInfinate - 1);
+    StartFreeSomeRamL(aUseAbsolute?aTargetFree:(aTargetFree + iLowThreshold), KGOomPriorityInfinate - 1, EGOomRequestMemory);
     }
 
 void CMemoryMonitor::FreeOptionalRamL(TInt aTargetFree, TInt aPluginId, TBool aUseAbsolute) // The ID of the plugin that will clear up the allocation, used to determine the priority of the allocation
@@ -337,7 +342,7 @@
 
     // Calculate the priority of the allocation (the priority of the plugin that will clear it up - 1)
     TInt priorityOfAllocation = iConfig->GetPluginConfig(aPluginId).CalculatePluginPriority(*iGOomWindowGroupList) - 1;
-    StartFreeSomeRamL(aUseAbsolute?aTargetFree:(aTargetFree + iGoodThreshold), priorityOfAllocation);
+    StartFreeSomeRamL(aUseAbsolute?aTargetFree:(aTargetFree + iGoodThreshold), priorityOfAllocation, EGOomRequestMemory);
     }
 
 // Does the EGL extension return the amount of memory in bits?
@@ -469,26 +474,52 @@
 void CMemoryMonitor::SetPriorityBusy(TInt aWgId)
     {
     FUNC_LOG;
+    TRACES2("Received SetPriorityBusy for appid = %x, wgid = %d", iGOomWindowGroupList->AppIdfromWgId(aWgId, ETrue), aWgId);
     
-    TRACES2("Received SetPriorityBusy for appid = %x, wgid = %d", iGOomWindowGroupList->AppIdfromWgId(aWgId, ETrue), aWgId);
-    iGOomWindowGroupList->SetPriorityBusy(aWgId);
-    AppClosePriorityChanged(aWgId, RGOomMonitorSession::EGOomPriorityBusy);
+    RArray<TInt> WgIdList;
+    iGOomWindowGroupList->GetAllWgIdsMatchingAppId(aWgId, WgIdList);
+        
+    TInt i = WgIdList.Count();
+    while(i--)
+        {
+        iGOomWindowGroupList->SetPriorityBusy(WgIdList[i]);
+        if(iGOomActionList->IsRunningKillAppActions())  //this may be too late as killing of apps has already begun, but we might still be able to save the app 
+            AppClosePriorityChanged(WgIdList[i], RGOomMonitorSession::EGOomPriorityBusy);
+        }
     }
 
 void CMemoryMonitor::SetPriorityNormal(TInt aWgId)
     {
     FUNC_LOG;
-
-    iGOomWindowGroupList->SetPriorityNormal(aWgId);
-    AppClosePriorityChanged(aWgId, RGOomMonitorSession::EGOomPriorityNormal);
+    TRACES2("Received SetPriorityBusy for appid = %x, wgid = %d", iGOomWindowGroupList->AppIdfromWgId(aWgId, ETrue), aWgId);
+    
+    RArray<TInt> WgIdList;
+    iGOomWindowGroupList->GetAllWgIdsMatchingAppId(aWgId, WgIdList);
+        
+    TInt i = WgIdList.Count();
+    while(i--)
+        {
+        iGOomWindowGroupList->SetPriorityNormal(WgIdList[i]);
+        if(iGOomActionList->IsRunningKillAppActions())
+            AppClosePriorityChanged(WgIdList[i], RGOomMonitorSession::EGOomPriorityNormal);
+        }
     }
 
 void CMemoryMonitor::SetPriorityHigh(TInt aWgId)
     {
     FUNC_LOG;
+    TRACES2("Received SetPriorityBusy for appid = %x, wgid = %d", iGOomWindowGroupList->AppIdfromWgId(aWgId, ETrue), aWgId);
     
-    iGOomWindowGroupList->SetPriorityHigh(aWgId);
-    AppClosePriorityChanged(aWgId, RGOomMonitorSession::EGOomPriorityHigh);
+    RArray<TInt> WgIdList;
+    iGOomWindowGroupList->GetAllWgIdsMatchingAppId(aWgId, WgIdList);
+        
+    TInt i = WgIdList.Count();
+    while(i--)
+        {    
+        iGOomWindowGroupList->SetPriorityHigh(WgIdList[i]);
+        if(iGOomActionList->IsRunningKillAppActions())
+            AppClosePriorityChanged(WgIdList[i], RGOomMonitorSession::EGOomPriorityHigh);
+        }
     }
 
 TInt CMemoryMonitor::GetFreeMemory()
@@ -586,14 +617,24 @@
     {
     FUNC_LOG;
     TInt current = GetFreeMemory();
-    if(current >= iGoodThreshold  && (!NeedToPostponeMemGood()))
+    if(current >= iGoodThreshold)
         {
-        TRACES("DoPostponedMemoryGood calling MemoryGOOD");
-        iGOomActionList->MemoryGood();
+        if(!NeedToPostponeMemGood())
+            {
+            TRACES("DoPostponedMemoryGood calling MemoryGOOD");
+            iGOomActionList->MemoryGood();
+            }
+        else
+            {
+            iMemAllocationsGoingDown->Continue();
+            }
         }
+    else
+        {
+        iMemAllocationsGoingDown->Continue();
+        }   
     }    
 
-
 void CMemoryMonitor::AppClosePriorityChanged(TInt aWgId, TInt aPriority)
     {
     FUNC_LOG;
@@ -615,19 +656,21 @@
         appCloseConfig = iConfig->GetApplicationConfig(aWgId).GetAppCloseConfig();
         TRACES("CMemoryMonitor::AppClosePriorityChanged NORMAL");
     }
-        
+    
+    if(!appCloseConfig)
+        {
+        appCloseConfig = iConfig->GetApplicationConfig(KGOomDefaultAppId).GetAppCloseConfig();
+        }
+    
     if (appCloseConfig)
         {  
-        TInt32 appId = iGOomWindowGroupList->AppIdfromWgId(aWgId, ETrue);
-        TInt wgIndex=iGOomWindowGroupList->GetIndexFromAppId(appId);
-        
-        TRACES2("CMemoryMonitor::AppClosePriorityChanged wgindex %d, appid %x", wgIndex, appId);
+        TInt wgIndex=iGOomWindowGroupList->GetIndexFromWgId(aWgId);
         
         if(wgIndex>=0)
             {
-            TRACES2("CMemoryMonitor::AppClosePriorityChanged Setting Priority for app %x, wgid %d", appId, aWgId);
+            TRACES2("CMemoryMonitor::AppClosePriorityChanged Setting Priority for app %x, wgid %d", iGOomWindowGroupList->AppIdfromWgId(aWgId, ETrue), aWgId);
             TUint priority = appCloseConfig->CalculateCloseAppPriority(*iGOomWindowGroupList, wgIndex);
-            iGOomActionList->SetPriority(wgIndex, priority);
+            iGOomActionList->SetPriority(aWgId, priority);
             }
         else
             {
@@ -644,3 +687,105 @@
 {
     return iGOomWindowGroupList; 
 }
+
+TBool CMemoryMonitor::IsSafeToProcessNewRequest(TUint aClientId)
+    {
+    FUNC_LOG;
+    if(iActiveClientId == aClientId)
+        {
+        TRACES1("Repeated Request from %x", aClientId);
+        return EFalse;
+        }
+    
+    TUint currrentPluginRun = iGOomActionList->CurrentPluginRun();
+    if(currrentPluginRun)
+        {
+        if(iConfig->GetApplicationConfig(aClientId).iSkipPluginId == currrentPluginRun)
+            {
+            TRACES2("Request from %x cannot be served now as plugin %x is running", aClientId, currrentPluginRun);
+            return EFalse;
+            }
+        }
+    
+    TRACES1("Going to process new request %d",iPostponeMemGood);
+    return ETrue;
+    }
+
+void CMemoryMonitor::WaitAndSynchroniseMemoryState() //this will be called after freeing memory
+    {
+    FUNC_LOG;
+    
+    switch (iTrigger)
+        {
+        case EGOomThresholdCrossed:
+            {
+            //Call memory good if we are good.
+            DoPostponedMemoryGood();
+            break;
+            }
+        case EGOomFocusChanged:
+        case EGOomRequestMemory:
+            {
+            //start timer
+            //cancel timer if end critical allocations request
+            //end critical allocations when timer expires
+            if ( iSynchTimer && //exists
+                 !iSynchTimer->IsActive() ) // keep it simple
+                {                
+	        iSynchTimer->After(KGoomWaitTimeToSynch);
+                }
+            break;
+            }
+        }
+    }
+
+void CMemoryMonitor::SynchroniseMemoryState()
+    {
+    FUNC_LOG;
+    TInt current = GetFreeMemory();
+    if(current >= iGoodThreshold)
+        {
+        if(!NeedToPostponeMemGood())
+            {
+            TRACES("SynchroniseMemoryState calling MemoryGOOD");
+            iGOomActionList->MemoryGood();
+            }
+        else
+            {
+            iMemAllocationsGoingDown->Continue();
+            }
+        }
+    else if(current < iLowThreshold)
+        {
+        iMemAllocationsGrowing->Stop();
+        iMemAllocationsGoingDown->Continue();
+        }
+    else
+        {
+        iMemAllocationsGrowing->Continue();
+        iMemAllocationsGoingDown->Continue();
+        }
+    }
+    
+    
+CGOomSynchTimer* CGOomSynchTimer::NewL(CMemoryMonitor& aMonitor)
+    {
+    CGOomSynchTimer* self = new (ELeave) CGOomSynchTimer(aMonitor);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CGOomSynchTimer::CGOomSynchTimer(CMemoryMonitor& aMonitor) : CTimer(EPriorityStandard), iMonitor(aMonitor)
+    {
+    CActiveScheduler::Add(this);
+    }
+    
+void CGOomSynchTimer::RunL()
+    {
+    FUNC_LOG;
+    iMonitor.SynchroniseMemoryState();
+    }
+
+