// 内存池技术.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<stdio.h>
#include<iostream>
#include<Windows.h>
using namespace std;
#define CRITICAL_ALIGN 8
#define CRITICAL_COUNT 16 //分16级
#define CRITICAL_VALUE 128 //128字节
#define FREELIST_INDEX(n) ((n -1) / CRITICAL_ALIGN)
#define ROUND_UP(n) ((n / 8 + 1) * 8)
//
union obj {
obj* free_list_link;
char client_data[1];
};
obj* freeList[CRITICAL_COUNT] = { NULL };
char* start_free; //内存池首
char* end_free; //内存池尾
size_t heap_size;
//从内存池分配内存(向freeList中进行分配)
char* chunk_alloc(size_t size, int& nobjs)
{
char* result;
size_t total_bytes = size * nobjs;
size_t bytes_left = end_free - start_free;
if (bytes_left >= total_bytes) {
result = start_free;
start_free += total_bytes;
return result;
}
else if(bytes_left >= size) {
nobjs = bytes_left / size;
total_bytes = nobjs * size;
result = start_free;
start_free += total_bytes;
return result;
}
else {
size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
if (bytes_left >= CRITICAL_ALIGN) {
obj** my_free_list = freeList + FREELIST_INDEX(bytes_left);
((obj*)start_free)->free_list_link = *my_free_list;
*my_free_list = (obj*)start_free;
}
start_free = (char*)malloc(bytes_to_get);
if (start_free == 0) {
int i;
obj** my_free_list;
obj* p;
for (i = size;i < CRITICAL_VALUE;i += CRITICAL_ALIGN) {
my_free_list = freeList + FREELIST_INDEX(i);
p = *my_free_list;
if (p != NULL) {
start_free = (char*)p;
end_free = start_free + i;
*my_free_list = p->free_list_link;
return chunk_alloc(size, nobjs);
}
}
}
heap_size += bytes_to_get;
end_free = start_free + bytes_to_get;
return (chunk_alloc(size, nobjs));
}
}
void * refill(size_t n)
{
int nobjs = 20;//定为20
char* chunk = chunk_alloc(n, nobjs);
memset((void*)chunk, 0x00, n*nobjs);//内存清零
if (nobjs == 1) return (void*)chunk;//分配到一个直接给用户
obj** my_free_list = freeList + FREELIST_INDEX(n);
obj* tmp_free = (obj*)chunk;
*my_free_list = tmp_free;
for (size_t i = 1; i < nobjs; i++) {
tmp_free->free_list_link = (obj*)(chunk + n);
tmp_free = tmp_free->free_list_link;
}
obj* result = *my_free_list;
*my_free_list = result->free_list_link;
return (void*)result;
}
void* allocate(size_t n)
{
obj** my_free_list;
obj* result;
if (n > CRITICAL_VALUE) {
return malloc(n);
}
else {
//交给内存池进行分配
my_free_list = freeList + FREELIST_INDEX(n);
result = *my_free_list;
if (result == NULL) {
//如果是空的,那么就从内存池分配内存
return refill(ROUND_UP(n));
}
*my_free_list = result->free_list_link;
return (void*)result;
}
}
int main()
{
void* link = allocate(13);
return 0;
}