webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp
changeset 0 dd21522fd290
child 8 7c90e6132015
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDES
       
    21 
       
    22 #include <e32base.h>
       
    23 #include <e32std.h>
       
    24 #include <e32hal.h>
       
    25 #include "MemoryPool.h"
       
    26 #include "StopScheduler.h"
       
    27 #include "fast_malloc.h"
       
    28 #include <OOMMonitorSession.h>
       
    29 
       
    30 // CONSTANTS
       
    31 
       
    32 // CLASS DECLARATIONS
       
    33 
       
    34 //-----------------------------------------------------------------------------
       
    35 // CMemoryPool::AddCollector
       
    36 //-----------------------------------------------------------------------------
       
    37 void CMemoryPool::AddCollector( MMemoryCollector* aCollector )
       
    38     {
       
    39     // sort the collectors according to their priorities
       
    40     TInt i;
       
    41     for( i=0; i<iCollectors.Count(); ++i )
       
    42       {
       
    43       if( aCollector->Priority() <= iCollectors[i]->Priority() ) break;
       
    44       }
       
    45 
       
    46     iCollectors.Insert( aCollector, i );
       
    47     }
       
    48 
       
    49 //-----------------------------------------------------------------------------
       
    50 // CMemoryPool::RemoveCollector
       
    51 //-----------------------------------------------------------------------------
       
    52 void CMemoryPool::RemoveCollector( MMemoryCollector* aCollector )
       
    53     {
       
    54     TInt idx = iCollectors.Find( aCollector );
       
    55     if( idx != KErrNotFound )
       
    56         iCollectors.Remove( idx );
       
    57     }
       
    58 
       
    59 //-----------------------------------------------------------------------------
       
    60 // CMemoryPool::AddStopper
       
    61 //-----------------------------------------------------------------------------
       
    62 void CMemoryPool::AddStopper( MOOMStopper* aStopper )
       
    63     {
       
    64     if( !iStopScheduler )
       
    65         iStopScheduler = new CStopScheduler(*this);
       
    66     iStoppers.Append( aStopper );
       
    67     }
       
    68 
       
    69 //-----------------------------------------------------------------------------
       
    70 // CMemoryPool::RemoveStopper
       
    71 //-----------------------------------------------------------------------------
       
    72 void CMemoryPool::RemoveStopper( MOOMStopper* aStopper )
       
    73     {
       
    74 	if( !iStopScheduler ) return;
       
    75     TInt idx = iStoppers.Find( aStopper );
       
    76     if( idx != KErrNotFound )
       
    77         iStoppers.Remove( idx );
       
    78     }
       
    79 
       
    80 //-----------------------------------------------------------------------------
       
    81 // CMemoryPool::SetNotifier
       
    82 //-----------------------------------------------------------------------------
       
    83 void CMemoryPool::SetNotifier( MOOMNotifier* aNotifier )
       
    84     {
       
    85     iNotifier = aNotifier;
       
    86     }
       
    87 
       
    88 //-----------------------------------------------------------------------------
       
    89 // CMemoryPool::Create()
       
    90 //-----------------------------------------------------------------------------
       
    91 TBool CMemoryPool::Create()
       
    92     {
       
    93     iNestedChecks = 0;
       
    94 
       
    95     iCollectors.Reset();
       
    96     iIsStopping = EFalse;
       
    97     iIsCollecting = EFalse;
       
    98     iMemStatus = ENoOOM;
       
    99 
       
   100     // stop scheduler
       
   101     iStopScheduler = 0;
       
   102     iNotifier = 0;
       
   103 
       
   104     return ETrue;
       
   105     }
       
   106 
       
   107 
       
   108 //-----------------------------------------------------------------------------
       
   109 // CMemoryPool::SetStopping
       
   110 //-----------------------------------------------------------------------------
       
   111 void CMemoryPool::SetStopping( TBool aStopping )
       
   112     {
       
   113     iIsStopping = aStopping;
       
   114     // all operations are stopped, must have some memory available
       
   115     if( !iIsStopping ) iMemStatus = ENoOOM;
       
   116 
       
   117     // notify the client when stopping is done
       
   118     if( !aStopping && iNotifier )
       
   119         {
       
   120         iNotifier->Notify();
       
   121         }
       
   122     }
       
   123 
       
   124 //-----------------------------------------------------------------------------
       
   125 // CMemoryPool::CollectMemory
       
   126 //-----------------------------------------------------------------------------
       
   127 void CMemoryPool::CollectMemory(TUint aSize)
       
   128     {
       
   129     if( iIsCollecting ) return;
       
   130 
       
   131     iIsCollecting = ETrue;
       
   132     for( TInt i=0; i<iCollectors.Count(); ++i )
       
   133       {
       
   134         iCollectors[i]->Collect(aSize);
       
   135       }
       
   136 
       
   137     User::CompressAllHeaps();
       
   138     iIsCollecting = EFalse;
       
   139 	
       
   140 	if (iStopScheduler)
       
   141 		iStopScheduler->Start( CStopScheduler::ECheckMemory, aSize );
       
   142     }
       
   143 
       
   144 //-----------------------------------------------------------------------------
       
   145 // CMemoryPool::RestoreCollectors
       
   146 //-----------------------------------------------------------------------------
       
   147 void CMemoryPool::RestoreCollectors( TOOMPriority aPriority )
       
   148   {
       
   149   if( iIsCollecting ) return;
       
   150 
       
   151     for( TInt i=0; i<iCollectors.Count(); ++i )
       
   152       {
       
   153         if( iCollectors[i]->Priority() >= aPriority )
       
   154             iCollectors[i]->Restore();
       
   155       }
       
   156   }
       
   157 
       
   158 //-----------------------------------------------------------------------------
       
   159 // CMemoryPool::~CMemoryPool
       
   160 //-----------------------------------------------------------------------------
       
   161 CMemoryPool::~CMemoryPool()
       
   162     {
       
   163     iCollectors.Reset();
       
   164     iStoppers.Reset();
       
   165     delete iStopScheduler;
       
   166 
       
   167     // NOTE: remove this when UI spec has OOM notifier defined
       
   168     delete iNotifier;
       
   169     }
       
   170 
       
   171 //-----------------------------------------------------------------------------
       
   172 // CMemoryPool::AllocFromPool
       
   173 //-----------------------------------------------------------------------------
       
   174 TAny* CMemoryPool::AllocFromPool( TUint aSize )
       
   175     {
       
   176     // reset the status for next allocation
       
   177     iMemStatus &= ~ERescueOOM;
       
   178 
       
   179     TAny *p = DoAlloc( aSize );
       
   180 
       
   181     // check memory manager status
       
   182     if( !p || iMemStatus & ERescueOOM )
       
   183         {
       
   184         if( !iIsCollecting )
       
   185             {
       
   186             CollectMemory();
       
   187             }
       
   188 
       
   189         if( !p )
       
   190             p = DoAlloc( aSize );
       
   191 
       
   192         NotifyAndStop();
       
   193         }
       
   194 
       
   195     return p;
       
   196     }
       
   197 
       
   198 //-----------------------------------------------------------------------------
       
   199 // CMemoryPool::SetStatus
       
   200 //-----------------------------------------------------------------------------
       
   201 void CMemoryPool::SetStatus( TOOMCheckResult aType )
       
   202     {
       
   203     iMemStatus |= aType;
       
   204     }
       
   205 
       
   206 //-----------------------------------------------------------------------------
       
   207 // CMemoryPool::NotifyAndStop()
       
   208 //-----------------------------------------------------------------------------
       
   209 void CMemoryPool::NotifyAndStop()
       
   210   {
       
   211   if( !iIsStopping )
       
   212     {
       
   213         iIsStopping = ETrue;
       
   214 		if (iStopScheduler)
       
   215 			iStopScheduler->Start( CStopScheduler::EStopLoading, 0 );
       
   216     }
       
   217   }
       
   218 
       
   219 //-----------------------------------------------------------------------------
       
   220 // CPlainAllocator::DoAlloc
       
   221 //-----------------------------------------------------------------------------
       
   222 TUint CFastMemoryPool::FreeMemory(TFreeMem& aFree )
       
   223     {
       
   224     return free_memory( aFree.iPool, aFree.iHeap, aFree.iHal );
       
   225     }
       
   226 
       
   227 //-----------------------------------------------------------------------------
       
   228 // CFastMemoryPool::DoAlloc
       
   229 //-----------------------------------------------------------------------------
       
   230 TAny* CFastMemoryPool::DoAlloc( TUint aSize )
       
   231     {
       
   232     return fast_malloc( aSize );
       
   233     }
       
   234 
       
   235 //-----------------------------------------------------------------------------
       
   236 // CFastMemoryPool::ReAllocate
       
   237 //-----------------------------------------------------------------------------
       
   238 TAny* CFastMemoryPool::ReAllocate( TAny* aPtr, TUint aSize )
       
   239     {
       
   240     // reset the status for next allocation
       
   241     iMemStatus &= ~ERescueOOM;
       
   242 
       
   243     TAny* p = fast_realloc( aPtr, aSize );
       
   244 
       
   245     // check memory manager status
       
   246     if( !p || iMemStatus & ERescueOOM )
       
   247         {
       
   248         if( !iIsCollecting )
       
   249             {
       
   250             CollectMemory();
       
   251             }
       
   252 
       
   253         if( !p )
       
   254             p = fast_realloc( aPtr, aSize );
       
   255 
       
   256         NotifyAndStop();
       
   257         }
       
   258 
       
   259     return p;
       
   260     }
       
   261 
       
   262 //-----------------------------------------------------------------------------
       
   263 // CFastMemoryPool::PreCheck
       
   264 //-----------------------------------------------------------------------------
       
   265 TBool CFastMemoryPool::PreCheck( TUint aTotalSize, TUint aMaxBufSize, const TDesC8& /*aCheckerName*/ )
       
   266     {
       
   267     // avoid small checkings
       
   268     if( aTotalSize < 1024 ) return ETrue;
       
   269 
       
   270     if( !fast_pre_check( aTotalSize, aMaxBufSize ) )
       
   271         {
       
   272         CollectMemory(aTotalSize);
       
   273         ROomMonitorSession oomMs;
       
   274         if ( oomMs.Connect() == KErrNone ) {
       
   275             oomMs.RequestFreeMemory( aTotalSize );
       
   276             oomMs.Close();
       
   277         }
       
   278         if( !fast_pre_check( aTotalSize, aMaxBufSize ) )
       
   279             {
       
   280             iMemStatus |= ECheckOOM;
       
   281             NotifyAndStop();
       
   282             return EFalse;
       
   283             }
       
   284         }
       
   285 
       
   286     return ETrue;
       
   287     }
       
   288 
       
   289 //-----------------------------------------------------------------------------
       
   290 // CMemoryPool::PostCheck
       
   291 //-----------------------------------------------------------------------------
       
   292 TUint CFastMemoryPool::PostCheck()
       
   293     {
       
   294     fast_post_check();
       
   295     return iMemStatus;
       
   296     }
       
   297 
       
   298 //-----------------------------------------------------------------------------
       
   299 // CPlainAllocator::Free
       
   300 //-----------------------------------------------------------------------------
       
   301 void CFastMemoryPool::Free( TAny* aPtr )
       
   302     {
       
   303     return fast_free( aPtr );
       
   304     }
       
   305 
       
   306 //-----------------------------------------------------------------------------
       
   307 // CPlainAllocator::MemorySize
       
   308 //-----------------------------------------------------------------------------
       
   309 TUint CFastMemoryPool::MemorySize( TAny* aPtr )
       
   310     {
       
   311     return fast_malloc_size( aPtr );
       
   312     }
       
   313 
       
   314 //-----------------------------------------------------------------------------
       
   315 // CPlainAllocator::SetRescueBufferSize
       
   316 //-----------------------------------------------------------------------------
       
   317 void CFastMemoryPool::SetRescueBufferSize( TInt aSize )
       
   318     {
       
   319     fast_set_rescue_buffer_size( aSize );
       
   320     }
       
   321 
       
   322 void CFastMemoryPool::RestoreRescueBuffer()
       
   323     {
       
   324     alloc_rescue_buffer();
       
   325     }
       
   326 
       
   327 //-----------------------------------------------------------------------------
       
   328 // CDefaultMemoryPool::~CDefaultMemoryPool
       
   329 //-----------------------------------------------------------------------------
       
   330 CDefaultMemoryPool::~CDefaultMemoryPool()
       
   331     {
       
   332     }
       
   333 
       
   334 //-----------------------------------------------------------------------------
       
   335 // CDefaultMemoryPool::DoAlloc
       
   336 //-----------------------------------------------------------------------------
       
   337 TAny* CDefaultMemoryPool::DoAlloc(TUint aSize)
       
   338     {
       
   339     return User::Alloc( aSize );
       
   340     }
       
   341 
       
   342 //-----------------------------------------------------------------------------
       
   343 // CDefaultMemoryPool::ReAllocate
       
   344 //-----------------------------------------------------------------------------
       
   345 TAny* CDefaultMemoryPool::ReAllocate( TAny* aPtr, TUint aSize )
       
   346     {   
       
   347     return User::ReAlloc( aPtr, aSize );
       
   348     }
       
   349 
       
   350 //-----------------------------------------------------------------------------
       
   351 // CDefaultMemoryPool::FreeMemory
       
   352 //-----------------------------------------------------------------------------
       
   353 TUint CDefaultMemoryPool::FreeMemory(TFreeMem& /*aFree*/)
       
   354     {
       
   355     // free memory in Hal
       
   356     TMemoryInfoV1Buf info;
       
   357     UserHal::MemoryInfo( info );
       
   358     return info().iFreeRamInBytes;
       
   359     }
       
   360 
       
   361 //-----------------------------------------------------------------------------
       
   362 // CDefaultMemoryPool::Free
       
   363 //-----------------------------------------------------------------------------
       
   364 void CDefaultMemoryPool::Free(TAny* aPtr)
       
   365     {
       
   366     User::Free( aPtr );
       
   367     }
       
   368 
       
   369 //-----------------------------------------------------------------------------
       
   370 // CDefaultMemoryPool::MemorySize
       
   371 //-----------------------------------------------------------------------------
       
   372 TUint CDefaultMemoryPool::MemorySize(TAny* aPtr)
       
   373     {
       
   374     return User::AllocLen( aPtr );
       
   375     }
       
   376 
       
   377 //-----------------------------------------------------------------------------
       
   378 // CDefaultMemoryPool::SetRescueBufferSize
       
   379 //-----------------------------------------------------------------------------
       
   380 void CDefaultMemoryPool::SetRescueBufferSize( TInt aSize )
       
   381     {
       
   382     iRescueBufferSize = aSize;
       
   383     }
       
   384 
       
   385 //-----------------------------------------------------------------------------
       
   386 // CDefaultMemoryPool::PreCheck
       
   387 //-----------------------------------------------------------------------------
       
   388 TBool CDefaultMemoryPool::PreCheck( TUint aTotalSize, TUint /*aMaxBufSize*/, const TDesC8& /*aCheckerName*/ )
       
   389     {
       
   390     // avoid small checkings
       
   391     if( aTotalSize < 1024 ) return ETrue;
       
   392 
       
   393     // free memory in Hal
       
   394     TMemoryInfoV1Buf info;
       
   395     UserHal::MemoryInfo( info );
       
   396     TInt sizeNeeded = aTotalSize + iRescueBufferSize;
       
   397     if( sizeNeeded > info().iFreeRamInBytes )
       
   398         {
       
   399         CollectMemory(sizeNeeded);
       
   400         
       
   401         // check memory again
       
   402         UserHal::MemoryInfo( info );
       
   403 
       
   404         if(sizeNeeded > info().iFreeRamInBytes ) 
       
   405             {
       
   406             NotifyAndStop();
       
   407             iMemStatus |= ECheckOOM;
       
   408             return EFalse;
       
   409             }
       
   410         }
       
   411 
       
   412     return ETrue;
       
   413     }
       
   414 
       
   415 //-----------------------------------------------------------------------------
       
   416 // CDefaultMemoryPool::PostCheck
       
   417 //-----------------------------------------------------------------------------
       
   418 TUint CDefaultMemoryPool::PostCheck()
       
   419     {
       
   420     return iMemStatus;
       
   421     }
       
   422 
       
   423 void CDefaultMemoryPool::RestoreRescueBuffer()
       
   424     {
       
   425     // do nothing here.
       
   426     }
       
   427 
       
   428 // END OF FILE