mempool.{h,c}
#ifndef _MEMPOOL_H_
#define _MEMPOOL_H_
#include <stdlib.h>
#define POOL_ALIGNMENT 16
typedef unsigned char u_char;
typedef struct pool_data_s pool_data_t;
typedef struct pool_s pool_t;
struct pool_data_s
{
u_char *last;
u_char *end;
pool_t *next;
int failed;
} ;
struct pool_s
{
pool_data_t d;
size_t max;
pool_t *current;
} ;
pool_t *create_pool(size_t size);
void *pool_alloc(size_t size);
void *pool_calloc(size_t size);
void *palloc(pool_t *pool, size_t size);
void *pnalloc(pool_t *pool, size_t size);
int pool_destory(pool_t *pool);
int pool_reset(pool_t *pool);
void get_pool_status(pool_t *pool);
#endif
#include "mempool.h"
#include "alloc.h"
#include <stdio.h>
static void *palloc_block(pool_t *pool, size_t size);
pool_t *create_pool(size_t size)
{
pool_t *p;
p = my_memalign(POOL_ALIGNMENT, size);
if(p == NULL)
{
return p;
}
p->d.last = (u_char *) p + sizeof(pool_t);
p->d.end = (u_char *)p + size;
p->d.next = NULL;
p->d.failed = 0;
size = p->d.end - p->d.last;
p->max = size;
p->current = p;
return p;
}
void *palloc(pool_t *pool, size_t size)
{
void *m;
pool_t *p = pool->current;
if(size >= p->max)
{
return NULL;
}
do
{
if(p->d.end - p->d.last > size)
{
m = p->d.last;
p->d.last += size;
return m;
}
p = p->d.next;
} while(p);
return palloc_block(pool, size);
}
static void *palloc_block(pool_t *pool, size_t size)
{
void *m;
pool_t *new_pool, *p, *current;
size_t pool_size;
pool_size = pool->d.end - (u_char *)pool;
new_pool = my_memalign(POOL_ALIGNMENT, pool_size);
if(new_pool == NULL)
{
return NULL;
}
//init new_pool
new_pool->d.last = (u_char *)new_pool + sizeof(pool_t);
new_pool->d.end = (u_char *)new_pool + pool_size;
new_pool->d.next = NULL;
new_pool->d.failed = 0;
new_pool->max = new_pool->d.end - new_pool->d.last;
//因为原来的pool_t不能分配才到这个函数,所以从current开始的pool_t块都failed加1
//当pool->current指向的块的failed超过4时,current指向下一个块
//其实前面的块失败次数永远 >= 后面的块,所以当一个块failed < 4时,最后的块也不会改变current了
current = pool->current;
for(p = current; p->d.next; p = p->d.next)
{
if(p->d.failed++ > 4)
{
current = p->d.next;
}
}
//无论如何,new_pool都是在单链表的尾部,上面的p沿current开始直到尾部
p->d.next = new_pool;
//如果当前的current指向了原本链表最后一块的d.next,那么
pool->current = current ? current : new_pool;
m = new_pool->d.last;
new_pool->d.last += size;
return m;
}
void get_pool_status(pool_t *pool)
{
int n = 0;
pool_t *p = pool;
printf("**********************************************************************\n");
for(; p; p = p->d.next, n++)
{
printf("pool:%d ", n);
printf("max:%d left:%d\n", p->max, p->d.end - p->d.last);
}
printf("**********************************************************************\n");
}
int pool_reset(pool_t *pool)
{
pool_t *pp = pool;
pool->current = pool;
for(; pp ; pp = pp->d.next)
{
pp->d.last = (u_char *)pp + sizeof(pool_t);
pp->d.failed = 0;
}
return 0;
}
int pool_destory(pool_t *pool)
{
pool_t *pp, *p;
pp = pool;
p = pp->d.next;
for(; pp; pp = p, p = pp->d.next)
{
pp->d.next = NULL;
free(pp);
if(p == NULL)
{
break;
}
}
return 0;
}
alloc.{h, c}
#ifndef _ALLOC_H_
#define _ALLOC_H_
#include <stdlib.h>
void *my_memalign(size_t alignment, size_t size);
#endif
#include "alloc.h"
#include <stdlib.h>
void *my_memalign(size_t alignment, size_t size)
{
void *p;
int err;
err = posix_memalign(&p, alignment, size);
return p;
}
mempool_test.c
#include "mempool.h"
#include <stdio.h>
#define ITEM 20
typedef struct
{
int a[10];
} data_t;
int main()
{
pool_t *pool;
data_t *p[ITEM];
size_t size;
int i;
size = 128;
pool = create_pool(size);
get_pool_status(pool);
for(i = 0; i < ITEM ;i++)
{
p[i] = palloc(pool, sizeof(data_t));
p[i]->a[0] = i;
}
get_pool_status(pool);
pool_reset(pool);
get_pool_status(pool);
pool_destory(pool);
pool = NULL;
get_pool_status(pool);
return 0;
}