/* * 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; }
/* * 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); }
/* * 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; }
/* * 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); }
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; }
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_); }
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); }