一个仿照Nginx的内存池

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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值