/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "os/os.h"

#include <string.h>
#include <assert.h>

#define OS_MEMPOOL_TRUE_BLOCK_SIZE(bsize)   OS_ALIGN(bsize, OS_ALIGNMENT)

STAILQ_HEAD(, os_mempool) g_os_mempool_list = 
    STAILQ_HEAD_INITIALIZER(g_os_mempool_list);

/**
 * os mempool init
 *  
 * Initialize a memory pool. 
 * 
 * @param mp            Pointer to a pointer to a mempool
 * @param blocks        The number of blocks in the pool
 * @param blocks_size   The size of the block, in bytes. 
 * @param membuf        Pointer to memory to contain blocks. 
 * @param name          Name of the pool.
 * 
 * @return os_error_t 
 */
os_error_t
os_mempool_init(struct os_mempool *mp, int blocks, int block_size, void *membuf,
                char *name)
{
    int true_block_size;
    uint8_t *block_addr;
    struct os_memblock *block_ptr;

    /* Check for valid parameters */
    if ((!mp) || (!membuf) || (blocks <= 0) || (block_size <= 0)) {
        return OS_INVALID_PARM;
    }

    /* Blocks need to be sized properly and memory buffer should be aligned */
    if (((uint32_t)membuf & (OS_ALIGNMENT - 1)) != 0) {
        return OS_MEM_NOT_ALIGNED;
    }
    true_block_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(block_size);

    /* Initialize the memory pool structure */
    mp->mp_block_size = block_size;
    mp->mp_num_free = blocks;
    mp->mp_num_blocks = blocks;
    mp->mp_membuf_addr = (uint32_t)membuf;
    mp->name = name;
    SLIST_FIRST(mp) = membuf;

    /* Chain the memory blocks to the free list */
    block_addr = (uint8_t *)membuf;
    block_ptr = (struct os_memblock *)block_addr;
    while (blocks > 1) {
        block_addr += true_block_size;
        SLIST_NEXT(block_ptr, mb_next) = (struct os_memblock *)block_addr;
        block_ptr = (struct os_memblock *)block_addr;
        --blocks;
    }

    /* Last one in the list should be NULL */
    SLIST_NEXT(block_ptr, mb_next) = NULL;

    STAILQ_INSERT_TAIL(&g_os_mempool_list, mp, mp_list);

    return OS_OK;
}

/**
 * os memblock get 
 *  
 * Get a memory block from a memory pool 
 * 
 * @param mp Pointer to the memory pool
 * 
 * @return void* Pointer to block if available; NULL otherwise
 */
void *
os_memblock_get(struct os_mempool *mp)
{
    os_sr_t sr;
    struct os_memblock *block;

    /* Check to make sure they passed in a memory pool (or something) */
    block = NULL;
    if (mp) {
        OS_ENTER_CRITICAL(sr);
        /* Check for any free */
        if (mp->mp_num_free) {
            /* Get a free block */
            block = SLIST_FIRST(mp);

            /* Set new free list head */
            SLIST_FIRST(mp) = SLIST_NEXT(block, mb_next);

            /* Decrement number free by 1 */
            mp->mp_num_free--;
        }
        OS_EXIT_CRITICAL(sr);
    }

    return (void *)block;
}

/**
 * os memblock put 
 *  
 * Puts the memory block back into the pool 
 * 
 * @param mp Pointer to memory pool
 * @param block_addr Pointer to memory block
 * 
 * @return os_error_t 
 */
os_error_t
os_memblock_put(struct os_mempool *mp, void *block_addr)
{
    os_sr_t sr;
    uint32_t end;
    uint32_t true_block_size;
    uint32_t baddr32;
    struct os_memblock *block;

    /* Make sure parameters are valid */
    if ((mp == NULL) || (block_addr == NULL)) {
        return OS_INVALID_PARM;
    }

    /* Check that the block we are freeing is a valid block! */
    baddr32 = (uint32_t)block_addr;
    true_block_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(mp->mp_block_size);
    end = mp->mp_membuf_addr + (mp->mp_num_blocks * true_block_size);
    if ((baddr32 < mp->mp_membuf_addr) || (baddr32 >= end)) {
        return OS_INVALID_PARM;
    }

    /* All freed blocks should be on true block size boundaries! */
    if (((baddr32 - mp->mp_membuf_addr) % true_block_size) != 0) {
        return OS_INVALID_PARM;
    }

    /* 
     * XXX: we should do boundary checks here! The block had better be within 
     * the pool. If it fails, do we return an error or assert()? Add this when 
     * we add the memory debug. 
     */ 
    block = (struct os_memblock *)block_addr;
    OS_ENTER_CRITICAL(sr);
    
    /* Chain current free list pointer to this block; make this block head */
    SLIST_NEXT(block, mb_next) = SLIST_FIRST(mp);
    SLIST_FIRST(mp) = block;

    /* XXX: Should we check that the number free <= number blocks? */
    /* Increment number free */
    mp->mp_num_free++;

    OS_EXIT_CRITICAL(sr);

    return OS_OK;
}


struct os_mempool *
os_mempool_info_get_next(struct os_mempool *mp, struct os_mempool_info *omi)
{
    struct os_mempool *cur;

    if (mp == NULL) {
        cur = STAILQ_FIRST(&g_os_mempool_list);
    } else {
        cur = STAILQ_NEXT(mp, mp_list);
    }

    if (cur == NULL) {
        return (NULL);
    }

    omi->omi_block_size = cur->mp_block_size;
    omi->omi_num_blocks = cur->mp_num_blocks;
    omi->omi_num_free = cur->mp_num_free;
    strncpy(omi->omi_name, cur->name, sizeof(omi->omi_name));

    return (cur);
}

