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; } }