OSCL_EXPORT_REF OsclSharedPtr<PVMFMediaCmd>
PVMFMediaCmd::createMediaCmd(const PVMFMediaMsgHeader* msgHeader,
                             Oscl_DefAlloc* gen_alloc)
{
    // allocate enough room
    uint8* my_ptr;
    OsclRefCounter* my_refcnt;

    uint aligned_media_data_size =
        oscl_mem_aligned_size(sizeof(PVMFMediaCmd));

    // must compute the aligned size for PVMFMediaCmd.
    if (gen_alloc)
    {
        uint aligned_refcnt_size =
            oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
        uint aligned_cleanup_size =
            oscl_mem_aligned_size(sizeof(MediaCmdCleanupDA));

        my_ptr = (uint8*) gen_alloc->ALLOCATE(aligned_refcnt_size +
                                              aligned_cleanup_size +
                                              aligned_media_data_size +
                                              sizeof(PVMFMediaMsgHeader));

        MediaCmdCleanupDA *my_cleanup =
            OSCL_PLACEMENT_NEW(my_ptr + aligned_refcnt_size, MediaCmdCleanupDA(gen_alloc));
        my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterDA(my_ptr, my_cleanup));
        my_ptr += aligned_refcnt_size + aligned_cleanup_size;

    }
    else
    {
        OsclMemAllocator my_alloc;
        uint aligned_refcnt_size =
            oscl_mem_aligned_size(sizeof(OsclRefCounterSA<MediaCmdCleanupSA>));
        my_ptr = (uint8*) my_alloc.ALLOCATE(aligned_refcnt_size +
                                            aligned_media_data_size +
                                            sizeof(PVMFMediaMsgHeader));
        my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA<MediaCmdCleanupSA>(my_ptr));
        my_ptr += aligned_refcnt_size;
    }

    PVMFMediaCmd *media_cmd_ptr = OSCL_PLACEMENT_NEW(my_ptr, PVMFMediaCmd());

    media_cmd_ptr->hdr_ptr =
        OSCL_PLACEMENT_NEW(my_ptr + aligned_media_data_size, PVMFMediaMsgHeader());

    media_cmd_ptr->hdr_ptr->timestamp = msgHeader->timestamp;
    media_cmd_ptr->hdr_ptr->duration = msgHeader->duration;
    media_cmd_ptr->hdr_ptr->stream_id = msgHeader->stream_id;
    media_cmd_ptr->hdr_ptr->seqnum    = msgHeader->seqnum;
    media_cmd_ptr->hdr_ptr->format_id = msgHeader->format_id;
    media_cmd_ptr->hdr_ptr->format_spec_info = msgHeader->format_spec_info;

    OsclSharedPtr<PVMFMediaCmd> shared_media_data(media_cmd_ptr, my_refcnt);

    return shared_media_data;
}
        virtual void destruct_and_dealloc(OsclAny* ptr)
        {
            uint8* tmp_ptr = (uint8*) ptr;
            uint aligned_size =
                oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
            // skip the refcounter
            tmp_ptr += aligned_size;
            // skip the MediaData Cleanup
            aligned_size = oscl_mem_aligned_size(sizeof(MediaCmdCleanupDA));
            tmp_ptr += aligned_size;

            PVMFMediaCmd* mcmd_ptr = reinterpret_cast<PVMFMediaCmd*>(tmp_ptr);
            mcmd_ptr->~PVMFMediaCmd();
            gen_alloc->deallocate(ptr);
        }
