windowing/windowserver/nonnga/SERVER/WsMemMgr.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "WsMemMgr.h"
       
    17 #include "inifile.h"
       
    18 #include "panics.h"
       
    19 #include "wstop.h"
       
    20 
       
    21 CWsMemoryManager * CWsMemoryManager::iStatic = NULL;
       
    22 
       
    23 CWsMemoryManager * CWsMemoryManager::Static()
       
    24 	{
       
    25 	return iStatic;
       
    26 	}
       
    27 
       
    28 CWsMemoryManager * CWsMemoryManager::NewLC()
       
    29 	{
       
    30 	CWsMemoryManager * self = new (ELeave) CWsMemoryManager;
       
    31 	CleanupStack::PushL(self);
       
    32 	self->ConstructL();
       
    33 	iStatic = self;
       
    34 	return iStatic;
       
    35 	}
       
    36 
       
    37 CWsMemoryManager::CWsMemoryManager()
       
    38 	{
       
    39 	iImpl = User::SwitchAllocator(this);
       
    40 	}
       
    41 	
       
    42 CWsMemoryManager::~CWsMemoryManager()
       
    43 	{
       
    44 	WS_ASSERT_ALWAYS(this == User::SwitchAllocator(iImpl),EWsPanicMemoryManager);
       
    45 	iStatic = 0;
       
    46 	if (iReserve!=NULL)
       
    47 		{
       
    48 		Free(iReserve);
       
    49 		iReserve = NULL;
       
    50 		}	
       
    51 	}
       
    52 
       
    53 void CWsMemoryManager::ConstructL()
       
    54 	{
       
    55 	_LIT(KMemMgrReserve, "MEMORYRESERVE");
       
    56 	const TInt KDefaultMemMgrReserve = 1024;
       
    57 	
       
    58 	if (!WsIniFile->FindVar(KMemMgrReserve, iReserveSize))
       
    59 		iReserveSize = KDefaultMemMgrReserve;
       
    60 
       
    61 	if (iReserveSize > 0)
       
    62 		iReserve = Alloc(iReserveSize);
       
    63 	}
       
    64 
       
    65 /**
       
    66 Implementing RAllocator
       
    67 */
       
    68 
       
    69 /**
       
    70 Alloc and ReAlloc attempt to obtain memory through CWsTop::ReleaseMemory when they run low.
       
    71 ReleaseMemory looks for blocks of memory that the window server doesn't need urgently and frees
       
    72 them.
       
    73 */
       
    74 TAny* CWsMemoryManager::Alloc(TInt aSize)
       
    75 	{
       
    76 	TBool keepTrying = ETrue;
       
    77 	do
       
    78 		{
       
    79 		if(iReleasing)
       
    80 			return iImpl->Alloc(aSize); //fallback on RAllocator
       
    81 		
       
    82 		if(TAny* ret = iImpl->Alloc(aSize)) //normal case
       
    83 			return ret;
       
    84 		
       
    85 		if(iReserveEnabled && iReserve && (aSize < iReserveSize))
       
    86 			{
       
    87 			Free(iReserve);
       
    88 			iReserve = NULL;
       
    89 			}
       
    90 		else
       
    91 			{
       
    92 			iReleasing = ETrue;
       
    93 			keepTrying = CWsTop::ReleaseMemory();
       
    94 			if(keepTrying)
       
    95  				{
       
    96  				const TInt reclaimed = Compress(); //Try to give back to the OS
       
    97  				}			
       
    98 			iReleasing = EFalse;
       
    99 			}
       
   100 		
       
   101 		} while(keepTrying);
       
   102 
       
   103 	return NULL;
       
   104 	}
       
   105 
       
   106 TAny* CWsMemoryManager::ReAlloc(TAny* aPtr, TInt aSize, TInt aMode)
       
   107 	{
       
   108 	TBool keepTrying = ETrue;
       
   109 	do
       
   110 		{
       
   111 		if(iReleasing)
       
   112 			return iImpl->ReAlloc(aPtr, aSize, aMode); //fallback on RAllocator
       
   113 		
       
   114 		if(TAny* ret = iImpl->ReAlloc(aPtr, aSize, aMode)) //normal case
       
   115 			return ret;
       
   116 		
       
   117 		if(iReserveEnabled && iReserve && (aSize < iReserveSize))
       
   118 			{
       
   119 			Free(iReserve);
       
   120 			iReserve = NULL;
       
   121 			}
       
   122 		else
       
   123 			{
       
   124 			iReleasing = ETrue;
       
   125 			keepTrying = CWsTop::ReleaseMemory();
       
   126 			if(keepTrying)
       
   127  				{
       
   128  				const TInt reclaimed = Compress(); //Try to give back to the OS
       
   129  				}	
       
   130 			iReleasing = EFalse;
       
   131 			}
       
   132 
       
   133 		} while(keepTrying);
       
   134 
       
   135 	return NULL;
       
   136 	}
       
   137 
       
   138 /**
       
   139 The rest of these functions just call the default implementation
       
   140 */
       
   141 void CWsMemoryManager::Free(TAny* aPtr)
       
   142 	{
       
   143 	return iImpl->Free(aPtr);
       
   144 	}
       
   145 
       
   146 TInt CWsMemoryManager::AllocLen(const TAny* aCell) const
       
   147 	{
       
   148 	return iImpl->AllocLen(aCell);
       
   149 	}
       
   150 
       
   151 TInt CWsMemoryManager::Compress()
       
   152 	{
       
   153 	return iImpl->Compress();
       
   154 	}
       
   155 
       
   156 void CWsMemoryManager::Reset()
       
   157 	{
       
   158 	iImpl->Reset();
       
   159 	}
       
   160 
       
   161 TInt CWsMemoryManager::AllocSize(TInt& aTotalAllocSize) const
       
   162 	{
       
   163 	return iImpl->AllocSize(aTotalAllocSize);
       
   164 	}
       
   165 
       
   166 TInt CWsMemoryManager::Available(TInt& aBiggestBlock) const
       
   167 	{
       
   168 	return iImpl->Available(aBiggestBlock);
       
   169 	}
       
   170 
       
   171 TInt CWsMemoryManager::DebugFunction(TInt aFunc, TAny* a1, TAny* a2)
       
   172 	{
       
   173 	return iImpl->DebugFunction(aFunc,a1,a2);
       
   174 	}
       
   175 
       
   176 TInt CWsMemoryManager::Count() const
       
   177 	{
       
   178 	return iImpl->Count();
       
   179 	}
       
   180 /** This is a fairly dumb way to enable and disable the reserve, but we normally
       
   181 get away with it because wserv is high priority.  A better approach would be to
       
   182 use placement new into the reserve memory and manage it directly.  This would also
       
   183 allow us to track misbehaving code which allocated during OOM drawing and didn't
       
   184 free at the end.
       
   185 */
       
   186 void CWsMemoryManager::EnableReserve()
       
   187 	{
       
   188 	WS_ASSERT_DEBUG(!iReserveEnabled, EWsPanicMemoryManager);
       
   189 	iReserveEnabled = ETrue;
       
   190 	}
       
   191 
       
   192 void CWsMemoryManager::DisableReserve()
       
   193 	{
       
   194 	WS_ASSERT_DEBUG(iReserveEnabled, EWsPanicMemoryManager);
       
   195 	iReserveEnabled = EFalse;
       
   196 	if((!iReserve) && (iReserveSize > 0))
       
   197 		iReserve = Alloc(iReserveSize);
       
   198 	}