ClRcT clPoolFree( ClUint8T* pChunk, void* pCookie) { ClRcT rc = CL_OK; ClPoolHeaderT* pPoolHeader = NULL; ClExtendedPoolHeaderT* pExtendedPoolHeader = NULL; ClUint32T freeChunk = 0; ClUint32T chunkSize = 0; ClFreeListHeaderT* pCurrentFreeList = NULL; NULL_CHECK (pChunk); NULL_CHECK (pCookie); pExtendedPoolHeader = (ClExtendedPoolHeaderT*)pCookie; pPoolHeader = pExtendedPoolHeader->pPoolHeader; CL_POOL_LOG(CL_LOG_SEV_TRACE,"freeing chunk pChunk = %p,extended pool = %p\n", pChunk,(void*)pExtendedPoolHeader); CL_POOL_LOCK (pPoolHeader); chunkSize = pPoolHeader->poolConfig.chunkSize; CL_POOL_REVOKE_SIZE(pPoolHeader->flags,chunkSize); CL_POOL_FREE_LIST_GET (pChunk, pExtendedPoolHeader, pCurrentFreeList); pCurrentFreeList->pChunk = (ClUint8T*)pChunk; pCurrentFreeList->pNextFreeChunk = pExtendedPoolHeader->pFirstFreeChunk; pExtendedPoolHeader->pFirstFreeChunk = pCurrentFreeList; CL_POOL_STATS_UPDATE_FREES (pPoolHeader); freeChunk = ++pExtendedPoolHeader->numFreeChunks; if (freeChunk == 1) { /*Was full before. Move it to partial*/ CL_POOL_LOG(CL_LOG_SEV_TRACE,"Dequeuing extended pool %p from full list and moving the extended pool to partial list\n", (void*)pExtendedPoolHeader); CL_POOL_EXTENDED_FULLLIST_DEQUEUE (pPoolHeader, pExtendedPoolHeader); CL_POOL_EXTENDED_PARTIALLIST_QUEUE (pPoolHeader, pExtendedPoolHeader); } if (freeChunk == pExtendedPoolHeader->numChunks) { /* * Add to the free extended pool list after deleting from the partial * list */ CL_POOL_LOG(CL_LOG_SEV_TRACE, "Dequeuing extended pool %p from partial list and moving the extended pool to free list\n", (void*)pExtendedPoolHeader); CL_POOL_EXTENDED_PARTIALLIST_DEQUEUE(pPoolHeader,pExtendedPoolHeader); CL_POOL_EXTENDED_FREELIST_QUEUE(pPoolHeader,pExtendedPoolHeader); } CL_POOL_UNLOCK(pPoolHeader); rc = CL_OK; return rc; }
ClRcT clPoolAllocate( ClPoolT poolHandle, ClUint8T** ppChunk, void** ppCookie) { ClPoolHeaderT* pPoolHeader = NULL; ClRcT rc = CL_OK; ClFreeListHeaderT* pFreeChunk = NULL; ClExtendedPoolHeaderT* pExtendedPoolHeader = NULL; pPoolHeader = (ClPoolHeaderT*)poolHandle; NULL_CHECK (pPoolHeader); NULL_CHECK (ppChunk); NULL_CHECK (ppCookie); CL_POOL_LOCK (pPoolHeader); if(CL_POOL_GRANT_SIZE(pPoolHeader->flags, pPoolHeader->poolConfig.chunkSize) == CL_FALSE) { rc = CL_POOL_RC(CL_ERR_NO_MEMORY); CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Request of %d bytes would exceed process upper limit\n",pPoolHeader->poolConfig.chunkSize)); goto out_unlock; } /*Check for a partially full queue*/ if (CL_POOL_EXTENDED_PARTIALLIST_EMPTY (pPoolHeader)) { /*Look for an extended pool in the free list*/ if (CL_POOL_EXTENDED_FREELIST_EMPTY (pPoolHeader)) { /*Grow the extended pool*/ rc = clPoolExtend(poolHandle); if(rc != CL_OK) { CL_DEBUG_PRINT (CL_DEBUG_ERROR, ("Pool extension error for chunksize:%d\n", pPoolHeader->poolConfig.chunkSize)); CL_POOL_LOG(CL_LOG_ERROR, "Pool allocate failed to extend %d byte pool of %d chunksize", pPoolHeader->poolConfig.incrementPoolSize, pPoolHeader->poolConfig.chunkSize); goto out_unlock; } } CL_POOL_EXTENDED_FREELIST_POP_DEQUEUE (pPoolHeader, pExtendedPoolHeader); CL_POOL_EXTENDED_PARTIALLIST_QUEUE (pPoolHeader ,pExtendedPoolHeader); } /* * We are here when we have a free chunk: * Point of no-return */ CL_POOL_EXTENDED_PARTIALLIST_POP (pPoolHeader, pExtendedPoolHeader); pFreeChunk = pExtendedPoolHeader->pFirstFreeChunk; pExtendedPoolHeader->pFirstFreeChunk = pFreeChunk->pNextFreeChunk; *ppChunk = (ClUint8T*)pFreeChunk->pChunk; *ppCookie = (void *)pExtendedPoolHeader; CL_POOL_STATS_UPDATE_ALLOCS (pPoolHeader); --pExtendedPoolHeader->numFreeChunks; CL_DEBUG_PRINT (CL_DEBUG_TRACE, ("pExtendedPoolHeader = %p pExtendedPoolHeader->numFreeChunks " "= %d pPoolHeader->poolConfig.chunkSize = %d from address = %p\n", (void*)pExtendedPoolHeader, pExtendedPoolHeader->numFreeChunks, pPoolHeader->poolConfig.chunkSize, (void*)pFreeChunk->pChunk)); /* * Was free partially but now full. * move it to full list. */ if (pExtendedPoolHeader->numFreeChunks == 0) { CL_DEBUG_PRINT (CL_DEBUG_TRACE, ("Dequeuing extended pool %p from partial list and queueing it to " "full list\n", (void*)pExtendedPoolHeader)); CL_POOL_EXTENDED_PARTIALLIST_DEQUEUE (pPoolHeader, pExtendedPoolHeader); CL_POOL_EXTENDED_FULLLIST_QUEUE (pPoolHeader, pExtendedPoolHeader); } out_unlock: CL_POOL_UNLOCK (pPoolHeader); return rc; }