完成空间配置器

This commit is contained in:
邹晓航
2014-09-17 14:52:39 +08:00
parent 67f6bedb15
commit 90699d642e
2 changed files with 113 additions and 3 deletions

View File

@@ -1,6 +1,8 @@
#ifndef _ALLOC_H_
#define _ALLOC_H_
#include <cstdlib>
namespace TinySTL{
/*
@@ -9,8 +11,9 @@ namespace TinySTL{
class alloc{
private:
enum EAlign{ ALIGN = 8};//С<><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5>߽<EFBFBD>
enum EMaxBytes{ MAXBYTES = 128};//С<><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
enum EMaxBytes{ MAXBYTES = 128};//С<><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>malloc<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
enum ENFreeLists{ NFREELISTS = (EMaxBytes::MAXBYTES / EAlign::ALIGN)};//free-lists<74>ĸ<EFBFBD><C4B8><EFBFBD>
enum ENObjs{ NOBJS = 20};//ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD>ӵĽڵ<C4BD><DAB5><EFBFBD>
private:
//free-lists<74>Ľڵ㹹<DAB5><E3B9B9>
union obj{
@@ -50,6 +53,108 @@ namespace TinySTL{
alloc::obj *alloc::free_list[alloc::ENFreeLists::NFREELISTS] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
void *alloc::allocate(size_t bytes){
if (bytes > EMaxBytes::MAXBYTES){
return malloc(bytes);
}
size_t index = FREELIST_INDEX(bytes);
obj *list = free_list[index];
if (list){//<2F><>list<73><74><EFBFBD>пռ<D0BF><D5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
free_list[index] = list->next;
return list;
}else{//<2F><>listû<74><C3BB><EFBFBD><EFBFBD>Ŀռ<D5BC><E4A3AC>Ҫ<EFBFBD><D2AA><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ռ<EFBFBD>
return refill(ROUND_UP(bytes));
}
}
void alloc::deallocate(void *ptr, size_t bytes){
if (bytes > EMaxBytes::MAXBYTES){
free(ptr);
}
size_t index = FREELIST_INDEX(bytes);
obj *node = static_cast<obj *>(ptr);
node->next = free_list[index];
free_list[index] = node;
}
void *alloc::reallocate(void *ptr, size_t old_sz, size_t new_sz){
deallocate(ptr, old_sz);
ptr = allocate(new_sz);
return ptr;
}
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>СΪn<CEAA>Ķ<EFBFBD><C4B6>󣬲<EFBFBD><F3A3ACB2><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ϊ<EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD>free list<73><74><EFBFBD>ӽڵ<D3BD>
//<2F><><EFBFBD><EFBFBD>bytes<65>Ѿ<EFBFBD><D1BE>ϵ<EFBFBD>Ϊ8<CEAA>ı<EFBFBD><C4B1><EFBFBD>
void *alloc::refill(size_t bytes){
size_t nobjs = ENObjs::NOBJS;
//<2F><><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>ȡ
char *chunk = chunk_alloc(bytes, nobjs);
obj **my_free_list = 0;
obj *result = 0;
obj *current_obj = 0, *next_obj = 0;
if (nobjs == 1){//ȡ<><C8A1><EFBFBD>Ŀռ<C4BF>ֻ<EFBFBD><D6BB>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
return chunk;
}else{
my_free_list = free_list + FREELIST_INDEX(bytes);
result = (obj *)(chunk);
*my_free_list = next_obj = (obj *)(chunk + bytes);
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD>Ŀռ<C4BF><D5BC><EFBFBD><EFBFBD><EFBFBD><EBB5BD>Ӧ<EFBFBD><D3A6>free list<73><74><EFBFBD><EFBFBD>ȥ
for (int i = 1;; ++i){
current_obj = next_obj;
next_obj = (obj *)((char *)next_obj + bytes);
if (nobjs - 1 == i){
current_obj->next = 0;
break;
}else{
current_obj->next = next_obj;
}
}
return result;
}
}
//<2F><><EFBFBD><EFBFBD>bytes<65>Ѿ<EFBFBD><D1BE>ϵ<EFBFBD>Ϊ8<CEAA>ı<EFBFBD><C4B1><EFBFBD>
char *alloc::chunk_alloc(size_t bytes, size_t& nobjs){
char *result = 0;
size_t total_bytes = bytes * nobjs;
size_t bytes_left = end_free - start_free;
if (bytes_left >= total_bytes){//<2F>ڴ<EFBFBD><DAB4><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ
result = start_free;
start_free = start_free + total_bytes;
return result;
}else if(bytes_left >= bytes){//<2F>ڴ<EFBFBD><DAB4><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD>ռ<D5BC><E4B2BB><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3B9BB>Ӧһ<D3A6><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD>
nobjs = bytes_left / bytes;
total_bytes = nobjs * bytes;
result = start_free;
start_free += total_bytes;
return result;
}else{//<2F>ڴ<EFBFBD><DAB4><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD>С<EFBFBD><D0A1><EFBFBD>޷<EFBFBD><DEB7>
size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
if(bytes_left > 0){
obj **my_free_list = free_list + FREELIST_INDEX(bytes_left);
((obj *)start_free)->next = *my_free_list;
*my_free_list = (obj *)start_free;
}
start_free = (char *)malloc(bytes_to_get);
if (!start_free){
obj **my_free_list = 0, *p = 0;
for(int i = 0; i <= EMaxBytes::MAXBYTES; i += EAlign::ALIGN){
my_free_list = free_list + FREELIST_INDEX(i);
p = *my_free_list;
if(!p){
*my_free_list = p->next;
start_free = (char *)p;
end_free = start_free + i;
return chunk_alloc(bytes, nobjs);
}
}
end_free = 0;
}
heap_size += bytes_to_get;
end_free = start_free + bytes_to_get;
return chunk_alloc(bytes, nobjs);
}
}
}
#endif

View File

@@ -1,12 +1,17 @@
#include <iostream>
#include <memory>
#include "Alloc.h"
#include "Construct.h"
using namespace std;
int main(){
cout << "Holle World" << endl;
for (int i = 1; i != 100000; ++i){
TinySTL::alloc::allocate(i % 128 * sizeof(int));
//std::allocator<int> alloc; alloc.allocate(i % 128);
//malloc(i % 128 * sizeof(int));
}
system("pause");
return 0;
}