Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 #include "oscl_mem_mempool.h"
     19 
     20 
     21 /**
     22  *  OsclMemPoolFixedChunkAllocator section
     23  **/
     24 
     25 OSCL_EXPORT_REF OsclMemPoolFixedChunkAllocator::OsclMemPoolFixedChunkAllocator(const uint32 numchunk, const uint32 chunksize, Oscl_DefAlloc* gen_alloc) :
     26         iNumChunk(1), iChunkSize(0), iChunkSizeMemAligned(0),
     27         iMemPoolAllocator(gen_alloc), iMemPool(NULL),
     28         iCheckNextAvailableFreeChunk(false), iObserver(NULL),
     29         iNextAvailableContextData(NULL),
     30         iRefCount(1),
     31         iEnableNullPtrReturn(false)
     32 {
     33     iNumChunk = numchunk;
     34     iChunkSize = chunksize;
     35 
     36     if (iNumChunk == 0)
     37     {
     38         iNumChunk = 1;
     39     }
     40 
     41     if (iChunkSize > 0)
     42     {
     43         createmempool();
     44     }
     45 }
     46 
     47 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::enablenullpointerreturn()
     48 {
     49     iEnableNullPtrReturn = true;
     50 }
     51 
     52 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::addRef()
     53 {
     54     // Just increment the ref count
     55     ++iRefCount;
     56 }
     57 
     58 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::removeRef()
     59 {
     60     // Decrement the ref count
     61     --iRefCount;
     62 
     63     // If ref count reaches 0 then destroy this object automatically
     64     if (iRefCount <= 0)
     65     {
     66         OSCL_DELETE(this);
     67     }
     68 }
     69 
     70 
     71 OSCL_EXPORT_REF OsclMemPoolFixedChunkAllocator::~OsclMemPoolFixedChunkAllocator()
     72 {
     73     // Decrement the ref count
     74     --iRefCount;
     75 
     76     // If ref count reaches 0 then destroy this object
     77     if (iRefCount <= 0)
     78     {
     79         destroymempool();
     80     }
     81 }
     82 
     83 
     84 OSCL_EXPORT_REF OsclAny* OsclMemPoolFixedChunkAllocator::allocate(const uint32 n)
     85 {
     86     // Create the memory pool if it hasn't been created yet.
     87     // Use the allocation size, n, as the chunk size for memory pool
     88     if (iChunkSize == 0)
     89     {
     90         iChunkSize = n;
     91         createmempool();
     92     }
     93     else if (n > iChunkSize)
     94     {
     95         OSCL_LEAVE(OsclErrArgument);
     96         // OSCL_UNUSED_RETURN(NULL);    This statement was removed to avoid compiler warning for Unreachable Code
     97 
     98     }
     99 
    100     if (iFreeMemChunkList.empty())
    101     {
    102         // No free chunk is available
    103         if (iEnableNullPtrReturn)
    104         {
    105             return NULL;
    106         }
    107         else
    108         {
    109             OSCL_LEAVE(OsclErrNoResources);
    110         }
    111     }
    112 
    113     // Return the next available chunk from the pool
    114     OsclAny* freechunk = iFreeMemChunkList.back();
    115     // Remove the chunk from the free list
    116     iFreeMemChunkList.pop_back();
    117     addRef();
    118     return freechunk;
    119 }
    120 
    121 
    122 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::deallocate(OsclAny* p)
    123 {
    124     if (iMemPool == NULL)
    125     {
    126         // Memory pool hasn't been allocated yet so error
    127         OSCL_LEAVE(OsclErrNotReady);
    128     }
    129 
    130     uint8* ptmp = (uint8*)p;
    131     uint8* mptmp = (uint8*)iMemPool;
    132 
    133     if ((ptmp < mptmp) || ptmp >= (mptmp + iNumChunk*iChunkSizeMemAligned))
    134     {
    135         // Returned memory is not part of this memory pool
    136         OSCL_LEAVE(OsclErrArgument);
    137     }
    138 
    139     if (((ptmp - mptmp) % iChunkSizeMemAligned) != 0)
    140     {
    141         // Returned memory is not aligned to the chunk.
    142         OSCL_LEAVE(OsclErrArgument);
    143     }
    144 
    145     // Put the returned chunk in the free pool
    146     iFreeMemChunkList.push_back(p);
    147 
    148     // Notify the observer about free chunk available if waiting for such callback
    149     if (iCheckNextAvailableFreeChunk)
    150     {
    151         iCheckNextAvailableFreeChunk = false;
    152         if (iObserver)
    153         {
    154             iObserver->freechunkavailable(iNextAvailableContextData);
    155         }
    156     }
    157 
    158     // Decrement the refcount since deallocating succeeded
    159     removeRef();
    160 }
    161 
    162 
    163 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::notifyfreechunkavailable(OsclMemPoolFixedChunkAllocatorObserver& obs, OsclAny* aContextData)
    164 {
    165     iCheckNextAvailableFreeChunk = true;
    166     iObserver = &obs;
    167     iNextAvailableContextData = aContextData;
    168 }
    169 
    170 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::CancelFreeChunkAvailableCallback()
    171 {
    172     iCheckNextAvailableFreeChunk = false;
    173     iObserver = NULL;
    174     iNextAvailableContextData = NULL;
    175 }
    176 
    177 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::createmempool()
    178 {
    179     if (iChunkSize == 0 || iNumChunk == 0)
    180     {
    181         OSCL_LEAVE(OsclErrArgument);
    182     }
    183 
    184     // Create one block of memory for the memory pool
    185     iChunkSizeMemAligned = oscl_mem_aligned_size(iChunkSize);
    186     int32 leavecode = 0;
    187     if (iMemPoolAllocator)
    188     {
    189         OSCL_TRY(leavecode, iMemPool = iMemPoolAllocator->ALLOCATE(iNumChunk * iChunkSizeMemAligned));
    190     }
    191     else
    192     {
    193         iMemPool = OSCL_MALLOC(iNumChunk * iChunkSizeMemAligned);
    194     }
    195 
    196     if (leavecode || iMemPool == NULL)
    197     {
    198         OSCL_LEAVE(OsclErrNoMemory);
    199     }
    200 
    201 #if OSCL_MEM_FILL_WITH_PATTERN
    202     oscl_memset(iMemPool, 0x55, iNumChunk*iChunkSizeMemAligned);
    203 #endif
    204 
    205     // Set up the free mem chunk list vector
    206     iFreeMemChunkList.reserve(iNumChunk);
    207     uint8* chunkptr = (uint8*)iMemPool;
    208 
    209     for (uint32 i = 0; i < iNumChunk; ++i)
    210     {
    211         iFreeMemChunkList.push_back((OsclAny*)chunkptr);
    212         chunkptr += iChunkSizeMemAligned;
    213     }
    214 }
    215 
    216 
    217 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::destroymempool()
    218 {
    219     // If ref count reaches 0 then destroy this object
    220     if (iRefCount <= 0)
    221     {
    222 #if OSCL_MEM_CHECK_ALL_MEMPOOL_CHUNKS_ARE_RETURNED
    223         // Assert if all of the chunks were not returned
    224         OSCL_ASSERT(iFreeMemChunkList.size() == iNumChunk);
    225 #endif
    226 
    227         iFreeMemChunkList.clear();
    228 
    229         if (iMemPool)
    230         {
    231             if (iMemPoolAllocator)
    232             {
    233                 iMemPoolAllocator->deallocate(iMemPool);
    234             }
    235             else
    236             {
    237                 OSCL_FREE(iMemPool);
    238             }
    239 
    240             iMemPool = NULL;
    241         }
    242     }
    243 }
    244 
    245 
    246 
    247 /**
    248  *  OsclMemPoolResizableAllocator section
    249  **/
    250 
    251 #define OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER 10
    252 #define OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN 0x55
    253 #define OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN 0xAA
    254 #define OSCLMEMPOOLRESIZABLEALLOCATOR_MIN_BUFFERSIZE 8
    255 
    256 OSCL_EXPORT_REF OsclMemPoolResizableAllocator::OsclMemPoolResizableAllocator(uint32 aMemPoolBufferSize, uint32 aMemPoolBufferNumLimit, uint32 aExpectedNumBlocksPerBuffer, Oscl_DefAlloc* gen_alloc) :
    257         iMemPoolBufferSize(aMemPoolBufferSize),
    258         iMemPoolBufferNumLimit(aMemPoolBufferNumLimit),
    259         iExpectedNumBlocksPerBuffer(aExpectedNumBlocksPerBuffer),
    260         iMemPoolBufferAllocator(gen_alloc),
    261         iCheckNextAvailable(false),
    262         iRequestedNextAvailableSize(0),
    263         iNextAvailableContextData(NULL),
    264         iObserver(NULL),
    265         iCheckFreeMemoryAvailable(false),
    266         iRequestedAvailableFreeMemSize(0),
    267         iFreeMemContextData(NULL),
    268         iFreeMemPoolObserver(NULL),
    269         iRefCount(1),
    270         iEnableNullPtrReturn(false)
    271 {
    272     OSCL_ASSERT(aMemPoolBufferSize > OSCLMEMPOOLRESIZABLEALLOCATOR_MIN_BUFFERSIZE);
    273 
    274     iMaxNewMemPoolBufferSz = 0;
    275     // Calculate and save the mem aligned size of buffer and block info header structures
    276     iBufferInfoAlignedSize = oscl_mem_aligned_size(sizeof(MemPoolBufferInfo));
    277     iBlockInfoAlignedSize = oscl_mem_aligned_size(sizeof(MemPoolBlockInfo));
    278 
    279     // Pre-allocate memory for vector
    280     if (iMemPoolBufferNumLimit > 0)
    281     {
    282         iMemPoolBufferList.reserve(iMemPoolBufferNumLimit);
    283     }
    284     else
    285     {
    286         iMemPoolBufferList.reserve(2);
    287     }
    288 
    289     // Determine the size of memory pool buffer and create one
    290     uint32 buffersize = oscl_mem_aligned_size(iMemPoolBufferSize) + iBufferInfoAlignedSize;
    291     if (iExpectedNumBlocksPerBuffer > 0)
    292     {
    293         buffersize += (iExpectedNumBlocksPerBuffer * iBlockInfoAlignedSize);
    294     }
    295     else
    296     {
    297         buffersize += (OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER * iBlockInfoAlignedSize);
    298     }
    299 
    300     addnewmempoolbuffer(buffersize);
    301 }
    302 
    303 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::enablenullpointerreturn()
    304 {
    305     iEnableNullPtrReturn = true;
    306 }
    307 
    308 OSCL_EXPORT_REF OsclAny* OsclMemPoolResizableAllocator::allocate(const uint32 aNumBytes)
    309 {
    310     MemPoolBlockInfo* freeblock = NULL;
    311     uint32 alignednumbytes = oscl_mem_aligned_size(aNumBytes);
    312 
    313     if (aNumBytes == 0)
    314     {
    315         OSCL_LEAVE(OsclErrArgument);
    316         // OSCL_UNUSED_RETURN(NULL);    This statement was removed to avoid compiler warning for Unreachable Code
    317     }
    318 
    319     // Find a free block that would accomodate the requested size with a block info header
    320     freeblock = findfreeblock(alignednumbytes + iBlockInfoAlignedSize);
    321     if (freeblock == NULL)
    322     {
    323         //We could not find the new buffer, the only way we can allocate the chunk is by allocating newmempool buffer
    324         //Validate is size is less than the regrow size.
    325         if (iMemPoolBufferNumLimit > 0 && iMaxNewMemPoolBufferSz > 0 && iMaxNewMemPoolBufferSz < alignednumbytes)
    326         {
    327             //cannot create the new buffer
    328             if (iEnableNullPtrReturn)
    329             {
    330                 return NULL;
    331             }
    332             else
    333             {
    334                 // Leave with resource limitation
    335                 OSCL_LEAVE(OsclErrNoResources);
    336             }
    337 
    338         }
    339         // Check if the requested size is bigger than the specified buffer size
    340         if (alignednumbytes > iMemPoolBufferSize)
    341         {
    342             // Would need to create a new buffer to accomodate this request
    343 
    344             // Check if another buffer can be created
    345             if (iMemPoolBufferNumLimit > 0 && iMemPoolBufferList.size() >= iMemPoolBufferNumLimit)
    346             {
    347                 // Check if there is a memory pool buffer that has no outstanding buffers
    348                 // If present then remove it so a new one can be added
    349                 bool emptybufferfound = false;
    350                 for (uint32 j = 0; j < iMemPoolBufferList.size(); ++j)
    351                 {
    352                     if (iMemPoolBufferList[j]->iNumOutstanding == 0)
    353                     {
    354                         // Free the memory
    355                         if (iMemPoolBufferAllocator)
    356                         {
    357                             iMemPoolBufferAllocator->deallocate((OsclAny*)iMemPoolBufferList[j]);
    358                         }
    359                         else
    360                         {
    361                             OSCL_FREE((OsclAny*)iMemPoolBufferList[j]);
    362                         }
    363 
    364                         // Remove the mempool buffer from the list
    365                         iMemPoolBufferList.erase(iMemPoolBufferList.begin() + j);
    366                         emptybufferfound = true;
    367                         break;
    368                     }
    369                 }
    370 
    371                 // Need to leave and return if empty buffer not found
    372                 if (!emptybufferfound)
    373                 {
    374                     if (iEnableNullPtrReturn)
    375                     {
    376                         return NULL;
    377                     }
    378                     else
    379                     {
    380                         // Leave with resource limitation
    381                         OSCL_LEAVE(OsclErrNoResources);
    382                     }
    383                 }
    384 
    385                 // Continue on to create a new buffer
    386                 OSCL_ASSERT(iMemPoolBufferList.size() < iMemPoolBufferNumLimit);
    387             }
    388 
    389             // Determine the size of memory pool buffer and create one
    390             uint32 buffersize = alignednumbytes + iBufferInfoAlignedSize;
    391             if (iExpectedNumBlocksPerBuffer > 0)
    392             {
    393                 buffersize += (iExpectedNumBlocksPerBuffer * iBlockInfoAlignedSize);
    394             }
    395             else
    396             {
    397                 buffersize += (OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER * iBlockInfoAlignedSize);
    398             }
    399 
    400             MemPoolBufferInfo* newbuffer = addnewmempoolbuffer(buffersize);
    401             OSCL_ASSERT(newbuffer != NULL);
    402             OSCL_ASSERT(newbuffer->iNextFreeBlock != NULL);
    403             freeblock = (MemPoolBlockInfo*)(newbuffer->iNextFreeBlock);
    404             OSCL_ASSERT(freeblock != NULL);
    405             OSCL_ASSERT(freeblock->iBlockSize >= alignednumbytes);
    406         }
    407         else
    408         {
    409             // Check if another buffer can be created
    410             if (iMemPoolBufferNumLimit > 0 && iMemPoolBufferList.size() >= iMemPoolBufferNumLimit)
    411             {
    412                 if (iEnableNullPtrReturn)
    413                 {
    414                     return NULL;
    415                 }
    416                 else
    417                 {
    418                     // Leave with resource limitation
    419                     OSCL_LEAVE(OsclErrNoResources);
    420                 }
    421             }
    422 
    423             // Determine the size of memory pool buffer and create one
    424             uint32 buffersize = oscl_mem_aligned_size(iMemPoolBufferSize) + iBufferInfoAlignedSize;
    425             if (iExpectedNumBlocksPerBuffer > 0)
    426             {
    427                 buffersize += (iExpectedNumBlocksPerBuffer * iBlockInfoAlignedSize);
    428             }
    429             else
    430             {
    431                 buffersize += (OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER * iBlockInfoAlignedSize);
    432             }
    433 
    434             MemPoolBufferInfo* newbuffer = addnewmempoolbuffer(buffersize);
    435             OSCL_ASSERT(newbuffer != NULL);
    436             OSCL_ASSERT(newbuffer->iNextFreeBlock != NULL);
    437             freeblock = (MemPoolBlockInfo*)(newbuffer->iNextFreeBlock);
    438             OSCL_ASSERT(freeblock != NULL);
    439             OSCL_ASSERT(freeblock->iBlockSize >= alignednumbytes);
    440         }
    441 
    442     }
    443 
    444     // Use the free block and return the buffer pointer
    445     OsclAny* bufptr = allocateblock(*freeblock, alignednumbytes);
    446     if (bufptr)
    447     {
    448         addRef();
    449         ++(freeblock->iParentBuffer->iNumOutstanding);
    450     }
    451     return bufptr;
    452 }
    453 
    454 
    455 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::deallocate(OsclAny* aPtr)
    456 {
    457     // Check that the returned pointer is from the memory pool
    458     if (validateblock(aPtr) == false)
    459     {
    460         OSCL_LEAVE(OsclErrArgument);
    461     }
    462 
    463     // Retrieve the block info header and validate the info
    464     uint8* byteptr = (uint8*)aPtr;
    465     MemPoolBlockInfo* retblock = (MemPoolBlockInfo*)(byteptr - iBlockInfoAlignedSize);
    466     OSCL_ASSERT(retblock != NULL);
    467     OSCL_ASSERT(retblock->iBlockPreFence == OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN);
    468     OSCL_ASSERT(retblock->iBlockPostFence == OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN);
    469 
    470     // Return the block to the memory pool buffer
    471     deallocateblock(*retblock);
    472     --(retblock->iParentBuffer->iNumOutstanding);
    473 
    474     // Check if user needs to be notified when block becomes available
    475     if (iCheckNextAvailable)
    476     {
    477         // Check if user is waiting for certain size
    478         if (iRequestedNextAvailableSize == 0)
    479         {
    480             // No so just make the callback
    481             iCheckNextAvailable = false;
    482             if (iObserver)
    483             {
    484                 iObserver->freeblockavailable(iNextAvailableContextData);
    485             }
    486         }
    487         else
    488         {
    489             // Check if the requested size is available now
    490             if (findfreeblock(iRequestedNextAvailableSize + iBlockInfoAlignedSize) != NULL)
    491             {
    492                 iCheckNextAvailable = false;
    493                 if (iObserver)
    494                 {
    495                     iObserver->freeblockavailable(iNextAvailableContextData);
    496                 }
    497             }
    498             else if (iRequestedNextAvailableSize > iMemPoolBufferSize)
    499             {
    500                 // The requested size is bigger than the set buffer size
    501 
    502                 // Check if there is space to grow the buffer,
    503                 if (iMemPoolBufferNumLimit == 0 || iMemPoolBufferList.size() < iMemPoolBufferNumLimit)
    504                 {
    505                     // Available
    506                     iCheckNextAvailable = false;
    507                     if (iObserver)
    508                     {
    509                         iObserver->freeblockavailable(iNextAvailableContextData);
    510                     }
    511                 }
    512                 else
    513                 {
    514                     // Not available so see if there is a buffer with
    515                     // no outstanding buffers which can be destroyed
    516                     // in the next allocate() call.
    517                     bool emptybufferfound = false;
    518                     for (uint32 j = 0; j < iMemPoolBufferList.size(); ++j)
    519                     {
    520                         if (iMemPoolBufferList[j]->iNumOutstanding == 0)
    521                         {
    522                             emptybufferfound = true;
    523                             break;
    524                         }
    525                     }
    526 
    527                     if (emptybufferfound)
    528                     {
    529                         iCheckNextAvailable = false;
    530                         if (iObserver)
    531                         {
    532                             iObserver->freeblockavailable(iNextAvailableContextData);
    533                         }
    534                     }
    535                 }
    536             }
    537         }
    538     }
    539     if (iCheckFreeMemoryAvailable)
    540     {
    541         if (iRequestedAvailableFreeMemSize == 0)
    542         {
    543             // No so just make the callback
    544             iCheckFreeMemoryAvailable = false;
    545             if (iFreeMemPoolObserver)
    546             {
    547                 iFreeMemPoolObserver->freememoryavailable(iFreeMemContextData);
    548             }
    549         }
    550         else
    551         {
    552             // Check if the requested size is available now
    553             if (getAvailableSize() >= iRequestedAvailableFreeMemSize)
    554             {
    555                 iCheckFreeMemoryAvailable = false;
    556                 if (iFreeMemPoolObserver)
    557                 {
    558                     iFreeMemPoolObserver->freememoryavailable(iFreeMemContextData);
    559                 }
    560             }
    561         }
    562     }
    563 
    564     // Decrement the refcount since deallocating succeeded
    565     removeRef();
    566 }
    567 
    568 
    569 OSCL_EXPORT_REF bool OsclMemPoolResizableAllocator::trim(OsclAny* aPtr, uint32 aBytesToFree)
    570 {
    571     // Amount to free has to be aligned
    572     uint32 alignedbytestofree = oscl_mem_aligned_size(aBytesToFree);
    573     if (alignedbytestofree > aBytesToFree)
    574     {
    575         // Not aligned so decrease amount to free by one alignment size
    576         alignedbytestofree -= 8;
    577     }
    578     OSCL_ASSERT(alignedbytestofree <= aBytesToFree);
    579 
    580     // Check that the returned pointer is from the memory pool
    581     if (validateblock(aPtr) == false)
    582     {
    583         OSCL_LEAVE(OsclErrArgument);
    584         // OSCL_UNUSED_RETURN(false);   This statement was removed to avoid compiler warning for Unreachable Code
    585     }
    586 
    587     // Retrieve the block info header and validate the info
    588     uint8* byteptr = (uint8*)aPtr;
    589     MemPoolBlockInfo* resizeblock = (MemPoolBlockInfo*)(byteptr - iBlockInfoAlignedSize);
    590     OSCL_ASSERT(resizeblock != NULL);
    591     OSCL_ASSERT(resizeblock->iBlockPreFence == OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN);
    592     OSCL_ASSERT(resizeblock->iBlockPostFence == OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN);
    593 
    594     if ((resizeblock->iBlockSize - iBlockInfoAlignedSize) < alignedbytestofree)
    595     {
    596         // The bytes to free in the resize is bigger than the original buffer size
    597         OSCL_LEAVE(OsclErrArgument);
    598         // OSCL_UNUSED_RETURN(false);   This statement was removed to avoid compiler warning for Unreachable Code
    599     }
    600 
    601     if (alignedbytestofree < (iBlockInfoAlignedSize + OSCLMEMPOOLRESIZABLEALLOCATOR_MIN_BUFFERSIZE))
    602     {
    603         // The resizing cannot be done since the amount to free doesn't have
    604         // enough space to put in a block info header plus the minimum buffer for the new free block
    605         // So don't do anything and return
    606         return false;
    607     }
    608 
    609     // Create and fill in a block info header for the memory being freed back to memory pool
    610     MemPoolBlockInfo* freeblock = (MemPoolBlockInfo*)((uint8*)resizeblock + resizeblock->iBlockSize - alignedbytestofree);
    611     freeblock->iBlockPreFence = OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN;
    612     freeblock->iNextFreeBlock = NULL;
    613     freeblock->iPrevFreeBlock = NULL;
    614     freeblock->iBlockSize = alignedbytestofree;
    615     freeblock->iBlockBuffer = (uint8*)freeblock + iBlockInfoAlignedSize;
    616     freeblock->iParentBuffer = resizeblock->iParentBuffer;
    617     freeblock->iBlockPostFence = OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN;
    618 
    619     // Return the free block to the memory pool buffer
    620     deallocateblock(*freeblock);
    621 
    622     // Adjust the block info for the block being resized
    623     resizeblock->iBlockSize -= alignedbytestofree;
    624     return true;
    625 }
    626 
    627 
    628 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::notifyfreeblockavailable(OsclMemPoolResizableAllocatorObserver& aObserver, uint32 aRequestedSize, OsclAny* aContextData)
    629 {
    630     // Save the parameters for the next deallocate() call
    631     iCheckNextAvailable = true;
    632     iObserver = &aObserver;
    633     iRequestedNextAvailableSize = oscl_mem_aligned_size(aRequestedSize);
    634     iNextAvailableContextData = aContextData;
    635 }
    636 
    637 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::CancelFreeChunkAvailableCallback()
    638 {
    639     iCheckNextAvailable = false;
    640     iObserver = NULL;
    641     iRequestedNextAvailableSize = 0;
    642     iNextAvailableContextData = NULL;
    643 }
    644 
    645 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::notifyfreememoryavailable(OsclMemPoolResizableAllocatorMemoryObserver& aObserver, uint32 aRequestedSize, OsclAny* aContextData)
    646 {
    647     // Save the parameters for the next deallocate() call
    648     iCheckFreeMemoryAvailable = true;
    649     iFreeMemPoolObserver = &aObserver;
    650     iRequestedAvailableFreeMemSize = oscl_mem_aligned_size(aRequestedSize);
    651     iFreeMemContextData = aContextData;
    652 }
    653 
    654 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::CancelFreeMemoryAvailableCallback()
    655 {
    656     iCheckFreeMemoryAvailable = false;
    657     iFreeMemPoolObserver = NULL;
    658     iRequestedAvailableFreeMemSize = 0;
    659     iFreeMemContextData = NULL;
    660 }
    661 
    662 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::addRef()
    663 {
    664     // Just increment the ref count
    665     ++iRefCount;
    666 }
    667 
    668 
    669 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::removeRef()
    670 {
    671     // Decrement the ref count
    672     --iRefCount;
    673 
    674     // If ref count reaches 0 then destroy this object automatically
    675     if (iRefCount <= 0)
    676     {
    677         OSCL_DELETE(this);
    678     }
    679 }
    680 
    681 
    682 OSCL_EXPORT_REF OsclMemPoolResizableAllocator::~OsclMemPoolResizableAllocator()
    683 {
    684     destroyallmempoolbuffers();
    685 }
    686 
    687 
    688 OsclMemPoolResizableAllocator::MemPoolBufferInfo* OsclMemPoolResizableAllocator::addnewmempoolbuffer(uint32 aBufferAlignedSize)
    689 {
    690     OSCL_ASSERT(aBufferAlignedSize > 0);
    691     OSCL_ASSERT(aBufferAlignedSize == oscl_mem_aligned_size(aBufferAlignedSize));
    692 
    693     // Allocate memory for one buffer
    694     uint8* newbuffer = NULL;
    695     if (iMemPoolBufferAllocator)
    696     {
    697         // Use the outside allocator
    698         newbuffer = (uint8*)iMemPoolBufferAllocator->ALLOCATE(aBufferAlignedSize);
    699     }
    700     else
    701     {
    702         // Allocate directly from heap
    703         newbuffer = (uint8*)OSCL_MALLOC(aBufferAlignedSize);
    704     }
    705 
    706     if (newbuffer == NULL)
    707     {
    708         OSCL_LEAVE(OsclErrNoMemory);
    709         // OSCL_UNUSED_RETURN(NULL);    This statement was removed to avoid compiler warning for Unreachable Code
    710     }
    711 
    712 #if OSCL_MEM_FILL_WITH_PATTERN
    713     oscl_memset(newbuffer, 0x55, aBufferAlignedSize);
    714 #endif
    715 
    716     // Fill in the buffer info header
    717     MemPoolBufferInfo* newbufferinfo = (MemPoolBufferInfo*)newbuffer;
    718     newbufferinfo->iBufferPreFence = OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN;
    719     newbufferinfo->iStartAddr = (OsclAny*)(newbuffer + iBufferInfoAlignedSize);
    720     newbufferinfo->iEndAddr = (OsclAny*)(newbuffer + aBufferAlignedSize - 1);
    721     newbufferinfo->iBufferSize = aBufferAlignedSize;
    722     newbufferinfo->iNumOutstanding = 0;
    723     newbufferinfo->iNextFreeBlock = (MemPoolBlockInfo*)(newbufferinfo->iStartAddr);
    724     newbufferinfo->iAllocatedSz = 0;
    725     newbufferinfo->iBufferPostFence = OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN;
    726 
    727     // Put in one free block in the new buffer
    728     MemPoolBlockInfo* freeblockinfo = (MemPoolBlockInfo*)(newbufferinfo->iStartAddr);
    729     freeblockinfo->iBlockPreFence = OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN;
    730     freeblockinfo->iNextFreeBlock = NULL;
    731     freeblockinfo->iPrevFreeBlock = NULL;
    732     freeblockinfo->iBlockSize = aBufferAlignedSize - iBufferInfoAlignedSize;
    733     freeblockinfo->iBlockBuffer = (uint8*)freeblockinfo + iBlockInfoAlignedSize;
    734     freeblockinfo->iParentBuffer = newbufferinfo;
    735     freeblockinfo->iBlockPostFence = OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN;
    736 
    737     // Add the new buffer to the list
    738     iMemPoolBufferList.push_front(newbufferinfo);
    739 
    740     return newbufferinfo;
    741 }
    742 
    743 
    744 void OsclMemPoolResizableAllocator::destroyallmempoolbuffers()
    745 {
    746     while (iMemPoolBufferList.empty() == false)
    747     {
    748         MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[0];
    749         // Check the buffer
    750         OSCL_ASSERT(bufferinfo != NULL);
    751         OSCL_ASSERT(bufferinfo->iBufferPreFence == OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN);
    752         OSCL_ASSERT(bufferinfo->iBufferPostFence == OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN);
    753         OSCL_ASSERT(bufferinfo->iNumOutstanding == 0);
    754 
    755         // Free the memory
    756         if (iMemPoolBufferAllocator)
    757         {
    758             iMemPoolBufferAllocator->deallocate((OsclAny*)bufferinfo);
    759         }
    760         else
    761         {
    762             OSCL_FREE((OsclAny*)bufferinfo);
    763         }
    764 
    765         iMemPoolBufferList.erase(iMemPoolBufferList.begin());
    766     }
    767 }
    768 
    769 
    770 OsclMemPoolResizableAllocator::MemPoolBlockInfo* OsclMemPoolResizableAllocator::findfreeblock(uint32 aBlockAlignedSize)
    771 {
    772     OSCL_ASSERT(aBlockAlignedSize > 0);
    773     OSCL_ASSERT(aBlockAlignedSize == oscl_mem_aligned_size(aBlockAlignedSize));
    774 
    775     // Go through each mempool buffer and return the first free block that
    776     // is bigger than the specified size
    777 
    778     if (aBlockAlignedSize == 0)
    779     {
    780         // Request should be non-zero
    781         OSCL_LEAVE(OsclErrArgument);
    782         // OSCL_UNUSED_RETURN(NULL);    This statement was removed to avoid compiler warning for Unreachable Code
    783     }
    784 
    785     for (uint32 i = 0; i < iMemPoolBufferList.size(); ++i)
    786     {
    787         MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
    788         MemPoolBlockInfo* blockinfo = bufferinfo->iNextFreeBlock;
    789         while (blockinfo != NULL)
    790         {
    791             if ((blockinfo->iBlockSize/* - iBlockInfoAlignedSize*/) >= aBlockAlignedSize)
    792             {
    793                 // This free block fits the request
    794                 return blockinfo;
    795             }
    796 
    797             // Go to the next free block
    798             blockinfo = blockinfo->iNextFreeBlock;
    799         }
    800     }
    801 
    802     return NULL;
    803 }
    804 
    805 
    806 OsclAny* OsclMemPoolResizableAllocator::allocateblock(MemPoolBlockInfo& aBlockPtr, uint32 aNumAlignedBytes)
    807 {
    808     OSCL_ASSERT(aNumAlignedBytes > 0);
    809     OSCL_ASSERT(aNumAlignedBytes == oscl_mem_aligned_size(aNumAlignedBytes));
    810 
    811     if (aNumAlignedBytes == 0)
    812     {
    813         OSCL_LEAVE(OsclErrArgument);
    814         // OSCL_UNUSED_RETURN(NULL);    This statement was removed to avoid compiler warning for Unreachable Code
    815     }
    816 
    817     // Remove the free block from the double linked list
    818     if (aBlockPtr.iPrevFreeBlock == NULL && aBlockPtr.iNextFreeBlock != NULL)
    819     {
    820         // Removing from the beginning of the free list
    821         aBlockPtr.iNextFreeBlock->iPrevFreeBlock = NULL;
    822         aBlockPtr.iParentBuffer->iNextFreeBlock = aBlockPtr.iNextFreeBlock;
    823     }
    824     else if (aBlockPtr.iPrevFreeBlock != NULL && aBlockPtr.iNextFreeBlock == NULL)
    825     {
    826         // Removing from the end of the free list
    827         aBlockPtr.iPrevFreeBlock->iNextFreeBlock = NULL;
    828     }
    829     else if (aBlockPtr.iPrevFreeBlock == NULL && aBlockPtr.iNextFreeBlock == NULL)
    830     {
    831         // Free list becomes empty so update the parent buffer's link
    832         aBlockPtr.iParentBuffer->iNextFreeBlock = NULL;
    833     }
    834     else
    835     {
    836         // Removing from middle of the free list
    837         aBlockPtr.iPrevFreeBlock->iNextFreeBlock = aBlockPtr.iNextFreeBlock;
    838         aBlockPtr.iNextFreeBlock->iPrevFreeBlock = aBlockPtr.iPrevFreeBlock;
    839     }
    840 
    841     aBlockPtr.iNextFreeBlock = NULL;
    842     aBlockPtr.iPrevFreeBlock = NULL;
    843 
    844     aBlockPtr.iParentBuffer->iAllocatedSz += aBlockPtr.iBlockSize;
    845 
    846     // Resize the block if too large
    847     uint32 extraspace = aBlockPtr.iBlockSize - iBlockInfoAlignedSize - aNumAlignedBytes;
    848     if (extraspace > (iBlockInfoAlignedSize + OSCLMEMPOOLRESIZABLEALLOCATOR_MIN_BUFFERSIZE))
    849     {
    850         trim(aBlockPtr.iBlockBuffer, extraspace);
    851     }
    852 
    853 #if OSCL_MEM_FILL_WITH_PATTERN
    854     oscl_memset(aBlockPtr.iBlockBuffer, 0x55, (aBlockPtr.iBlockSize - iBlockInfoAlignedSize));
    855 #endif
    856     return aBlockPtr.iBlockBuffer;
    857 }
    858 
    859 
    860 void OsclMemPoolResizableAllocator::deallocateblock(MemPoolBlockInfo& aBlockPtr)
    861 {
    862     OSCL_ASSERT(aBlockPtr.iParentBuffer);
    863 
    864     MemPoolBufferInfo* bufferinfo = aBlockPtr.iParentBuffer;
    865     MemPoolBlockInfo* rightblockinfo = bufferinfo->iNextFreeBlock;
    866     MemPoolBlockInfo* leftblockinfo = NULL;
    867 
    868     // Go through the free block list and find the free block which would
    869     // become the right neighbor of the block being freed
    870     while (rightblockinfo != NULL)
    871     {
    872         if (&aBlockPtr < rightblockinfo)
    873         {
    874             break;
    875         }
    876         leftblockinfo = rightblockinfo;
    877         rightblockinfo = rightblockinfo->iNextFreeBlock;
    878     }
    879 
    880     // Check where the newly freed block is in the list
    881     if (leftblockinfo == NULL && rightblockinfo == NULL)
    882     {
    883         // The free block list is empty.
    884         // Trivial case so add to list and return to list without merge
    885         bufferinfo->iNextFreeBlock = &aBlockPtr;
    886         aBlockPtr.iNextFreeBlock = NULL;
    887         aBlockPtr.iPrevFreeBlock = NULL;
    888         aBlockPtr.iParentBuffer->iAllocatedSz -= aBlockPtr.iBlockSize;
    889         return;
    890     }
    891     else if (leftblockinfo != NULL && rightblockinfo == NULL)
    892     {
    893         // Adding to the end of the list
    894         OSCL_ASSERT(leftblockinfo->iNextFreeBlock == NULL);
    895 
    896         // Check that the newly freed block doesn't overlap with an existing free block
    897         if (((uint8*)leftblockinfo + leftblockinfo->iBlockSize) > (uint8*)&aBlockPtr)
    898         {
    899             OSCL_LEAVE(OsclErrArgument);
    900         }
    901 
    902         leftblockinfo->iNextFreeBlock = &aBlockPtr;
    903         aBlockPtr.iPrevFreeBlock = leftblockinfo;
    904         aBlockPtr.iNextFreeBlock = NULL;
    905     }
    906     else if (leftblockinfo == NULL && rightblockinfo != NULL)
    907     {
    908         // Adding to the beginning of the list
    909         OSCL_ASSERT(rightblockinfo->iPrevFreeBlock == NULL);
    910 
    911         // Check that the newly freed block doesn't overlap with an existing free block
    912         if (((uint8*)&aBlockPtr + aBlockPtr.iBlockSize) > (uint8*)rightblockinfo)
    913         {
    914             OSCL_LEAVE(OsclErrArgument);
    915         }
    916 
    917         bufferinfo->iNextFreeBlock = &aBlockPtr;
    918         rightblockinfo->iPrevFreeBlock = &aBlockPtr;
    919         aBlockPtr.iPrevFreeBlock = NULL;
    920         aBlockPtr.iNextFreeBlock = rightblockinfo;
    921     }
    922     else
    923     {
    924         // Adding to the middle of the list
    925         OSCL_ASSERT(leftblockinfo->iNextFreeBlock == rightblockinfo);
    926         OSCL_ASSERT(rightblockinfo->iPrevFreeBlock == leftblockinfo);
    927 
    928         // Check that the newly freed block doesn't overlap with the existing free blocks
    929         if (((uint8*)&aBlockPtr + aBlockPtr.iBlockSize) > (uint8*)rightblockinfo ||
    930                 ((uint8*)leftblockinfo + leftblockinfo->iBlockSize) > (uint8*)&aBlockPtr)
    931         {
    932             OSCL_LEAVE(OsclErrArgument);
    933         }
    934 
    935         leftblockinfo->iNextFreeBlock = &aBlockPtr;
    936         rightblockinfo->iPrevFreeBlock = &aBlockPtr;
    937         aBlockPtr.iPrevFreeBlock = leftblockinfo;
    938         aBlockPtr.iNextFreeBlock = rightblockinfo;
    939     }
    940     aBlockPtr.iParentBuffer->iAllocatedSz -= aBlockPtr.iBlockSize;
    941 
    942     // Merge the newly freed block with neighbors if contiguous
    943     // Check which neighbors are contiguous in memory space
    944     bool rightadj = false;
    945     bool leftadj = false;
    946     if (aBlockPtr.iPrevFreeBlock)
    947     {
    948         MemPoolBlockInfo* leftnb = aBlockPtr.iPrevFreeBlock;
    949         if (((uint8*)leftnb + leftnb->iBlockSize) == (uint8*)&aBlockPtr)
    950         {
    951             leftadj = true;
    952         }
    953     }
    954     if (aBlockPtr.iNextFreeBlock)
    955     {
    956         MemPoolBlockInfo* rightnb = aBlockPtr.iNextFreeBlock;
    957         if (((uint8*)&aBlockPtr + aBlockPtr.iBlockSize) == (uint8*)rightnb)
    958         {
    959             rightadj = true;
    960         }
    961     }
    962 
    963     // Do the merge based on the check
    964     if (leftadj == false && rightadj == true)
    965     {
    966         // Merge the right neighbor with the newly freed block
    967         // Update newly freed block's size and remove the right neighbor from the list
    968         MemPoolBlockInfo* midblock = &aBlockPtr;
    969         MemPoolBlockInfo* rightblock = aBlockPtr.iNextFreeBlock;
    970         // Size update
    971         midblock->iBlockSize += rightblock->iBlockSize;
    972         // Right neighbor removal
    973         if (rightblock->iNextFreeBlock)
    974         {
    975             rightblock->iNextFreeBlock->iPrevFreeBlock = midblock;
    976         }
    977         midblock->iNextFreeBlock = rightblock->iNextFreeBlock;
    978     }
    979     else if (leftadj == true && rightadj == false)
    980     {
    981         // Merge the newly freed block with the left neighbor
    982         // Update the left neighbor's block size to include the newly freed block and
    983         // remove the newly freed block from the list
    984         MemPoolBlockInfo* midblock = &aBlockPtr;
    985         MemPoolBlockInfo* leftblock = aBlockPtr.iPrevFreeBlock;
    986         // Size update
    987         leftblock->iBlockSize += midblock->iBlockSize;
    988         // Newly freed block removal
    989         if (midblock->iNextFreeBlock)
    990         {
    991             midblock->iNextFreeBlock->iPrevFreeBlock = leftblock;
    992         }
    993         leftblock->iNextFreeBlock = midblock->iNextFreeBlock;
    994     }
    995     else if (leftadj == true && rightadj == true)
    996     {
    997         // Merge the newly freed block and right neighbor with the left neighbor
    998         // and remove the newly freed block and right neighbor from the list
    999         MemPoolBlockInfo* midblock = &aBlockPtr;
   1000         MemPoolBlockInfo* leftblock = aBlockPtr.iPrevFreeBlock;
   1001         MemPoolBlockInfo* rightblock = aBlockPtr.iNextFreeBlock;
   1002         // Size update
   1003         leftblock->iBlockSize += (midblock->iBlockSize + rightblock->iBlockSize);
   1004         // Newly freed and right neighbor block removal
   1005         if (rightblock->iNextFreeBlock)
   1006         {
   1007             rightblock->iNextFreeBlock->iPrevFreeBlock = leftblock;
   1008         }
   1009         leftblock->iNextFreeBlock = rightblock->iNextFreeBlock;
   1010     }
   1011 }
   1012 
   1013 
   1014 bool OsclMemPoolResizableAllocator::validateblock(OsclAny* aBlockBufPtr)
   1015 {
   1016     uint32 i = 0;
   1017 
   1018     if (aBlockBufPtr == NULL)
   1019     {
   1020         // Invalid pointer
   1021         return false;
   1022     }
   1023 
   1024     // Check if the pointer falls within one of the memory pool buffer's memory address
   1025     for (i = 0; i < iMemPoolBufferList.size(); ++i)
   1026     {
   1027         MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
   1028         if (aBlockBufPtr > bufferinfo->iStartAddr && aBlockBufPtr < bufferinfo->iEndAddr)
   1029         {
   1030             break;
   1031         }
   1032     }
   1033     if (i >= iMemPoolBufferList.size())
   1034     {
   1035         // Parent buffer is not part of this memory pool instance
   1036         return false;
   1037     }
   1038 
   1039     // Retrieve the block info header
   1040     MemPoolBlockInfo* chkblock = (MemPoolBlockInfo*)((uint8*)aBlockBufPtr - iBlockInfoAlignedSize);
   1041 
   1042     if (chkblock->iBlockPreFence != OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN ||
   1043             chkblock->iBlockPostFence != OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN)
   1044     {
   1045         // Memory fence checking failed
   1046         return false;
   1047     }
   1048 
   1049     // Check the parent buffer is one in the list
   1050     MemPoolBufferInfo* parentbuffer = chkblock->iParentBuffer;
   1051     if (parentbuffer == NULL)
   1052     {
   1053         return false;
   1054     }
   1055     for (i = 0; i < iMemPoolBufferList.size(); ++i)
   1056     {
   1057         if (parentbuffer == iMemPoolBufferList[i])
   1058         {
   1059             break;
   1060         }
   1061     }
   1062     if (i >= iMemPoolBufferList.size())
   1063     {
   1064         // Parent buffer is not part of this memory pool instance
   1065         return false;
   1066     }
   1067 
   1068     if (aBlockBufPtr < parentbuffer->iStartAddr || aBlockBufPtr > parentbuffer->iEndAddr)
   1069     {
   1070         // The address of the buffer is not part of the parent buffer
   1071         return false;
   1072     }
   1073 
   1074     if ((OsclAny*)((uint8*)chkblock + chkblock->iBlockSize - 1) > (parentbuffer->iEndAddr))
   1075     {
   1076         // The block size is too big
   1077         return false;
   1078     }
   1079 
   1080     return true;
   1081 }
   1082 
   1083 
   1084 OSCL_EXPORT_REF uint32 OsclMemPoolResizableAllocator::getBufferSize() const
   1085 {
   1086     if (iMemPoolBufferNumLimit == 0)
   1087         OSCL_LEAVE(OsclErrNotSupported);
   1088 
   1089     uint32 bufferSize = 0;
   1090     for (uint32 i = 0; i < iMemPoolBufferList.size(); ++i)
   1091     {
   1092         MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
   1093         bufferSize += getMemPoolBufferSize(bufferinfo);
   1094     }
   1095 
   1096     return bufferSize;
   1097 }
   1098 
   1099 OSCL_EXPORT_REF uint32 OsclMemPoolResizableAllocator::getAllocatedSize() const
   1100 {
   1101     //const uint32 expectedNumBlocksPerBuffer = iExpectedNumBlocksPerBuffer > 0 ? iExpectedNumBlocksPerBuffer : OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER;
   1102     uint32 allocatedSz = 0;
   1103     for (uint32 i = 0; i < iMemPoolBufferList.size(); ++i)
   1104     {
   1105         MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
   1106         allocatedSz += getMemPoolBufferAllocatedSize(bufferinfo);
   1107     }
   1108     return allocatedSz;
   1109 }
   1110 
   1111 OSCL_EXPORT_REF uint32 OsclMemPoolResizableAllocator::getAvailableSize() const
   1112 {
   1113     if (iMemPoolBufferNumLimit == 0)
   1114         OSCL_LEAVE(OsclErrNotSupported);
   1115 
   1116     uint32 availableSize = 0;
   1117     for (uint32 i = 0; i < iMemPoolBufferList.size(); ++i)
   1118     {
   1119         MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
   1120         uint32 memPoolBufferAvailableSz = 0;
   1121         memPoolBufferAvailableSz = (getMemPoolBufferSize(bufferinfo) - getMemPoolBufferAllocatedSize(bufferinfo));
   1122         availableSize += memPoolBufferAvailableSz;
   1123     }
   1124 
   1125     return availableSize;
   1126 }
   1127 
   1128 OSCL_EXPORT_REF uint32 OsclMemPoolResizableAllocator::getLargestContiguousFreeBlockSize() const
   1129 {
   1130     uint32 blockSz = 0;
   1131 
   1132     if (iMemPoolBufferNumLimit > 0)
   1133     {
   1134         for (uint32 i = 0; i < iMemPoolBufferList.size(); ++i)
   1135         {
   1136             MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
   1137             if (bufferinfo)
   1138             {
   1139                 MemPoolBlockInfo* blockinfo = bufferinfo->iNextFreeBlock;
   1140                 while (blockinfo != NULL)
   1141                 {
   1142                     if (blockinfo->iBlockSize > blockSz) blockSz = blockinfo->iBlockSize;
   1143                     blockinfo = blockinfo->iNextFreeBlock;
   1144                 }
   1145             }
   1146         }
   1147     }
   1148     else
   1149         OSCL_LEAVE(OsclErrNotSupported);
   1150 
   1151     if (blockSz > iBlockInfoAlignedSize) blockSz -= iBlockInfoAlignedSize;
   1152     else blockSz = 0;
   1153 
   1154     return blockSz;
   1155 }
   1156 
   1157 OSCL_EXPORT_REF bool OsclMemPoolResizableAllocator::setMaxSzForNewMemPoolBuffer(uint32 aMaxNewMemPoolBufferSz)
   1158 {
   1159     bool retval = true;
   1160     if (iMemPoolBufferNumLimit > 0)
   1161         iMaxNewMemPoolBufferSz = aMaxNewMemPoolBufferSz;
   1162     else
   1163         retval = false;
   1164     return retval;
   1165 }
   1166 
   1167 uint32 OsclMemPoolResizableAllocator::getMemPoolBufferSize(MemPoolBufferInfo* aBufferInfo) const
   1168 {
   1169     uint32 memPoolBufferSz = 0;
   1170 
   1171     if (aBufferInfo)
   1172         memPoolBufferSz = aBufferInfo->iBufferSize;
   1173 
   1174     return memPoolBufferSz;
   1175 }
   1176 
   1177 uint32 OsclMemPoolResizableAllocator::getMemPoolBufferAllocatedSize(MemPoolBufferInfo* aBufferInfo) const
   1178 {
   1179     return aBufferInfo->iAllocatedSz;
   1180     /*
   1181     uint32 allocatedSz = 0;
   1182     const uint32 expectedNumBlocksPerBuffer = iExpectedNumBlocksPerBuffer > 0 ? iExpectedNumBlocksPerBuffer : OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER;
   1183 
   1184     if (aBufferInfo)
   1185     {
   1186         if (aBufferInfo->iNumOutstanding > expectedNumBlocksPerBuffer)
   1187         {
   1188             allocatedSz = (aBufferInfo->iAllocatedSz - (expectedNumBlocksPerBuffer * iBlockInfoAlignedSize));
   1189         }
   1190         else
   1191         {
   1192             allocatedSz = (aBufferInfo->iAllocatedSz - (aBufferInfo->iNumOutstanding * iBlockInfoAlignedSize));
   1193         }
   1194     }
   1195     return allocatedSz;
   1196     */
   1197 }
   1198 
   1199 uint32 OsclMemPoolResizableAllocator::memoryPoolBufferMgmtOverhead() const
   1200 {
   1201     uint32 overheadBytes = iBufferInfoAlignedSize;
   1202     if (iExpectedNumBlocksPerBuffer > 0)
   1203     {
   1204         overheadBytes += (iExpectedNumBlocksPerBuffer * iBlockInfoAlignedSize);
   1205     }
   1206     else
   1207     {
   1208         overheadBytes += (OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER * iBlockInfoAlignedSize);
   1209     }
   1210     return overheadBytes;
   1211 }
   1212