SGI STL 内存管理代码[原理参见STL源码剖析]

来源:互联网 发布:淘宝电商夜鹰好吗 编辑:程序博客网 时间:2024/04/30 04:02
//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/__ALIGNtypedef 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]);}}