webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp
changeset 1 7c90e6132015
parent 0 dd21522fd290
child 10 a359256acfc6
equal deleted inserted replaced
0:dd21522fd290 1:7c90e6132015
    23 #include <e32std.h>
    23 #include <e32std.h>
    24 #include <e32hal.h>
    24 #include <e32hal.h>
    25 #include "MemoryPool.h"
    25 #include "MemoryPool.h"
    26 #include "StopScheduler.h"
    26 #include "StopScheduler.h"
    27 #include "fast_malloc.h"
    27 #include "fast_malloc.h"
       
    28 #include "SymbianDlHeap.h"
    28 #include <OOMMonitorSession.h>
    29 #include <OOMMonitorSession.h>
       
    30 #include <hal.h>
    29 
    31 
    30 // CONSTANTS
    32 // CONSTANTS
    31 
    33 
    32 // CLASS DECLARATIONS
    34 // CLASS DECLARATIONS
    33 
    35 
   388 TBool CDefaultMemoryPool::PreCheck( TUint aTotalSize, TUint /*aMaxBufSize*/, const TDesC8& /*aCheckerName*/ )
   390 TBool CDefaultMemoryPool::PreCheck( TUint aTotalSize, TUint /*aMaxBufSize*/, const TDesC8& /*aCheckerName*/ )
   389     {
   391     {
   390     // avoid small checkings
   392     // avoid small checkings
   391     if( aTotalSize < 1024 ) return ETrue;
   393     if( aTotalSize < 1024 ) return ETrue;
   392 
   394 
       
   395 	// first check the application heap's max free block
       
   396 	TInt maxFreeBlock = 0;
       
   397 	User::Allocator().Available(maxFreeBlock);
       
   398 	if (aTotalSize < maxFreeBlock)
       
   399 		return ETrue;
       
   400 	
       
   401 
   393     // free memory in Hal
   402     // free memory in Hal
   394     TMemoryInfoV1Buf info;
   403     TMemoryInfoV1Buf info;
   395     UserHal::MemoryInfo( info );
   404     UserHal::MemoryInfo( info );
   396     TInt sizeNeeded = aTotalSize + iRescueBufferSize;
   405     TInt sizeNeeded = aTotalSize + iRescueBufferSize;
   397     if( sizeNeeded > info().iFreeRamInBytes )
   406 
       
   407 	// check if there is enough space for the heap to grow
       
   408 	bool needSysCheck = EFalse;
       
   409 	if (info().iFreeRamInBytes > sizeNeeded) {
       
   410 		RHeap& heap = User::Heap();
       
   411 		if (heap.MaxLength() - heap.Size() > sizeNeeded)
       
   412 			return ETrue;
       
   413 
       
   414 		needSysCheck = ETrue;
       
   415 	}
       
   416 
       
   417 	if(sizeNeeded > info().iFreeRamInBytes || needSysCheck)
   398         {
   418         {
   399         CollectMemory(sizeNeeded);
   419         CollectMemory(sizeNeeded);
   400         
   420         
   401         // check memory again
   421         // check memory again
   402         UserHal::MemoryInfo( info );
   422         UserHal::MemoryInfo( info );
   423 void CDefaultMemoryPool::RestoreRescueBuffer()
   443 void CDefaultMemoryPool::RestoreRescueBuffer()
   424     {
   444     {
   425     // do nothing here.
   445     // do nothing here.
   426     }
   446     }
   427 
   447 
       
   448 #ifdef __NEW_ALLOCATOR__
       
   449 //-----------------------------------------------------------------------------
       
   450 // CNewSymbianHeapPool::FreeMemory
       
   451 //-----------------------------------------------------------------------------
       
   452 TUint CNewSymbianHeapPool::FreeMemory(TFreeMem& /*aFree*/ )
       
   453     {
       
   454     // TODO: implement free_memory
       
   455     return KMaxTUint;
       
   456 //    return free_memory( aFree.iPool, aFree.iHeap, aFree.iHal );
       
   457     }
       
   458 
       
   459 //-----------------------------------------------------------------------------
       
   460 // CNewSymbianHeapPool::DoAlloc
       
   461 //-----------------------------------------------------------------------------
       
   462 TAny* CNewSymbianHeapPool::DoAlloc( TUint aSize )
       
   463     {
       
   464     return iAlloc->Alloc( aSize );
       
   465     }
       
   466 
       
   467 //-----------------------------------------------------------------------------
       
   468 // CNewSymbianHeapPool::ReAllocate
       
   469 //-----------------------------------------------------------------------------
       
   470 TAny* CNewSymbianHeapPool::ReAllocate( TAny* aPtr, TUint aSize )
       
   471     {
       
   472     // reset the status for next allocation
       
   473     iMemStatus &= ~ERescueOOM;
       
   474 
       
   475     TAny* p = iAlloc->ReAlloc( aPtr, aSize );
       
   476     
       
   477     // check memory manager status
       
   478     if( !p || iMemStatus & ERescueOOM )
       
   479         {
       
   480         if( !iIsCollecting )
       
   481             {
       
   482             CollectMemory();
       
   483             }
       
   484 
       
   485         if( !p )
       
   486 			p = iAlloc->ReAlloc( aPtr, aSize );
       
   487 
       
   488         NotifyAndStop();
       
   489         }
       
   490 
       
   491     return p;
       
   492     }
       
   493 
       
   494 //-----------------------------------------------------------------------------
       
   495 // CNewSymbianHeapPool::PreCheck
       
   496 //-----------------------------------------------------------------------------
       
   497 TBool CNewSymbianHeapPool::PreCheck(TUint aTotalSize, TUint aMaxBufSize,
       
   498 		const TDesC8& /*aCheckerName*/)
       
   499 	{
       
   500 	/* aTotalSize - total amount desired
       
   501 	 * aMaxBufSize - largest single allocation desired
       
   502 	 */
       
   503 
       
   504 	// avoid small checkings
       
   505 	if (aTotalSize < 1024)
       
   506 		return ETrue;
       
   507 
       
   508 	/*
       
   509 	 * Browser fast_malloc implementation merges together total/max allocation requests and says YES if system free memory is >6MB
       
   510 	 */
       
   511 	// mirror existing size calculation
       
   512 	aTotalSize = aTotalSize > (aMaxBufSize * 2) ? aTotalSize
       
   513 			: (aMaxBufSize * 2);
       
   514 
       
   515 	// if we have more than 6 MB of free mem, we 
       
   516 	// should skip malloc_info call.
       
   517 	// free memory in Hal
       
   518     TInt systemFreeMemory = 0;
       
   519 	if( HAL::Get(HALData::EMemoryRAMFree, systemFreeMemory) == KErrNone )
       
   520 		{
       
   521 		const TUint checkThreshold = 6*1024*1024;
       
   522 		if(systemFreeMemory> checkThreshold && systemFreeMemory> aTotalSize)
       
   523 		return ETrue;
       
   524 		}
       
   525 
       
   526 	/* For a proper implementation of RHeap, the stats available are:
       
   527 	 * AllocSize	Total number of allocated bytes
       
   528 	 * Size			Total number of bytes held from system
       
   529 	 * Available	Max block size and amount of bytes held but not allocated
       
   530 	 */
       
   531 	/* We don't have those bits of the heap implemented yet
       
   532 	 */ 
       
   533 	TInt freeSpace = 0; // be conservative, use 0 intead of 64<<10;
       
   534 	TInt req = freeSpace + systemFreeMemory - aTotalSize;	
       
   535 	
       
   536 	if(req > 0)
       
   537 		return ETrue;
       
   538 	
       
   539 	// First, ask system for memory from other applications.
       
   540 	ROomMonitorSession oomMs;
       
   541 	if (oomMs.Connect() == KErrNone)
       
   542 		{
       
   543 		oomMs.RequestFreeMemory(aTotalSize);
       
   544 		oomMs.Close();
       
   545 		}
       
   546 
       
   547 	// We haven't altered our heap yet, so ask the system how much is free now...
       
   548 	HAL::Get(HALData::EMemoryRAMFree, systemFreeMemory);
       
   549 	req = freeSpace + systemFreeMemory - aTotalSize;	
       
   550 	
       
   551 	if(req > 0)
       
   552 		return ETrue;
       
   553 	
       
   554 	// We haven't got the required amount free yet, try the browser heap.
       
   555 	CollectMemory(aTotalSize);
       
   556 	// ask the system how much is free now...
       
   557 	HAL::Get(HALData::EMemoryRAMFree, systemFreeMemory);
       
   558 	req = freeSpace + systemFreeMemory - aTotalSize;	
       
   559 	
       
   560 	// if we still haven't got enough RAM, we should stop the browser from going any further just yet.
       
   561 	if (req < 0)
       
   562 		{
       
   563 		iMemStatus |= ECheckOOM;
       
   564 		NotifyAndStop();
       
   565 		return EFalse;
       
   566 		}
       
   567 	
       
   568 	return ETrue;
       
   569 	}
       
   570 
       
   571 //-----------------------------------------------------------------------------
       
   572 // CNewSymbianHeapPool::PostCheck
       
   573 //-----------------------------------------------------------------------------
       
   574 TUint CNewSymbianHeapPool::PostCheck()
       
   575     {
       
   576     return iMemStatus;
       
   577     }
       
   578 
       
   579 //-----------------------------------------------------------------------------
       
   580 // CNewSymbianHeapPool::Free
       
   581 //-----------------------------------------------------------------------------
       
   582 void CNewSymbianHeapPool::Free( TAny* aPtr )
       
   583     {
       
   584     return iAlloc->Free( aPtr );
       
   585     }
       
   586 
       
   587 //-----------------------------------------------------------------------------
       
   588 // CNewSymbianHeapPool::MemorySize
       
   589 //-----------------------------------------------------------------------------
       
   590 TUint CNewSymbianHeapPool::MemorySize( TAny* aPtr )
       
   591     {
       
   592     return iAlloc->AllocLen( aPtr );
       
   593     }
       
   594 
       
   595 //-----------------------------------------------------------------------------
       
   596 // CNewSymbianHeapPool::SetRescueBufferSize
       
   597 //-----------------------------------------------------------------------------
       
   598 void CNewSymbianHeapPool::SetRescueBufferSize( TInt /*aSize*/ )
       
   599     {
       
   600     //fast_set_rescue_buffer_size( aSize );
       
   601     }
       
   602 
       
   603 //-----------------------------------------------------------------------------
       
   604 // CNewSymbianHeapPool::RestoreRescueBuffer
       
   605 //-----------------------------------------------------------------------------
       
   606 void CNewSymbianHeapPool::RestoreRescueBuffer()
       
   607     {
       
   608     //alloc_rescue_buffer();
       
   609     }
       
   610 
       
   611 CNewSymbianHeapPool::CNewSymbianHeapPool() : CMemoryPool()
       
   612 	{
       
   613 	}
       
   614 
       
   615 CNewSymbianHeapPool::~CNewSymbianHeapPool()
       
   616 	{
       
   617 //	iAlloc->Close();	// TODO: Need to clean up here, but it's not implemented in the allocator yet.
       
   618 						// Not fatal anyway because all the handles are process local and we should only
       
   619 						// be deleting this object when we're closing the allocator - which we never do
       
   620 						// except at process end.
       
   621 	}
       
   622 
       
   623 const TInt KMaxHeapSize = 0x2000000; //32MB
       
   624 const TInt KHeapGrowSize = 0x10000;  //64KB
       
   625 
       
   626 TBool CNewSymbianHeapPool::Create()
       
   627 	{
       
   628 	// need to know system page size
       
   629 	TInt page_size;
       
   630 	UserHal::PageSizeInBytes(page_size);
       
   631 
       
   632 	// Create the thread's heap chunk.
       
   633 	//
       
   634 	// The chunk needs reserve enough address space for twice the maximum allocation
       
   635 	// The heap object is instantiated exactly half way up the chunk, and initially is provided just 1 page of memory
       
   636 	// This memory can be committed as part of the call to creat the chunk
       
   637 	//
       
   638 	TInt maxChunkSize = 2 * KMaxHeapSize;
       
   639 	TInt offset = KMaxHeapSize;
       
   640 	TInt minLength = page_size;
       
   641 	RChunk c;
       
   642 	TInt r = c.CreateDisconnectedLocal(offset, offset+minLength, maxChunkSize, EOwnerProcess);
       
   643 	if (r!=KErrNone)
       
   644 		return EFalse;
       
   645 	
       
   646 	iAlloc = new (c.Base() + offset) RSymbianDLHeap(c.Handle(), offset, minLength, KMaxHeapSize, KHeapGrowSize, 8, EFalse /* not single threaded! */);
       
   647 	iAlloc->iHandles = &iAlloc->iChunkHandle;
       
   648 	iAlloc->iHandleCount = 2;
       
   649 	// chunk handle now 'owned' by iAlloc
       
   650 	r = iAlloc->iLock.CreateLocal(EOwnerProcess);
       
   651 
       
   652 	if(r != KErrNone)
       
   653 		return EFalse;
       
   654 	
       
   655 	return CMemoryPool::Create();
       
   656 	}
       
   657 
       
   658 #endif
   428 // END OF FILE
   659 // END OF FILE