Beispiel #1
0
/*
 * 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, pj_size_t size)
{
    pj_pool_block *block = pool->block_list.next;
    void *p;
    pj_size_t block_size;

    PJ_CHECK_STACK();

    while (block != &pool->block_list) {
	p = pj_pool_alloc_from_block(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, pj_pool_get_used_size(pool), 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. Also count the size wasted due to aligning
     * the block.
     */
    if (pool->increment_size < 
	    size + sizeof(pj_pool_block) + PJ_POOL_ALIGNMENT) 
    {
        pj_size_t count;
        count = (size + pool->increment_size + sizeof(pj_pool_block) +
                 PJ_POOL_ALIGNMENT) / 
                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, pj_pool_get_used_size(pool), pool->capacity));

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

    p = pj_pool_alloc_from_block(block, size);
    pj_assert(p != NULL);
#if PJ_DEBUG
    if (p == NULL) {
	p = p;
    }
#endif
    return p;
}
Beispiel #2
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, pj_pool_get_used_size(pool), 
	pj_pool_get_used_size(pool)*100/pool->capacity));

    reset_pool(pool);
}
Beispiel #3
0
/*
 * 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, pj_pool_get_used_size(pool)));

    /* 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;

    /* Set start and end of buffer. */
    block->buf = ((unsigned char*)block) + sizeof(pj_pool_block);
    block->end = ((unsigned char*)block) + size;

    /* Set the start pointer, aligning it as needed */
    block->cur = ALIGN_PTR(block->buf, PJ_POOL_ALIGNMENT);

    /* 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;
}
Beispiel #4
0
/*
 * 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, pj_pool_get_used_size(pool), 
	pj_pool_get_used_size(pool)*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;
    if (pool->factory->policy.block_free)
	(*pool->factory->policy.block_free)(pool->factory, pool, initial_size);
}
Beispiel #5
0
SIPCall::~SIPCall()
{
    _debug ("SIPCall: Delete call");
    _debug ("SDP: pool capacity %d", pj_pool_get_capacity (pool_));
    _debug ("SDP: pool size %d", pj_pool_get_used_size (pool_));
    delete local_sdp_;
    pj_pool_release (pool_);

    delete _audiortp;
}
Beispiel #6
0
static void cpool_dump_status(pj_pool_factory *factory, pj_bool_t detail )
{
#if PJ_LOG_MAX_LEVEL >= 3
    pj_caching_pool *cp = (pj_caching_pool*)factory;

    pj_lock_acquire(cp->lock);

    PJ_LOG(3,("cachpool", " Dumping caching pool:"));
    PJ_LOG(3,("cachpool", "   Capacity=%u, max_capacity=%u, used_cnt=%u", \
			     cp->capacity, cp->max_capacity, cp->used_count));
    if (detail) {
	pj_pool_t *pool = (pj_pool_t*) cp->used_list.next;
	pj_uint32_t total_used = 0, total_capacity = 0;
        PJ_LOG(3,("cachpool", "  Dumping all active pools:"));
	while (pool != (void*)&cp->used_list) {
	    unsigned pool_capacity = pj_pool_get_capacity(pool);
	    PJ_LOG(3,("cachpool", "   %12s: %8d of %8d (%d%%) used", 
				  pj_pool_getobjname(pool), 
				  pj_pool_get_used_size(pool), 
				  pool_capacity,
				  pj_pool_get_used_size(pool)*100/pool_capacity));
	    total_used += pj_pool_get_used_size(pool);
	    total_capacity += pool_capacity;
	    pool = pool->next;
	}
	if (total_capacity) {
	    PJ_LOG(3,("cachpool", "  Total %9d of %9d (%d %%) used!",
				  total_used, total_capacity,
				  total_used * 100 / total_capacity));
	}
    }

    pj_lock_release(cp->lock);
#else
    PJ_UNUSED_ARG(factory);
    PJ_UNUSED_ARG(detail);
#endif
}
    //
    // Get current total bytes allocated from the pool.
    //
    pj_size_t get_used_size()
    {
	pj_pool_get_used_size(p_);
    }
Beispiel #8
0
static void cpool_release_pool( pj_pool_factory *pf, pj_pool_t *pool)
{
    pj_caching_pool *cp = (pj_caching_pool*)pf;
    unsigned pool_capacity;
    unsigned i;

    PJ_CHECK_STACK();

    PJ_ASSERT_ON_FAIL(pf && pool, return);

    pj_lock_acquire(cp->lock);

#if PJ_SAFE_POOL
    /* Make sure pool is still in our used list */
    if (pj_list_find_node(&cp->used_list, pool) != pool) {
	pj_assert(!"Attempt to destroy pool that has been destroyed before");
	return;
    }
#endif

    /* Erase from the used list. */
    pj_list_erase(pool);

    /* Decrement used count. */
    --cp->used_count;

    pool_capacity = pj_pool_get_capacity(pool);

    /* Destroy the pool if the size is greater than our size or if the total
     * capacity in our recycle list (plus the size of the pool) exceeds 
     * maximum capacity.
   . */
    if (pool_capacity > pool_sizes[PJ_CACHING_POOL_ARRAY_SIZE-1] ||
	cp->capacity + pool_capacity > cp->max_capacity)
    {
	pj_pool_destroy_int(pool);
	pj_lock_release(cp->lock);
	return;
    }

    /* Reset pool. */
    PJ_LOG(6, (pool->obj_name, "recycle(): cap=%d, used=%d(%d%%)", 
	       pool_capacity, pj_pool_get_used_size(pool), 
	       pj_pool_get_used_size(pool)*100/pool_capacity));
    pj_pool_reset(pool);

    pool_capacity = pj_pool_get_capacity(pool);

    /*
     * Otherwise put the pool in our recycle list.
     */
    i = (unsigned) (unsigned long) pool->factory_data;

    pj_assert(i<PJ_CACHING_POOL_ARRAY_SIZE);
    if (i >= PJ_CACHING_POOL_ARRAY_SIZE ) {
	/* Something has gone wrong with the pool. */
	pj_pool_destroy_int(pool);
	pj_lock_release(cp->lock);
	return;
    }

    pj_list_insert_after(&cp->free_list[i], pool);
    cp->capacity += pool_capacity;

    pj_lock_release(cp->lock);
}