//mempool.h
#ifndef _MEM_POOL_H #define _MEM_POOL_H #include <stdlib.h> static size_t __freelist_index(size_t bytes); static size_t __round_up(size_t bytes); static void mem_init(); static void* mem_malloc(size_t n); static void mem_free(void* p,size_t n); static void mem_destroy(); //static void *mem_realloc(void*ptr,size_t newsize,size_t oldsize); static void *refill(size_t n); static char *chunk_alloc(size_t size,int *nobjs); #define __MAX_BYTES 20*1024 #define __ALIGN 512 #define __NFREELISTS __MAX_BYTES/__ALIGN typedef union obj{ union obj *free_list_link; char client_data[1]; }obj; obj *free_list[__NFREELISTS]; static char* start_free; static char* end_free; static size_t heap_size; static unsigned long g_addr[__NFREELISTS * 10]; static int g_addr_num=0; #endif
//mempool.c
#include <stdio.h> #include "string.h" #include "mempool.h" static size_t __freelist_index(size_t bytes) { return (bytes + __ALIGN - 1) /__ALIGN - 1; } static size_t __round_up(size_t bytes){ return (bytes + __ALIGN - 1) & ~(__ALIGN-1); } static void *mem_malloc(size_t n) { obj**my_free_list; obj* result; void *p; if(n > (size_t)__MAX_BYTES) { p = malloc(n); return p; } my_free_list = free_list + __freelist_index(n); result = *my_free_list; if(result == NULL) { p = refill(__round_up(n)); return p; } *my_free_list = result->free_list_link; return result; } static void mem_free(void*p,size_t n){ obj* q = (obj*)p; obj** my_free_list; if(n > (size_t)__MAX_BYTES) { free(p); return ; } my_free_list = free_list + __freelist_index(n); q->free_list_link = *my_free_list; *my_free_list = q; } static void *refill(size_t n) { int nobjs = 20; char *chunk = chunk_alloc(n,&nobjs); obj** my_free_list; obj* result; obj* curr_obj,*next_obj; int i; if(nobjs == 1) return chunk; my_free_list = free_list + __freelist_index(n); result = (obj*)chunk; *my_free_list = next_obj = (obj*)(chunk + n); for (i=1;i<nobjs;i++) { curr_obj = next_obj; next_obj = (obj*)((char*)next_obj + n); curr_obj->free_list_link = next_obj; } curr_obj->free_list_link = NULL; return result; } static char* chunk_alloc(size_t size,int *nobjs) { char *result; size_t total_bytes = size * (*nobjs); size_t left_bytes = end_free - start_free; size_t bytes_to_get; obj **my_free_list,*p; int i; if(left_bytes >= total_bytes) { result = start_free; start_free += total_bytes; return result; } if(left_bytes >= size) { *nobjs = (int)(left_bytes/size); total_bytes = size * (*nobjs); result = start_free; start_free += total_bytes; return result; } if(left_bytes > 0) { my_free_list = free_list + __freelist_index(left_bytes); ((obj*)start_free)->free_list_link = *my_free_list; *my_free_list = (obj*)start_free; } bytes_to_get = 2*total_bytes + __round_up(heap_size >> 4); start_free = (char*)malloc(bytes_to_get); g_addr[g_addr_num ++] = start_free; if(start_free) { heap_size += bytes_to_get; end_free = start_free + bytes_to_get; return chunk_alloc(size,nobjs); } i = (int)__freelist_index(size) + 1; for(;i<__NFREELISTS;++i) { my_free_list = free_list + i; p = *my_free_list; if(p) { *my_free_list = p->free_list_link; start_free = (char*)p; end_free = start_free+(i + 1) * __ALIGN; return chunk_alloc(size,nobjs); } } end_free = NULL;//应该抛出异常 return NULL; } static void mem_init() { int i; start_free = end_free = NULL; heap_size = 0; for(i=0;i<__NFREELISTS;free_list[i]=NULL,++i); memset(g_addr,0,sizeof(g_addr)); g_addr_num = 0; } static void mem_destroy() { int i; for( i=0;i<g_addr_num;++i) { free(g_addr[i]); } }