/* $Header: /pjproject-0.3/pjlib/src/pj/pool.c 8     10/14/05 12:26a Bennylp $ */
/* $Log: /pjproject-0.3/pjlib/src/pj/pool.c $
 * 
 * 8     10/14/05 12:26a Bennylp
 * Finished error code framework, some fixes in ioqueue, etc. Pretty
 * major.
 * 
 * 7     9/17/05 10:37a Bennylp
 * Major reorganization towards version 0.3.
 * 
 */
#include <pj/pool.h>
#include <pj/log.h>
#include <pj/except.h>
#include <pj/assert.h>
#include <pj/os.h>
#include <pj/compat/sprintf.h>

/* Include inline definitions when inlining is disabled. */
#if !PJ_FUNCTIONS_ARE_INLINED
#  include <pj/pool_i.h>
#endif

#define LOG(expr)   PJ_LOG(5,expr)

int PJ_NO_MEMORY_EXCEPTION;

/*
 * Create new block.
 * Create a new big chunk of memory block, from which user allocation will be
 * taken from.
 */
static pj_pool_block *pj_pool_create_block( pj_pool_t *pool, pj_size_t size)
{
    pj_pool_block *block;

    PJ_CHECK_STACK();
    pj_assert(size >= sizeof(pj_pool_block));

    LOG((pool->obj_name, "create_block(sz=%u), cur.cap=%u, cur.used=%u", 
	 size, pool->capacity, pool->used_size));

    /* Request memory from allocator. */
    block = (pj_pool_block*) 
	(*pool->factory->policy.block_alloc)(pool->factory, size);
    if (block == NULL) {
	(*pool->callback)(pool, size);
	return NULL;
    }

    /* Add capacity. */
    pool->capacity += size;
    pool->used_size += sizeof(pj_pool_block);

    /* Set block attribytes. */
    block->cur = block->buf = ((unsigned char*)block) + sizeof(pj_pool_block);
    block->end = ((unsigned char*)block) + size;

    /* Insert in the front of the list. */
    pj_list_insert_after(&pool->block_list, block);

    LOG((pool->obj_name," block created, buffer=%p-%p",block->buf, block->end));

    return block;
}

/*
 * Allocate memory chunk for user from available blocks.
 * This will iterate through block list to find space to allocate the chunk.
 * If no space is available in all the blocks, a new block might be created
 * (depending on whether the pool is allowed to resize).
 */
PJ_DEF(void*) pj_pool_allocate_find(pj_pool_t *pool, unsigned size)
{
    pj_pool_block *block = pool->block_list.next;
    void *p;
    unsigned block_size;

    PJ_CHECK_STACK();

    while (block != &pool->block_list) {
	p = pj_pool_alloc_from_block(pool, block, size);
	if (p != NULL)
	    return p;
	block = block->next;
    }
    /* No available space in all blocks. */

    /* If pool is configured NOT to expand, return error. */
    if (pool->increment_size == 0) {
	LOG((pool->obj_name, "Can't expand pool to allocate %u bytes "
	     "(used=%u, cap=%u)",
	     size, pool->used_size, pool->capacity));
	(*pool->callback)(pool, size);
	return NULL;
    }

    /* If pool is configured to expand, but the increment size
     * is less than the required size, expand the pool by multiple
     * increment size
     */
    if (pool->increment_size < size + sizeof(pj_pool_block)) {
        unsigned count;
        count = (size + pool->increment_size + sizeof(pj_pool_block)) / 
                pool->increment_size;
        block_size = count * pool->increment_size;

    } else {
        block_size = pool->increment_size;
    }

    LOG((pool->obj_name, 
	 "%u bytes requested, resizing pool by %u bytes (used=%u, cap=%u)",
	 size, block_size, pool->used_size, pool->capacity));

    block = pj_pool_create_block(pool, block_size);
    if (!block)
	return NULL;

    p = pj_pool_alloc_from_block(pool, block, size);
    pj_assert(p != NULL);
#if PJ_DEBUG
    if (p == NULL) {
	p = p;
    }
#endif
    return p;
}

