现在的位置: 首页 > 综合 > 正文

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

2013年10月10日 ⁄ 综合 ⁄ 共 3050字 ⁄ 字号 评论关闭
//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]);
	}
}

抱歉!评论已关闭.