⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pool.c

📁 基于sip协议的网络电话源码
💻 C
字号:
/* $Id: pool.c 974 2007-02-19 01:13:53Z bennylp $ *//*  * Copyright (C)2003-2007 Benny Prijono <benny@prijono.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  */#include <pj/pool.h>#include <pj/log.h>#include <pj/except.h>#include <pj/assert.h>#include <pj/os.h>#if !PJ_HAS_POOL_ALT_API/* Include inline definitions when inlining is disabled. */#if !PJ_FUNCTIONS_ARE_INLINED#  include <pj/pool_i.h>#endif#define LOG(expr)   PJ_LOG(6,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, 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 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(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     */    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, 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;}/* * 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_CHECK_STACK();    pool->increment_size = increment_size;    pool->callback = callback;    if (name) {	if (strchr(name, '%') != NULL) {	    pj_ansi_snprintf(pool->obj_name, sizeof(pool->obj_name), 			     name, pool);	} else {	    pj_ansi_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();    /* Size must be at least sizeof(pj_pool)+sizeof(pj_pool_block) */    PJ_ASSERT_RETURN(initial_size >= sizeof(pj_pool_t)+sizeof(pj_pool_block),		     NULL);    /* If callback is NULL, set calback from the policy */    if (callback == NULL)	callback = f->policy.callback;    /* Allocate initial block */    buffer = (*f->policy.block_alloc)(f, initial_size);    if (!buffer)	return NULL;    /* Set pool administrative data. */    pool = (pj_pool_t*)buffer;    pj_bzero(pool, 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;}/* * 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);}/* * 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);}#endif	/* PJ_HAS_POOL_ALT_API */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -