sysresmonitoring/oommonitor/src/oommemorymonitor.cpp
branchRCL_3
changeset 82 4610cd70c542
parent 63 c2c61fdca848
equal deleted inserted replaced
70:739cef680932 82:4610cd70c542
     1 /*
     1 /*
     2 * Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies). 
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
    15 *
    15 *
    16 */
    16 */
    17 
    17 
    18 
    18 
    19 #include <hal.h>
    19 #include <hal.h>
    20 
       
    21 
    20 
    22 #include <UikonInternalPSKeys.h>
    21 #include <UikonInternalPSKeys.h>
    23 
    22 
    24 #include "oommemorymonitor.h"
    23 #include "oommemorymonitor.h"
    25 #include "oommonitorplugin.h"
    24 #include "oommonitorplugin.h"
   161     iWatchdogStatusSubscriber = new (ELeave) CSubscribeHelper(TCallBack(WatchdogStatusStatusChanged, this), iWatchdogStatusProperty);
   160     iWatchdogStatusSubscriber = new (ELeave) CSubscribeHelper(TCallBack(WatchdogStatusStatusChanged, this), iWatchdogStatusProperty);
   162     iWatchdogStatusSubscriber->Subscribe();
   161     iWatchdogStatusSubscriber->Subscribe();
   163 #endif
   162 #endif
   164     
   163     
   165     
   164     
   166     iOOMWatcher = COutOfMemoryWatcher::NewL(*this, iLowRamThreshold, iGoodRamThreshold, iConfig->GlobalConfig().iSwapUsageMonitored, iLowSwapThreshold, iGoodSwapThreshold);
   165     iOOMWatcher = COutOfMemoryWatcher::NewL(*this, iLowThreshold, iGoodThreshold);
   167     iOOMWatcher->Start();
   166     iOOMWatcher->Start();
   168 
   167 
   169     iWservEventReceiver = new(ELeave) CWservEventReceiver(*this, iWs);
   168     iWservEventReceiver = new(ELeave) CWservEventReceiver(*this, iWs);
   170     iWservEventReceiver->ConstructL();
   169     iWservEventReceiver->ConstructL();
   171     }
   170     }
   184 void CMemoryMonitor::FreeMemThresholdCrossedL()
   183 void CMemoryMonitor::FreeMemThresholdCrossedL()
   185     {
   184     {
   186     FUNC_LOG;
   185     FUNC_LOG;
   187 
   186 
   188     iActionTrigger = ERamRotation;
   187     iActionTrigger = ERamRotation;
   189     StartFreeSomeRamL(iGoodRamThreshold, iGoodSwapThreshold);
   188     StartFreeSomeRamL(iGoodThreshold);
   190     }
   189     }
   191 
   190 
   192 void CMemoryMonitor::HandleFocusedWgChangeL()
   191 void CMemoryMonitor::HandleFocusedWgChangeL()
   193     {
   192     {
   194     FUNC_LOG;
   193     FUNC_LOG;
   195 
   194 
   196     TInt oldGoodRamThreshold = iGoodRamThreshold;
   195     TInt oldGoodThreshold = iGoodThreshold;
   197     TInt oldLowRamThreshold = iLowRamThreshold;
   196     TInt oldLowThreshold = iLowThreshold;
   198     TInt oldGoodSwapThreshold = iGoodSwapThreshold;
   197     
   199     TInt oldLowSwapThreshold = iLowSwapThreshold;
       
   200         
       
   201     // Refresh the low and good memory thresholds as they may have changed due to the new foreground application
   198     // Refresh the low and good memory thresholds as they may have changed due to the new foreground application
   202     RefreshThresholds();
   199     RefreshThresholds();
   203        
   200        
   204     if ((oldGoodRamThreshold != iGoodRamThreshold)
   201     if ((oldGoodThreshold != iGoodThreshold)
   205             || (oldLowRamThreshold != iLowRamThreshold)
   202             || (oldLowThreshold != iLowThreshold))
   206             || (oldGoodSwapThreshold != iGoodSwapThreshold)
       
   207             || (oldLowSwapThreshold != iLowSwapThreshold))
       
   208         // If the thresholds have changed then update the memory watched
   203         // If the thresholds have changed then update the memory watched
   209         {
   204         {
   210         iOOMWatcher->UpdateThresholds(iLowRamThreshold, iGoodRamThreshold, iLowSwapThreshold, iGoodSwapThreshold);
   205         iOOMWatcher->UpdateThresholds(iLowThreshold, iGoodThreshold);
   211         }
   206         }
   212     
   207     
   213     // If the available memory is less than the low memory threshold then free some RAM
   208     // If the available memory is less than the low memory threshold then free some RAM
   214     User::CompressAllHeaps();
   209     User::CompressAllHeaps();
   215     TInt currentFreeRam = 0;
   210     TInt current = 0;
   216     HAL::Get( HALData::EMemoryRAMFree, currentFreeRam );
   211     HAL::Get( HALData::EMemoryRAMFree, current );
   217 	TInt currentFreeSwap = 0;
   212     
   218 	if (iConfig->GlobalConfig().iSwapUsageMonitored)
   213     if (current < iLowThreshold)
   219 		{
       
   220         SVMSwapInfo swapInfo;
       
   221 		UserSvr::HalFunction(EHalGroupVM, EVMHalGetSwapInfo, &swapInfo, 0);
       
   222 		currentFreeSwap = swapInfo.iSwapFree;
       
   223 		}
       
   224     
       
   225     if ((currentFreeRam < iLowRamThreshold) ||
       
   226 		(iConfig->GlobalConfig().iSwapUsageMonitored && (currentFreeSwap < iLowSwapThreshold)))
       
   227         {
   214         {
   228         iActionTrigger = ERamRotation;
   215         iActionTrigger = ERamRotation;
   229         StartFreeSomeRamL(iGoodRamThreshold, iGoodSwapThreshold);
   216         StartFreeSomeRamL(iGoodThreshold);
   230         }
   217         }
   231     }
   218     }
   232 
   219 
   233 void CMemoryMonitor::StartFreeSomeRamL(TInt aFreeRamTarget, TInt aFreeSwapTarget)
   220 void CMemoryMonitor::StartFreeSomeRamL(TInt aTargetFree)
   234     {
   221     {
   235     StartFreeSomeRamL(aFreeRamTarget, aFreeSwapTarget, KOomPriorityInfinate - 1);
   222     StartFreeSomeRamL(aTargetFree, KOomPriorityInfinate - 1);
   236     }
   223     }
   237 
   224 
   238 void CMemoryMonitor::StartFreeSomeRamL(TInt aFreeRamTarget, TInt aFreeSwapTarget, TInt aMaxPriority) // The maximum priority of action to run
   225 void CMemoryMonitor::StartFreeSomeRamL(TInt aTargetFree, TInt aMaxPriority) // The maximum priority of action to run
   239     {
   226     {
   240     FUNC_LOG;
   227     FUNC_LOG;
   241 
   228 
   242     TRACES4("MemoryMonitor::StartFreeSomeRamL: aFreeRamTarget = %d, iCurrentRamTarget = %d, aFreeSwapSpaceTarget = %d, iCurrentSwapTarget = %d", aFreeRamTarget, iCurrentRamTarget, aFreeSwapTarget, iCurrentSwapTarget);
   229     TRACES2("MemoryMonitor::StartFreeSomeRamL: aTargetFree = %d, iCurrentTarget = %d", aTargetFree, iCurrentTarget);
   243     
   230     
   244     // Update the target if new target is higher. If the target is lower than the current target and memory 
   231     // Update the target if new target is higher. If the target is lower than the current target and memory 
   245     // is currently being freed then we do not want to reduce the amount of memory this operation frees.
   232     // is currently being freed then we do not want to reduce the amount of memory this operation frees.
   246     if (aFreeRamTarget > iCurrentRamTarget)
   233     if (aTargetFree > iCurrentTarget)
   247         {
   234         iCurrentTarget = aTargetFree;
   248         iCurrentRamTarget = aFreeRamTarget;
       
   249         }
       
   250     
       
   251     if (aFreeSwapTarget > iCurrentSwapTarget)
       
   252         {
       
   253         iCurrentSwapTarget = aFreeSwapTarget;
       
   254         }
       
   255 
   235 
   256     // check if there is enough free memory already.
   236     // check if there is enough free memory already.
   257     TInt freeMemory = 0;
   237     TInt freeMemory;
   258     GetFreeMemory(freeMemory);
   238     GetFreeMemory(freeMemory);
   259     TInt freeSwap = 0;
   239 
   260     if (iConfig->GlobalConfig().iSwapUsageMonitored)
   240     TRACES1("MemoryMonitor::StartFreeSomeRamL, freeMemory = %d", freeMemory);
   261         {
   241     
   262         GetFreeSwapSpace(freeSwap);
   242     if (freeMemory >= iCurrentTarget)
   263         }
       
   264 
       
   265     TRACES2("MemoryMonitor::StartFreeSomeRamL, freeMemory = %d, freeSwap = %d", freeMemory, freeSwap);
       
   266     
       
   267     if ((freeMemory >= iCurrentRamTarget) &&
       
   268         ((!iConfig->GlobalConfig().iSwapUsageMonitored) || (freeSwap >= iCurrentSwapTarget)))
       
   269         {
   243         {
   270         if (iLastMemoryMonitorStatusProperty != EFreeingMemory)
   244         if (iLastMemoryMonitorStatusProperty != EFreeingMemory)
   271             {
   245             {
   272         ResetTargets();
   246         ResetTargets();
   273         iOomActionList->SwitchOffPlugins();
   247         iOomActionList->SwitchOffPlugins();
   286 #endif
   260 #endif
   287 	
   261 	
   288     // Build the list of memory freeing actions
   262     // Build the list of memory freeing actions
   289     iOomActionList->BuildActionListL(*iOomWindowGroupList, *iConfig);
   263     iOomActionList->BuildActionListL(*iOomWindowGroupList, *iConfig);
   290     
   264     
   291 	iOomActionList->SetCurrentTargets(iCurrentRamTarget, iCurrentSwapTarget);
   265     iOomActionList->SetCurrentTarget(iCurrentTarget);
   292     
   266     
   293     // Run the memory freeing actions
   267     // Run the memory freeing actions
   294     iOomActionList->FreeMemory(aMaxPriority);
   268     iOomActionList->FreeMemory(aMaxPriority);
   295     }
   269     }
   296 
   270 
   297 void CMemoryMonitor::RequestFreeMemoryPandSL(TInt aBytesRequested)
   271 void CMemoryMonitor::RequestFreeMemoryPandSL(TInt aBytesRequested)
   298     {
   272     {
   299     FUNC_LOG;
   273     FUNC_LOG;
   300     
   274     
   301     iActionTrigger = EPublishAndSubscribe;
   275     iActionTrigger = EPublishAndSubscribe;
   302     StartFreeSomeRamL(aBytesRequested + iLowRamThreshold, iLowSwapThreshold);
   276     StartFreeSomeRamL(aBytesRequested + iLowThreshold);
   303     }
   277     }
   304 
   278 
   305 void CMemoryMonitor::RequestFreeMemoryL(TInt aBytesRequested, TBool aDataPaged)
   279 void CMemoryMonitor::RequestFreeMemoryL(TInt aBytesRequested)
   306     {
   280     {
   307     FUNC_LOG;
   281     FUNC_LOG;
   308     
   282     
   309     iActionTrigger = EClientServerRequestFreeMemory;
   283     iActionTrigger = EClientServerRequestFreeMemory;
   310     iDataPaged = aDataPaged;
   284     StartFreeSomeRamL(aBytesRequested + iLowThreshold);
   311     StartFreeSomeRamL(iLowRamThreshold, aBytesRequested + iLowSwapThreshold);
   285     }
   312     }
   286 
   313 
   287 void CMemoryMonitor::FreeOptionalRamL(TInt aBytesRequested, TInt aPluginId) // The ID of the plugin that will clear up the allocation, used to determine the priority of the allocation
   314 void CMemoryMonitor::FreeOptionalRamL(TInt aBytesRequested, TInt aPluginId, TBool aDataPaged) // The ID of the plugin that will clear up the allocation, used to determine the priority of the allocation
       
   315     {
   288     {
   316     FUNC_LOG;
   289     FUNC_LOG;
   317     
   290     
   318     iActionTrigger = EClientServerRequestOptionalRam;
   291     iActionTrigger = EClientServerRequestOptionalRam;
   319 
   292 
   320     iDataPaged = aDataPaged;
       
   321        
       
   322     // Calculate the priority of the allocation (the priority of the plugin that will clear it up - 1)
   293     // Calculate the priority of the allocation (the priority of the plugin that will clear it up - 1)
   323     TInt priorityOfAllocation = iConfig->GetPluginConfig(aPluginId).CalculatePluginPriority(*iOomWindowGroupList) - 1;
   294     TInt priorityOfAllocation = iConfig->GetPluginConfig(aPluginId).CalculatePluginPriority(*iOomWindowGroupList) - 1;
   324    
   295    
   325     StartFreeSomeRamL(aBytesRequested + iGoodRamThreshold, iLowSwapThreshold, priorityOfAllocation);
   296     StartFreeSomeRamL(aBytesRequested + iGoodThreshold, priorityOfAllocation);
   326     }
   297     }
   327 
   298 
   328 void CMemoryMonitor::GetFreeMemory(TInt& aCurrentFreeMemory)
   299 void CMemoryMonitor::GetFreeMemory(TInt& aCurrentFreeMemory)
   329     {
   300     {
   330     FUNC_LOG;
   301     FUNC_LOG;
   333     User::CompressAllHeaps();
   304     User::CompressAllHeaps();
   334 
   305 
   335     HAL::Get( HALData::EMemoryRAMFree, aCurrentFreeMemory );
   306     HAL::Get( HALData::EMemoryRAMFree, aCurrentFreeMemory );
   336 
   307 
   337     TRACES1("CMemoryMonitor::GetFreeMemory: Free RAM now %d", aCurrentFreeMemory);
   308     TRACES1("CMemoryMonitor::GetFreeMemory: Free RAM now %d", aCurrentFreeMemory);
   338     }
       
   339 
       
   340 void CMemoryMonitor::GetFreeSwapSpace(TInt& aCurrentFreeSwapSpace)
       
   341     {
       
   342     FUNC_LOG;
       
   343     
       
   344     SVMSwapInfo swapInfo;
       
   345     UserSvr::HalFunction(EHalGroupVM, EVMHalGetSwapInfo, &swapInfo, 0);
       
   346     aCurrentFreeSwapSpace = swapInfo.iSwapFree;
       
   347         
       
   348     TRACES1("CMemoryMonitor::GetFreeSwapSpace: Free swap space now %d", aCurrentFreeSwapSpace);
       
   349     }
   309     }
   350 
   310 
   351 #ifndef CLIENT_REQUEST_QUEUE 
   311 #ifndef CLIENT_REQUEST_QUEUE 
   352 TInt CMemoryMonitor::WatchdogStatusStatusChanged(TAny* aPtr)
   312 TInt CMemoryMonitor::WatchdogStatusStatusChanged(TAny* aPtr)
   353     {
   313     {
   396     FUNC_LOG;
   356     FUNC_LOG;
   397 
   357 
   398     iOomWindowGroupList->Refresh();
   358     iOomWindowGroupList->Refresh();
   399     
   359     
   400     // Calculate the desired good threshold, this could be the globally configured value...
   360     // Calculate the desired good threshold, this could be the globally configured value...
   401     iGoodRamThreshold = CMemoryMonitor::GlobalConfig().iGoodRamThreshold;
   361     iGoodThreshold = CMemoryMonitor::GlobalConfig().iGoodRamThreshold;
   402     iLowRamThreshold = CMemoryMonitor::GlobalConfig().iLowRamThreshold;
   362     iLowThreshold = CMemoryMonitor::GlobalConfig().iLowRamThreshold;
   403     iGoodSwapThreshold = CMemoryMonitor::GlobalConfig().iGoodSwapThreshold;
   363     TRACES2("CMemoryMonitor::RefreshThresholds: Global Good Threshold = %d, Global Low Threshold = %d", iGoodThreshold, iLowThreshold);
   404     iLowSwapThreshold = CMemoryMonitor::GlobalConfig().iLowSwapThreshold;
       
   405     TRACES4("CMemoryMonitor::RefreshThresholds: Global Good Ram Threshold = %d, Global Low Ram Threshold = %d, Global Good Swap Threshold = %d, Global Low Swap Threshold = %d", iGoodRamThreshold, iLowRamThreshold, iGoodSwapThreshold, iLowSwapThreshold);
       
   406 
   364 
   407 #ifdef _DEBUG
   365 #ifdef _DEBUG
   408     TRACES("CMemoryMonitor::RefreshThresholds: Dumping Window Group List");
   366     TRACES("CMemoryMonitor::RefreshThresholds: Dumping Window Group List");
   409     TInt wgIndex = iOomWindowGroupList->Count() - 1;
   367     TInt wgIndex = iOomWindowGroupList->Count() - 1;
   410     while (wgIndex >= 0)        
   368     while (wgIndex >= 0)        
   433             }
   391             }
   434 
   392 
   435         // If this application configuration overrides the good_ram_threshold then set it
   393         // If this application configuration overrides the good_ram_threshold then set it
   436         if (iConfig->GetApplicationConfig(foregroundAppId).iGoodRamThreshold != KOomThresholdUnset)
   394         if (iConfig->GetApplicationConfig(foregroundAppId).iGoodRamThreshold != KOomThresholdUnset)
   437             {
   395             {
   438             iGoodRamThreshold = iConfig->GetApplicationConfig(foregroundAppId).iGoodRamThreshold;
   396             iGoodThreshold = iConfig->GetApplicationConfig(foregroundAppId).iGoodRamThreshold;
   439             TRACES2("CMemoryMonitor::RefreshThresholds: For foreground app %x, Good Ram Threshold = %d", foregroundAppId, iGoodRamThreshold);
   397             TRACES2("CMemoryMonitor::RefreshThresholds: For foreground app %x, Good Threshold = %d", foregroundAppId, iGoodThreshold);
   440             }
   398             }
   441         // If this application configuration overrides the low_ram_threshold then set it
   399         // If this application configuration overrides the low_ram_threshold then set it
   442         if (iConfig->GetApplicationConfig(foregroundAppId).iLowRamThreshold != KOomThresholdUnset)
   400         if (iConfig->GetApplicationConfig(foregroundAppId).iLowRamThreshold != KOomThresholdUnset)
   443             {
   401             {
   444             iLowRamThreshold = iConfig->GetApplicationConfig(foregroundAppId).iLowRamThreshold;
   402             iLowThreshold = iConfig->GetApplicationConfig(foregroundAppId).iLowRamThreshold;
   445             TRACES2("CMemoryMonitor::RefreshThresholds: For foreground app %x, Low Ram Threshold = %d", foregroundAppId, iLowRamThreshold);
   403             TRACES2("CMemoryMonitor::RefreshThresholds: For foreground app %x, Low Threshold = %d", foregroundAppId, iLowThreshold);
   446             }
   404             }
   447 
   405 
   448         if (iConfig->GetApplicationConfig(foregroundAppId).iGoodSwapThreshold != KOomThresholdUnset)
       
   449             {
       
   450             iGoodSwapThreshold = iConfig->GetApplicationConfig(foregroundAppId).iGoodSwapThreshold;
       
   451             TRACES2("CMemoryMonitor::RefreshThresholds: For foreground app %x, Good Swap Threshold = %d", foregroundAppId, iGoodSwapThreshold);
       
   452             }
       
   453         // If this application configuration overrides the low_swap_threshold then set it
       
   454         if (iConfig->GetApplicationConfig(foregroundAppId).iLowSwapThreshold != KOomThresholdUnset)
       
   455             {
       
   456             iLowSwapThreshold = iConfig->GetApplicationConfig(foregroundAppId).iLowSwapThreshold;
       
   457             TRACES2("CMemoryMonitor::RefreshThresholds: For foreground app %x, Low Swap Threshold = %d", foregroundAppId, iLowSwapThreshold);
       
   458             }
       
   459         }
   406         }
   460     }
   407     }
   461 
   408 
   462 // SetMemoryMonitorStatusProperty - updates the property value only if it has changed
   409 // SetMemoryMonitorStatusProperty - updates the property value only if it has changed
   463 void CMemoryMonitor::SetMemoryMonitorStatusProperty(const TMemoryMonitorStatusPropertyValues aValue)
   410 void CMemoryMonitor::SetMemoryMonitorStatusProperty(const TMemoryMonitorStatusPropertyValues aValue)
   474     {
   421     {
   475     FUNC_LOG;
   422     FUNC_LOG;
   476 
   423 
   477     //we reset the target when a memory free operation completes, to deal with the case 
   424     //we reset the target when a memory free operation completes, to deal with the case 
   478     //where the operation was initiated with a target larger than the current good threshold
   425     //where the operation was initiated with a target larger than the current good threshold
   479     iCurrentRamTarget = iGoodRamThreshold;
   426     iCurrentTarget = iGoodThreshold;
   480     iCurrentSwapTarget = iGoodSwapThreshold;
   427     iOomActionList->SetCurrentTarget(iCurrentTarget);   
   481     iOomActionList->SetCurrentTargets(iCurrentRamTarget, iCurrentSwapTarget);
       
   482     }
   428     }
   483 
   429 
   484 void CMemoryMonitor::SetPriorityBusy(TInt aWgId)
   430 void CMemoryMonitor::SetPriorityBusy(TInt aWgId)
   485     {
   431     {
   486     FUNC_LOG;
   432     FUNC_LOG;
   504     {
   450     {
   505     return iActionTrigger;
   451     return iActionTrigger;
   506     }
   452     }
   507 
   453 
   508 #ifdef CLIENT_REQUEST_QUEUE 
   454 #ifdef CLIENT_REQUEST_QUEUE 
   509 TInt CMemoryMonitor::GoodRamThreshold() const
   455 TInt CMemoryMonitor::GoodThreshold() const
   510     {
   456     {
   511     return iGoodRamThreshold;
   457     return iGoodThreshold;
   512     }
   458     }
   513 
   459 
   514 TInt CMemoryMonitor::LowRamThreshold() const
   460 TInt CMemoryMonitor::LowThreshold() const
   515     {
   461     {
   516     return iLowRamThreshold;
   462     return iLowThreshold;
   517     }
   463     }
   518 
   464 
   519 void CMemoryMonitor::ActionsCompleted(TInt aBytesFree, TBool aMemoryGood)
   465 void CMemoryMonitor::ActionsCompleted(TInt aBytesFree, TBool aMemoryGood)
   520     {
   466     {
   521     iQueue->ActionsCompleted(aBytesFree, aMemoryGood);
   467     iQueue->ActionsCompleted(aBytesFree, aMemoryGood);