ClRcT
clPoolCreate(
    ClPoolT             *pHandle,
    ClPoolFlagsT        flags,
    const ClPoolConfigT *pPoolConfig)
{
    ClRcT rc = CL_OK;
    ClPoolHeaderT* pPoolHeader = NULL;
    ClUint32T chunkSize = 0;
    ClUint32T incrementPoolSize = 0;
    ClUint32T extendedPools = 0;
    ClUint32T i = 0;

    NULL_CHECK (pPoolConfig);
    NULL_CHECK (pHandle);

    *pHandle = 0;

    /* Validate the chunk config*/
    rc = clPoolValidateConfig (pPoolConfig);
    if(rc != CL_OK)
    {
        CL_DEBUG_PRINT (CL_DEBUG_ERROR, ("Invalid param\n"));
        goto out;
    }

    chunkSize = pPoolConfig->chunkSize;
    incrementPoolSize = pPoolConfig->incrementPoolSize;
    extendedPools = pPoolConfig->initialPoolSize/incrementPoolSize;

    rc = CL_POOL_RC (CL_ERR_NO_MEMORY);
    if ((pPoolHeader = (ClPoolHeaderT*)CL_POOL_ALLOC_EXTERNAL
                            (flags, sizeof (*pPoolHeader))) == NULL)
    {
        CL_DEBUG_PRINT (CL_DEBUG_ERROR,
                ("Error in allocating memory for pool header, chunk size:%d\n",
                 chunkSize));
        goto out;
    }
    memset (pPoolHeader, 0, sizeof (*pPoolHeader));
    memcpy (&(pPoolHeader->poolConfig), pPoolConfig,
            sizeof (pPoolHeader->poolConfig));
    pPoolHeader->flags = (ClPoolFlagsT) (pPoolHeader->flags | flags);

    rc = CL_POOL_LOCK_INIT (pPoolHeader);
    if(CL_OK != rc)
    {
        CL_DEBUG_PRINT (CL_DEBUG_ERROR,
                ("CL_POOL_LOCK_INIT failed, rc=[%#X]\n", rc));
        goto out;
    }

    /*Initialise the extended pool free,partial and full list*/
    CL_POOL_EXTENDED_FREELIST_INIT (pPoolHeader);
    CL_POOL_EXTENDED_PARTIALLIST_INIT (pPoolHeader);
    CL_POOL_EXTENDED_FULLLIST_INIT (pPoolHeader);

    if (extendedPools == 0)
    {
        rc = CL_OK;
        goto out;
    }

    /*Create the initial extended pools*/
    for (i = 0; i < extendedPools; ++i)
    {
        ClExtendedPoolHeaderT *pExtendedPoolHeader = NULL;
        if ((pExtendedPoolHeader =
                    (ClExtendedPoolHeaderT*)CL_POOL_ALLOC_EXTERNAL (flags,
                        sizeof (*pExtendedPoolHeader))) == NULL)
        {
            CL_DEBUG_PRINT (CL_DEBUG_ERROR,
                    ("Error allocating memory for extended pool header, chunk "
                     "size:%d extended pool number:%d\n", chunkSize, i));
            goto out_free;
        }
        memset (pExtendedPoolHeader, 0, sizeof (*pExtendedPoolHeader));
        /*Initialize the extended pool*/
        rc = clPoolAllocateExtendedPool (pPoolHeader, pExtendedPoolHeader);
        if(rc != CL_OK)
        {
            CL_POOL_FREE_EXTERNAL (flags, pExtendedPoolHeader,
                    sizeof (*pExtendedPoolHeader));
            CL_DEBUG_PRINT (CL_DEBUG_ERROR,
                    ("Error allocating extended pool, chunk size:%d extended "
                     "pool number:%d\n", chunkSize, i));
            goto out_free;
        }
        CL_POOL_STATS_UPDATE_EXTENDED_POOLS_INCR(pPoolHeader);
    }
    *pHandle = (ClPoolT)pPoolHeader;
    CL_POOL_LOG(CL_LOG_TRACE,
                "%d extended pools created for %d byte pool with chunksize:%d",
                extendedPools,
                pPoolHeader->poolConfig.incrementPoolSize,
                pPoolHeader->poolConfig.chunkSize);
    rc = CL_OK;
    goto out;

    out_free:
    if(pPoolHeader)
    {
        clPoolDestroy((ClPoolT)pPoolHeader);
    }
    out:
    return rc;
}
ClRcT
clPoolExtend(
    ClPoolT poolHandle)
{
    ClRcT                   rc                  = CL_OK;
    ClPoolHeaderT*          pPoolHeader         = NULL;
    ClExtendedPoolHeaderT*  pExtendedPoolHeader = NULL;

    pPoolHeader = (ClPoolHeaderT*)poolHandle;

    NULL_CHECK (pPoolHeader);

    CL_POOL_LOG(CL_LOG_SEV_INFO,"clPoolExtend() :: extendedPoolSize = %d, chunkSize = %d \n",
                pPoolHeader->poolConfig.incrementPoolSize,
                pPoolHeader->poolConfig.chunkSize);

    rc = CL_POOL_RC (CL_ERR_NO_MEMORY);
    if (CL_POOL_MAX_EXTENDED_POOLS (pPoolHeader))
    {
        CL_POOL_LOG(CL_LOG_SEV_ERROR,"POOL extend of %d byte pool failed.Max pool size :%d, extended pools:%d\n",
                   pPoolHeader->poolConfig.chunkSize,
                   pPoolHeader->poolConfig.maxPoolSize,
                   pPoolHeader->stats.numExtendedPools);
        goto out;
    }

    if((pExtendedPoolHeader =
        (ClExtendedPoolHeaderT*)CL_POOL_ALLOC_EXTERNAL (pPoolHeader->flags,
            sizeof (ClExtendedPoolHeaderT))) == NULL)
    {
        CL_POOL_LOG(CL_LOG_SEV_ERROR,"Error allocating memory for extended pool header, chunk size:%d extended pool number:%d\n",
                   pPoolHeader->poolConfig.chunkSize,
                   pPoolHeader->stats.numExtendedPools);
        goto out;
    }

    memset (pExtendedPoolHeader, 0, sizeof (*pExtendedPoolHeader));

    CL_POOL_LOG(CL_LOG_SEV_TRACE,"Extending %d byte pool of %d chunkSize",
                pPoolHeader->poolConfig.incrementPoolSize,
                pPoolHeader->poolConfig.chunkSize);

    /*Initialise the extended pool*/

    rc = clPoolAllocateExtendedPool (pPoolHeader, pExtendedPoolHeader);
    if (rc != CL_OK)
    {
        CL_POOL_LOG(CL_LOG_SEV_ERROR,
                    "Extended pool allocation of %d byte pool of %d chunksize failed. pool number:%d",
                    pPoolHeader->poolConfig.incrementPoolSize,
                    pPoolHeader->poolConfig.chunkSize, pPoolHeader->stats.numExtendedPools
                    );
        goto out_free;
    }

    CL_POOL_STATS_UPDATE_EXTENDED_POOLS_INCR(pPoolHeader);
    rc = CL_OK;
    goto out;

    out_free:
    CL_POOL_FREE_EXTERNAL (pPoolHeader->flags, pExtendedPoolHeader,
        sizeof (*pExtendedPoolHeader));

    out:
    return rc;
}