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 |