typedef struct common_obj_pool common_obj_pool;
typedef struct common_obj_node common_obj_node;
struct common_obj_pool {
uint count; //total num
uint size; //per size
uint free; //unused num
int head; //insert pos
int tail; //delete pos
uint len; //buffer len
void *ptr; //buffer addr
};
struct common_obj_node {
int status; //0:unuse, 1:inuse
int next; //>=0:next, -1:tail, -2:inuse
void *data; //user data
};
#define COM_OBJ_NODE_HEADL (sizeof(common_obj_node)-sizeof(void*))
#define COM_OBJ_NODE_SIZE (COM_OBJ_NODE_HEADL + (pool->size))
int common_obj_pool_init(common_obj_pool *pool, uint count, uint size)
{
int i;
common_obj_node *obj;
if(pool == NULL || count < 2 || size < 0)
return EINVAL;
pool->count = count;
pool->free = count;
pool->size = size;
pool->head = 0;
pool->tail = count-1;
pool->len = count*COM_OBJ_NODE_SIZE;
pool->ptr = malloc(pool->len);
if(pool->ptr == NULL)
return errno;
obj = pool->ptr;
for(i=0; i<count; i++){
obj->status = 0;
if(i == count-1)
obj->next = -1;
else
obj->next = i+1;
obj = (void*)obj + COM_OBJ_NODE_SIZE;
}
return 0;
}
int common_obj_pool_destroy(common_obj_pool *pool)
{
free(pool->ptr);
memset(pool, 0, sizeof(common_obj_pool));
return 0;
}
int common_obj_malloc(common_obj_pool *pool, void **ptr)
{
common_obj_node *obj;
if(pool == NULL)
return EINVAL;
if(pool->free <= 0)
return ENOMEM;
obj = pool->ptr + (pool->head)*COM_OBJ_NODE_SIZE;
if(obj->status != 0)
return EFAULT;
pool->head = obj->next;
pool->free--;
obj->status = 1;
obj->next = -2;
*ptr = &obj->data;
memset(*ptr, 0, pool->size);
return 0;
}
int common_obj_free(common_obj_pool *pool, void *ptr)
{
int index;
common_obj_node *obj, *tail;
if(pool == NULL || ptr == NULL)
return EINVAL;
obj = ptr - COM_OBJ_NODE_HEADL;
if(obj->status != 1)
return EFAULT;
index = ((void*)obj - pool->ptr) / COM_OBJ_NODE_SIZE;
<pre code_snippet_id="605188" snippet_file_name="blog_20150215_1_5241167" name="code" class="cpp"> if(pool->head < 0)
pool->head = index
else{tail = pool->ptr + (pool->tail)*COM_OBJ_NODE_SIZE; tail->next = index;} pool->tail = index; pool->free++; obj->status = 0; obj->next = -1; return 0;}