OsclMemPoolResizableAllocator::MemPoolBlockInfo* OsclMemPoolResizableAllocator::findfreeblock(uint32 aBlockAlignedSize)
{
    OSCL_ASSERT(aBlockAlignedSize > 0);
    OSCL_ASSERT(aBlockAlignedSize == oscl_mem_aligned_size(aBlockAlignedSize));

    // Go through each mempool buffer and return the first free block that
    // is bigger than the specified size

    if (aBlockAlignedSize == 0)
    {
        // Request should be non-zero
        OSCL_LEAVE(OsclErrArgument);
        // OSCL_UNUSED_RETURN(NULL);    This statement was removed to avoid compiler warning for Unreachable Code
    }

    for (uint32 i = 0; i < iMemPoolBufferList.size(); ++i)
    {
        MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
        MemPoolBlockInfo* blockinfo = bufferinfo->iNextFreeBlock;
        while (blockinfo != NULL)
        {
            if ((blockinfo->iBlockSize/* - iBlockInfoAlignedSize*/) >= aBlockAlignedSize)
            {
                // This free block fits the request
                return blockinfo;
            }

            // Go to the next free block
            blockinfo = blockinfo->iNextFreeBlock;
        }
    }

    return NULL;
}
OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::notifyfreememoryavailable(OsclMemPoolResizableAllocatorMemoryObserver& aObserver, uint32 aRequestedSize, OsclAny* aContextData)
{
    // Save the parameters for the next deallocate() call
    iCheckFreeMemoryAvailable = true;
    iFreeMemPoolObserver = &aObserver;
    iRequestedAvailableFreeMemSize = oscl_mem_aligned_size(aRequestedSize);
    iFreeMemContextData = aContextData;
}
OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::notifyfreeblockavailable(OsclMemPoolResizableAllocatorObserver& aObserver, uint32 aRequestedSize, OsclAny* aContextData)
{
    // Save the parameters for the next deallocate() call
    iCheckNextAvailable = true;
    iObserver = &aObserver;
    iRequestedNextAvailableSize = oscl_mem_aligned_size(aRequestedSize);
    iNextAvailableContextData = aContextData;
}
OSCL_EXPORT_REF OsclMemPoolResizableAllocator::OsclMemPoolResizableAllocator(uint32 aMemPoolBufferSize, uint32 aMemPoolBufferNumLimit, uint32 aExpectedNumBlocksPerBuffer, Oscl_DefAlloc* gen_alloc) :
        iMemPoolBufferSize(aMemPoolBufferSize),
        iMemPoolBufferNumLimit(aMemPoolBufferNumLimit),
        iExpectedNumBlocksPerBuffer(aExpectedNumBlocksPerBuffer),
        iMemPoolBufferAllocator(gen_alloc),
        iCheckNextAvailable(false),
        iRequestedNextAvailableSize(0),
        iNextAvailableContextData(NULL),
        iObserver(NULL),
        iCheckFreeMemoryAvailable(false),
        iRequestedAvailableFreeMemSize(0),
        iFreeMemContextData(NULL),
        iFreeMemPoolObserver(NULL),
        iRefCount(1),
        iEnableNullPtrReturn(false)
{
    OSCL_ASSERT(aMemPoolBufferSize > OSCLMEMPOOLRESIZABLEALLOCATOR_MIN_BUFFERSIZE);

    iMaxNewMemPoolBufferSz = 0;
    // Calculate and save the mem aligned size of buffer and block info header structures
    iBufferInfoAlignedSize = oscl_mem_aligned_size(sizeof(MemPoolBufferInfo));
    iBlockInfoAlignedSize = oscl_mem_aligned_size(sizeof(MemPoolBlockInfo));

    // Pre-allocate memory for vector
    if (iMemPoolBufferNumLimit > 0)
    {
        iMemPoolBufferList.reserve(iMemPoolBufferNumLimit);
    }
    else
    {
        iMemPoolBufferList.reserve(2);
    }

    // Determine the size of memory pool buffer and create one
    uint32 buffersize = oscl_mem_aligned_size(iMemPoolBufferSize) + iBufferInfoAlignedSize;
    if (iExpectedNumBlocksPerBuffer > 0)
    {
        buffersize += (iExpectedNumBlocksPerBuffer * iBlockInfoAlignedSize);
    }
    else
    {
        buffersize += (OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER * iBlockInfoAlignedSize);
    }

    addnewmempoolbuffer(buffersize);
}
OSCL_EXPORT_REF bool OsclMemPoolResizableAllocator::trim(OsclAny* aPtr, uint32 aBytesToFree)
{
    // Amount to free has to be aligned
    uint32 alignedbytestofree = oscl_mem_aligned_size(aBytesToFree);
    if (alignedbytestofree > aBytesToFree)
    {
        // Not aligned so decrease amount to free by one alignment size
        alignedbytestofree -= 8;
    }
    OSCL_ASSERT(alignedbytestofree <= aBytesToFree);

    // Check that the returned pointer is from the memory pool
    if (validateblock(aPtr) == false)
    {
        OSCL_LEAVE(OsclErrArgument);
        // OSCL_UNUSED_RETURN(false);   This statement was removed to avoid compiler warning for Unreachable Code
    }

    // Retrieve the block info header and validate the info
    uint8* byteptr = (uint8*)aPtr;
    MemPoolBlockInfo* resizeblock = (MemPoolBlockInfo*)(byteptr - iBlockInfoAlignedSize);
    OSCL_ASSERT(resizeblock != NULL);
    OSCL_ASSERT(resizeblock->iBlockPreFence == OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN);
    OSCL_ASSERT(resizeblock->iBlockPostFence == OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN);

    if ((resizeblock->iBlockSize - iBlockInfoAlignedSize) < alignedbytestofree)
    {
        // The bytes to free in the resize is bigger than the original buffer size
        OSCL_LEAVE(OsclErrArgument);
        // OSCL_UNUSED_RETURN(false);   This statement was removed to avoid compiler warning for Unreachable Code
    }

    if (alignedbytestofree < (iBlockInfoAlignedSize + OSCLMEMPOOLRESIZABLEALLOCATOR_MIN_BUFFERSIZE))
    {
        // The resizing cannot be done since the amount to free doesn't have
        // enough space to put in a block info header plus the minimum buffer for the new free block
        // So don't do anything and return
        return false;
    }

    // Create and fill in a block info header for the memory being freed back to memory pool
    MemPoolBlockInfo* freeblock = (MemPoolBlockInfo*)((uint8*)resizeblock + resizeblock->iBlockSize - alignedbytestofree);
    freeblock->iBlockPreFence = OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN;
    freeblock->iNextFreeBlock = NULL;
    freeblock->iPrevFreeBlock = NULL;
    freeblock->iBlockSize = alignedbytestofree;
    freeblock->iBlockBuffer = (uint8*)freeblock + iBlockInfoAlignedSize;
    freeblock->iParentBuffer = resizeblock->iParentBuffer;
    freeblock->iBlockPostFence = OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN;

    // Return the free block to the memory pool buffer
    deallocateblock(*freeblock);

    // Adjust the block info for the block being resized
    resizeblock->iBlockSize -= alignedbytestofree;
    return true;
}
OsclMemPoolResizableAllocator::MemPoolBufferInfo* OsclMemPoolResizableAllocator::addnewmempoolbuffer(uint32 aBufferAlignedSize)
{
    OSCL_ASSERT(aBufferAlignedSize > 0);
    OSCL_ASSERT(aBufferAlignedSize == oscl_mem_aligned_size(aBufferAlignedSize));

    // Allocate memory for one buffer
    uint8* newbuffer = NULL;
    if (iMemPoolBufferAllocator)
    {
        // Use the outside allocator
        newbuffer = (uint8*)iMemPoolBufferAllocator->ALLOCATE(aBufferAlignedSize);
    }
    else
    {
        // Allocate directly from heap
        newbuffer = (uint8*)OSCL_MALLOC(aBufferAlignedSize);
    }

    if (newbuffer == NULL)
    {
        OSCL_LEAVE(OsclErrNoMemory);
        // OSCL_UNUSED_RETURN(NULL);    This statement was removed to avoid compiler warning for Unreachable Code
    }

#if OSCL_MEM_FILL_WITH_PATTERN
    oscl_memset(newbuffer, 0x55, aBufferAlignedSize);
#endif

    // Fill in the buffer info header
    MemPoolBufferInfo* newbufferinfo = (MemPoolBufferInfo*)newbuffer;
    newbufferinfo->iBufferPreFence = OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN;
    newbufferinfo->iStartAddr = (OsclAny*)(newbuffer + iBufferInfoAlignedSize);
    newbufferinfo->iEndAddr = (OsclAny*)(newbuffer + aBufferAlignedSize - 1);
    newbufferinfo->iBufferSize = aBufferAlignedSize;
    newbufferinfo->iNumOutstanding = 0;
    newbufferinfo->iNextFreeBlock = (MemPoolBlockInfo*)(newbufferinfo->iStartAddr);
    newbufferinfo->iAllocatedSz = 0;
    newbufferinfo->iBufferPostFence = OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN;

    // Put in one free block in the new buffer
    MemPoolBlockInfo* freeblockinfo = (MemPoolBlockInfo*)(newbufferinfo->iStartAddr);
    freeblockinfo->iBlockPreFence = OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN;
    freeblockinfo->iNextFreeBlock = NULL;
    freeblockinfo->iPrevFreeBlock = NULL;
    freeblockinfo->iBlockSize = aBufferAlignedSize - iBufferInfoAlignedSize;
    freeblockinfo->iBlockBuffer = (uint8*)freeblockinfo + iBlockInfoAlignedSize;
    freeblockinfo->iParentBuffer = newbufferinfo;
    freeblockinfo->iBlockPostFence = OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN;

    // Add the new buffer to the list
    iMemPoolBufferList.push_front(newbufferinfo);

    return newbufferinfo;
}
 virtual void destruct_and_dealloc(OsclAny* ptr)
 {
     uint8* tmp_ptr = (uint8*) ptr;
     uint aligned_refcnt_size =
         oscl_mem_aligned_size(sizeof(OsclRefCounterSA<MediaCmdCleanupSA>));
     tmp_ptr += aligned_refcnt_size;
     PVMFMediaCmd* mcmd_ptr = reinterpret_cast<PVMFMediaCmd*>(tmp_ptr);
     mcmd_ptr->~PVMFMediaCmd();
     OsclMemAllocator alloc;
     alloc.deallocate(ptr);
 }
OsclAny* OsclMemPoolResizableAllocator::allocateblock(MemPoolBlockInfo& aBlockPtr, uint32 aNumAlignedBytes)
{
    OSCL_ASSERT(aNumAlignedBytes > 0);
    OSCL_ASSERT(aNumAlignedBytes == oscl_mem_aligned_size(aNumAlignedBytes));

    if (aNumAlignedBytes == 0)
    {
        OSCL_LEAVE(OsclErrArgument);
        // OSCL_UNUSED_RETURN(NULL);    This statement was removed to avoid compiler warning for Unreachable Code
    }

    // Remove the free block from the double linked list
    if (aBlockPtr.iPrevFreeBlock == NULL && aBlockPtr.iNextFreeBlock != NULL)
    {
        // Removing from the beginning of the free list
        aBlockPtr.iNextFreeBlock->iPrevFreeBlock = NULL;
        aBlockPtr.iParentBuffer->iNextFreeBlock = aBlockPtr.iNextFreeBlock;
    }
    else if (aBlockPtr.iPrevFreeBlock != NULL && aBlockPtr.iNextFreeBlock == NULL)
    {
        // Removing from the end of the free list
        aBlockPtr.iPrevFreeBlock->iNextFreeBlock = NULL;
    }
    else if (aBlockPtr.iPrevFreeBlock == NULL && aBlockPtr.iNextFreeBlock == NULL)
    {
        // Free list becomes empty so update the parent buffer's link
        aBlockPtr.iParentBuffer->iNextFreeBlock = NULL;
    }
    else
    {
        // Removing from middle of the free list
        aBlockPtr.iPrevFreeBlock->iNextFreeBlock = aBlockPtr.iNextFreeBlock;
        aBlockPtr.iNextFreeBlock->iPrevFreeBlock = aBlockPtr.iPrevFreeBlock;
    }

    aBlockPtr.iNextFreeBlock = NULL;
    aBlockPtr.iPrevFreeBlock = NULL;

    aBlockPtr.iParentBuffer->iAllocatedSz += aBlockPtr.iBlockSize;

    // Resize the block if too large
    uint32 extraspace = aBlockPtr.iBlockSize - iBlockInfoAlignedSize - aNumAlignedBytes;
    if (extraspace > (iBlockInfoAlignedSize + OSCLMEMPOOLRESIZABLEALLOCATOR_MIN_BUFFERSIZE))
    {
        trim(aBlockPtr.iBlockBuffer, extraspace);
    }

#if OSCL_MEM_FILL_WITH_PATTERN
    oscl_memset(aBlockPtr.iBlockBuffer, 0x55, (aBlockPtr.iBlockSize - iBlockInfoAlignedSize));
#endif
    return aBlockPtr.iBlockBuffer;
}
TPVStatusCode H223LowerLayer::Open()
{
    unsigned pdu_rate = (unsigned)(1000.0 / (float)H223_MIN_SAMPLE_INTERVAL + .5) + 1;
    iMemFragmentAlloc = OSCL_NEW(PVMFBufferPoolAllocator, ());
    iMemFragmentAlloc->SetLeaveOnAllocFailure(false);
    iMemFragmentAlloc->size((uint16)(pdu_rate*2), (uint16)(iSendPduSz + H223_SEND_PDU_SIZE_EXTRA));

    iMediaMsgPoolAlloc = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (pdu_rate));
    iMediaMsgPoolAlloc->enablenullpointerreturn();

    uint media_data_imp_size = oscl_mem_aligned_size(sizeof(PVMFMediaFragGroup<OsclMemAllocator>)) +
                               oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
    iMediaDataImplMemAlloc = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (pdu_rate, media_data_imp_size));
    iMediaDataImplMemAlloc->enablenullpointerreturn();
    iDispatchPacketAlloc = OSCL_NEW(PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>, (pdu_rate, 30, iMediaDataImplMemAlloc));
    iDispatchPacketAlloc->create();

    iDemuxBufferSize = (uint32)((float)(H223_DEMUX_BUFFER_INTERVAL_MS * iBitrate) / 8000.0);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223LowerLayer::Open iBitrate=%d, iDemuxBufferSize=%d", iBitrate, iDemuxBufferSize));
    iDemuxBufferPos = iDemuxBuffer = (uint8*)OSCL_DEFAULT_MALLOC(H223_DEMUX_BUFFER_SIZE);
    iIdleSyncCheckBuffer = (uint8*)OSCL_DEFAULT_MALLOC(H223_DEMUX_BUFFER_SIZE);
    return EPVT_Success;
}
OSCL_EXPORT_REF void ThreadSafeMemPoolFixedChunkAllocator::createmempool()
{
    if (iChunkSize == 0 || iNumChunk == 0)
    {
        OSCL_LEAVE(OsclErrArgument);
    }

    // Create one block of memory for the memory pool
    iChunkSizeMemAligned = oscl_mem_aligned_size(iChunkSize);
    int32 leavecode = 0;
    if (iMemPoolAllocator)
    {
        OSCL_TRY(leavecode, iMemPool = iMemPoolAllocator->ALLOCATE(iNumChunk * iChunkSizeMemAligned));
    }
    else
    {
        OSCL_TRY(leavecode, iMemPool = OSCL_MALLOC(iNumChunk * iChunkSizeMemAligned));
    }

    if (leavecode || iMemPool == NULL)
    {
        OSCL_LEAVE(OsclErrNoMemory);
    }

#if OSCL_MEM_FILL_WITH_PATTERN
    oscl_memset(iMemPool, 0x55, iNumChunk*iChunkSizeMemAligned);
#endif

    // Set up the free mem chunk list vector
    iFreeMemChunkList.reserve(iNumChunk);
    uint8* chunkptr = (uint8*)iMemPool;

    for (uint32 i = 0; i < iNumChunk; ++i)
    {
        iFreeMemChunkList.push_back((OsclAny*)chunkptr);
        chunkptr += iChunkSizeMemAligned;
    }
}
OSCL_EXPORT_REF OsclAny* OsclMemPoolResizableAllocator::allocate(const uint32 aNumBytes)
{
    MemPoolBlockInfo* freeblock = NULL;
    uint32 alignednumbytes = oscl_mem_aligned_size(aNumBytes);

    if (aNumBytes == 0)
    {
        OSCL_LEAVE(OsclErrArgument);
        // OSCL_UNUSED_RETURN(NULL);    This statement was removed to avoid compiler warning for Unreachable Code
    }

    // Find a free block that would accomodate the requested size with a block info header
    freeblock = findfreeblock(alignednumbytes + iBlockInfoAlignedSize);
    if (freeblock == NULL)
    {
        //We could not find a free buffer of requested size. This could be due to:
        //1) We have not created even a single parent chunk (or in other words this is the first allocation)
        //2) We are out of memory and might need to expand


        // Check if the requested size is bigger than the specified buffer size
        // Some of the users of this allocator, count on the allocator to expand beyond the original size
        // specified in the constructor. These users do NOT use setMaxSzForNewMemPoolBuffer to control expansion size.
        // If they did then it is wrong usage and we fail the allocation.
        // For example the allocator was intialized with 200KB size,
        // and overtime a request is made for say 300KB. Users of the allocator expect the allocator to do one of the following:
        // 1) If iMemPoolBufferNumLimit has been set and it has been reached then see
        // if one of older blocks can be freed up and we allocate a new block of 300KB. If we cannot then alloc will fail.
        // 2) If iMemPoolBufferNumLimit has not set then simply allocate a new block of 300 KB. Note that if iMemPoolBufferNumLimit
        // is not set allocator expands indefinitely.
        if (alignednumbytes > iMemPoolBufferSize)
        {
            if (iMaxNewMemPoolBufferSz != 0)
            {
                //wrong usage - fail allocation
                if (iEnableNullPtrReturn)
                {
                    return NULL;
                }
                else
                {
                    // Leave with resource limitation
                    OSCL_LEAVE(OsclErrNoResources);
                }
            }
            // Would need to create a new buffer to accomodate this request
            // Check if another buffer can be created
            if (iMemPoolBufferNumLimit > 0 && iMemPoolBufferList.size() >= iMemPoolBufferNumLimit)
            {
                // Check if there is a memory pool buffer that has no outstanding buffers
                // If present then remove it so a new one can be added
                bool emptybufferfound = false;
                for (uint32 j = 0; j < iMemPoolBufferList.size(); ++j)
                {
                    if (iMemPoolBufferList[j]->iNumOutstanding == 0)
                    {
                        // Free the memory
                        if (iMemPoolBufferAllocator)
                        {
                            iMemPoolBufferAllocator->deallocate((OsclAny*)iMemPoolBufferList[j]);
                        }
                        else
                        {
                            OSCL_FREE((OsclAny*)iMemPoolBufferList[j]);
                        }

                        // Remove the mempool buffer from the list
                        iMemPoolBufferList.erase(iMemPoolBufferList.begin() + j);
                        emptybufferfound = true;
                        break;
                    }
                }
                // Need to leave and return if empty buffer not found
                if (!emptybufferfound)
                {
                    if (iEnableNullPtrReturn)
                    {
                        return NULL;
                    }
                    else
                    {
                        // Leave with resource limitation
                        OSCL_LEAVE(OsclErrNoResources);
                    }
                }
                // Continue on to create a new buffer
                OSCL_ASSERT(iMemPoolBufferList.size() < iMemPoolBufferNumLimit);
            }
            // Determine the size of memory pool buffer and create one
            uint32 buffersize = alignednumbytes + iBufferInfoAlignedSize;
            if (iExpectedNumBlocksPerBuffer > 0)
            {
                buffersize += (iExpectedNumBlocksPerBuffer * iBlockInfoAlignedSize);
            }
            else
            {
                buffersize += (OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER * iBlockInfoAlignedSize);
            }

            MemPoolBufferInfo* newbuffer = addnewmempoolbuffer(buffersize);
            OSCL_ASSERT(newbuffer != NULL);
            OSCL_ASSERT(newbuffer->iNextFreeBlock != NULL);
            freeblock = (MemPoolBlockInfo*)(newbuffer->iNextFreeBlock);
            OSCL_ASSERT(freeblock != NULL);
            OSCL_ASSERT(freeblock->iBlockSize >= alignednumbytes);
        }
        else
        {
            // Check if another buffer can be created
            if (iMemPoolBufferNumLimit > 0 && iMemPoolBufferList.size() >= iMemPoolBufferNumLimit)
            {
                if (iEnableNullPtrReturn)
                {
                    return NULL;
                }
                else
                {
                    // Leave with resource limitation
                    OSCL_LEAVE(OsclErrNoResources);
                }
            }
            // Determine the size of memory pool buffer and create one
            // By default this allocator expands by iMemPoolBufferSize.
            // iMaxNewMemPoolBufferSz could specify the amount by which this allocator expands.
            // setMaxSzForNewMemPoolBuffer API can be used to control the expansion size.
            uint32 expansion_size = iMemPoolBufferSize;
            if (iMaxNewMemPoolBufferSz != 0)
            {
                expansion_size = iMaxNewMemPoolBufferSz;
            }
            //if alignednumbytes is larger than expansion_size, we cannot satisfy the request, so fail the allocation
            if (alignednumbytes > expansion_size)
            {
                if (iEnableNullPtrReturn)
                {
                    return NULL;
                }
                else
                {
                    // Leave with resource limitation
                    OSCL_LEAVE(OsclErrNoResources);
                }
            }
            uint32 buffersize = oscl_mem_aligned_size(expansion_size) + iBufferInfoAlignedSize;
            if (iExpectedNumBlocksPerBuffer > 0)
            {
                buffersize += (iExpectedNumBlocksPerBuffer * iBlockInfoAlignedSize);
            }
            else
            {
                buffersize += (OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER * iBlockInfoAlignedSize);
            }

            MemPoolBufferInfo* newbuffer = addnewmempoolbuffer(buffersize);
            OSCL_ASSERT(newbuffer != NULL);
            OSCL_ASSERT(newbuffer->iNextFreeBlock != NULL);
            freeblock = (MemPoolBlockInfo*)(newbuffer->iNextFreeBlock);
            OSCL_ASSERT(freeblock != NULL);
            OSCL_ASSERT(freeblock->iBlockSize >= alignednumbytes);
        }

    }

    // Use the free block and return the buffer pointer
    OsclAny* bufptr = allocateblock(*freeblock, alignednumbytes);
    if (bufptr)
    {
        addRef();
        ++(freeblock->iParentBuffer->iNumOutstanding);
    }
    return bufptr;
}
OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::createmempool()
{
    if (iChunkSize == 0 || iNumChunk == 0)
    {
        OSCL_LEAVE(OsclErrArgument);
    }

    if (iChunkAlignment > 0)
    {
        uint32 temp = iChunkAlignment - 1;
        iChunkSizeMemAligned = ((iChunkSize + temp) & (~temp));
    }
    else
    {
        // Create one block of memory for the memory pool
        iChunkSizeMemAligned = oscl_mem_aligned_size(iChunkSize);
    }

    int32 leavecode = 0;
    if (iMemPoolAllocator)
    {
        OSCL_TRY(leavecode, iMemPool = iMemPoolAllocator->ALLOCATE((iNumChunk * iChunkSizeMemAligned) + iChunkAlignment));
    }
    else
    {
        iMemPool = OSCL_MALLOC((iNumChunk * iChunkSizeMemAligned) + iChunkAlignment);
    }

    if (leavecode || iMemPool == NULL)
    {
        OSCL_LEAVE(OsclErrNoMemory);
    }

#if OSCL_MEM_FILL_WITH_PATTERN
    oscl_memset(iMemPool, 0x55, (iNumChunk*iChunkSizeMemAligned) + iChunkAlignment);
#endif

    // Set up the free mem chunk list vector
    iFreeMemChunkList.reserve(iNumChunk);
    uint8* chunkptr = (uint8*)iMemPool;

    // do the alignment if necessary
    if (iChunkAlignment > 0)
    {

        uint32 chunkptrAddr = (uint32) chunkptr;
        uint32 tempAlign = (iChunkAlignment - 1);
        uint32 difference = ((chunkptrAddr + tempAlign) & (~tempAlign)) - chunkptrAddr;

        chunkptr = chunkptr + difference;
        iMemPoolAligned = (OsclAny*) chunkptr;
    }
    else
    {
        iMemPoolAligned = iMemPool;
    }

    for (uint32 i = 0; i < iNumChunk; ++i)
    {
        iFreeMemChunkList.push_back((OsclAny*)chunkptr);
        chunkptr += iChunkSizeMemAligned;
    }
}