/*
 * Internal function to initialize pool.
 */
PJ_DEF(void) pj_pool_init_int(  pj_pool_t *pool, 
				const char *name,
				pj_size_t increment_size,
				pj_pool_callback *callback)
{
    pj_pool_block *block;

    PJ_CHECK_STACK();

    pool->increment_size = increment_size;
    pool->callback = callback;
    pool->used_size = sizeof(*pool);
    block = pool->block_list.next;
    while (block != &pool->block_list) {
	pool->used_size += sizeof(pj_pool_block);
	block = block->next;
    }

    if (name) {
	if (strchr(name, '%') != NULL) {
	    sprintf(pool->obj_name, name, pool);
	} else {
	    strncpy(pool->obj_name, name, PJ_MAX_OBJ_NAME);
	}
    } else {
	pool->obj_name[0] = '\0';
    }
}

/*
 * Create new memory pool.
 */
PJ_DEF(pj_pool_t*) pj_pool_create_int( pj_pool_factory *f, const char *name,
				       pj_size_t initial_size, 
				       pj_size_t increment_size,
				       pj_pool_callback *callback)
{
    pj_pool_t *pool;
    pj_pool_block *block;
    unsigned char *buffer;

    PJ_CHECK_STACK();

    buffer = (*f->policy.block_alloc)(f, initial_size);
    if (!buffer)
	return NULL;

    /* Set pool administrative data. */
    pool = (pj_pool_t*)buffer;
    pj_memset(pool, 0, sizeof(*pool));

    pj_list_init(&pool->block_list);
    pool->factory = f;

    /* Create the first block from the memory. */
    block = (pj_pool_block*) (buffer + sizeof(*pool));
    block->cur = block->buf = ((unsigned char*)block) + sizeof(pj_pool_block);
    block->end = buffer + initial_size;
    pj_list_insert_after(&pool->block_list, block);

    pj_pool_init_int(pool, name, increment_size, callback);

    /* Pool initial capacity and used size */
    pool->capacity = initial_size;

    LOG((pool->obj_name, "pool created, size=%u", pool->capacity));
    return pool;
}

/*
 * Reset the pool to the state when it was created.
 * All blocks will be deallocated except the first block. All memory areas
 * are marked as free.
 */
static void reset_pool(pj_pool_t *pool)
{
    pj_pool_block *block;

    PJ_CHECK_STACK();

    block = pool->block_list.prev;
    if (block == &pool->block_list)
	return;

    /* Skip the first block because it is occupying the same memory
       as the pool itself.
    */
    block = block->prev;
    
    while (block != &pool->block_list) {
	pj_pool_block *prev = block->prev;
	pj_list_erase(block);
	(*pool->factory->policy.block_free)(pool->factory, block, 
					    block->end - (unsigned char*)block);
	block = prev;
    }

    block = pool->block_list.next;
    block->cur = block->buf;
    pool->capacity = block->end - (unsigned char*)pool;
    pool->used_size = 0;
}

/*
 * The public function to reset pool.
 */
PJ_DEF(void) pj_pool_reset(pj_pool_t *pool)
{
    LOG((pool->obj_name, "reset(): cap=%d, used=%d(%d%%)", 
	pool->capacity, pool->used_size, pool->used_size*100/pool->capacity));

    reset_pool(pool);
}

/*
 * Destroy the pool.
 */
PJ_DEF(void) pj_pool_destroy_int(pj_pool_t *pool)
{
    pj_size_t initial_size;

    LOG((pool->obj_name, "destroy(): cap=%d, used=%d(%d%%), block0=%p-%p", 
	pool->capacity, pool->used_size, pool->used_size*100/pool->capacity,
	((pj_pool_block*)pool->block_list.next)->buf, 
	((pj_pool_block*)pool->block_list.next)->end));

    reset_pool(pool);
    initial_size = ((pj_pool_block*)pool->block_list.next)->end - 
		   (unsigned char*)pool;
    (*pool->factory->policy.block_free)(pool->factory, pool, initial_size);
}


