From 81affa4ffde9e15ba7c3244c9ac4cdda2114d9b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=99=93=E8=88=AA?= <1210603696@qq.com> Date: Tue, 6 Jan 2015 14:03:41 +0800 Subject: [PATCH] update --- TinySTL/Alloc.cpp | 119 ++++++++++++++++++++++++++++++++ TinySTL/Alloc.h | 110 ----------------------------- TinySTL/TinySTL.vcxproj | 5 ++ TinySTL/TinySTL.vcxproj.filters | 15 ++++ 4 files changed, 139 insertions(+), 110 deletions(-) create mode 100644 TinySTL/Alloc.cpp diff --git a/TinySTL/Alloc.cpp b/TinySTL/Alloc.cpp new file mode 100644 index 0000000..13e7b7d --- /dev/null +++ b/TinySTL/Alloc.cpp @@ -0,0 +1,119 @@ +#include "Alloc.h" + +namespace TinySTL{ + char *alloc::start_free = 0; + char *alloc::end_free = 0; + size_t alloc::heap_size = 0; + 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){//´Ëlist»¹ÓÐ¿Õ¼ä¸øÎÒÃÇ + free_list[index] = list->next; + return list; + } + else{//´ËlistûÓÐ×ã¹»µÄ¿Õ¼ä£¬ÐèÒª´ÓÄÚ´æ³ØÀïÃæÈ¡¿Õ¼ä + return refill(ROUND_UP(bytes)); + } + } + void alloc::deallocate(void *ptr, size_t bytes){ + if (bytes > EMaxBytes::MAXBYTES){ + free(ptr); + } + else{ + size_t index = FREELIST_INDEX(bytes); + obj *node = static_cast(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; + } + //·µ»ØÒ»¸ö´óСΪnµÄ¶ÔÏ󣬲¢ÇÒÓÐʱºò»áΪÊʵ±µÄfree listÔö¼Ó½Úµã + //¼ÙÉèbytesÒѾ­Éϵ÷Ϊ8µÄ±¶Êý + void *alloc::refill(size_t bytes){ + size_t nobjs = ENObjs::NOBJS; + //´ÓÄÚ´æ³ØÀïÈ¡ + char *chunk = chunk_alloc(bytes, nobjs); + obj **my_free_list = 0; + obj *result = 0; + obj *current_obj = 0, *next_obj = 0; + + if (nobjs == 1){//È¡³öµÄ¿Õ¼äÖ»¹»Ò»¸ö¶ÔÏóʹÓà + return chunk; + } + else{ + my_free_list = free_list + FREELIST_INDEX(bytes); + result = (obj *)(chunk); + *my_free_list = next_obj = (obj *)(chunk + bytes); + //½«È¡³öµÄ¶àÓàµÄ¿Õ¼ä¼ÓÈëµ½ÏàÓ¦µÄfree listÀïÃæÈ¥ + 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; + } + } + //¼ÙÉèbytesÒѾ­Éϵ÷Ϊ8µÄ±¶Êý + 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){//ÄÚ´æ³ØÊ£Óà¿Õ¼äÍêÈ«Âú×ãÐèÒª + result = start_free; + start_free = start_free + total_bytes; + return result; + } + else if (bytes_left >= bytes){//ÄÚ´æ³ØÊ£Óà¿Õ¼ä²»ÄÜÍêÈ«Âú×ãÐèÒª£¬µ«×ã¹»¹©Ó¦Ò»¸ö»òÒÔÉϵÄÇø¿é + nobjs = bytes_left / bytes; + total_bytes = nobjs * bytes; + 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 > 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); + } + } +} \ No newline at end of file diff --git a/TinySTL/Alloc.h b/TinySTL/Alloc.h index 9da069c..9d48e17 100644 --- a/TinySTL/Alloc.h +++ b/TinySTL/Alloc.h @@ -47,116 +47,6 @@ namespace TinySTL{ static void deallocate(void *ptr, size_t bytes); static void *reallocate(void *ptr, size_t old_sz, size_t new_sz); }; - - char *alloc::start_free = 0; - char *alloc::end_free = 0; - size_t alloc::heap_size = 0; - 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){//´Ëlist»¹ÓÐ¿Õ¼ä¸øÎÒÃÇ - free_list[index] = list->next; - return list; - }else{//´ËlistûÓÐ×ã¹»µÄ¿Õ¼ä£¬ÐèÒª´ÓÄÚ´æ³ØÀïÃæÈ¡¿Õ¼ä - return refill(ROUND_UP(bytes)); - } - } - void alloc::deallocate(void *ptr, size_t bytes){ - if (bytes > EMaxBytes::MAXBYTES){ - free(ptr); - }else{ - size_t index = FREELIST_INDEX(bytes); - obj *node = static_cast(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; - } - //·µ»ØÒ»¸ö´óСΪnµÄ¶ÔÏ󣬲¢ÇÒÓÐʱºò»áΪÊʵ±µÄfree listÔö¼Ó½Úµã - //¼ÙÉèbytesÒѾ­Éϵ÷Ϊ8µÄ±¶Êý - void *alloc::refill(size_t bytes){ - size_t nobjs = ENObjs::NOBJS; - //´ÓÄÚ´æ³ØÀïÈ¡ - char *chunk = chunk_alloc(bytes, nobjs); - obj **my_free_list = 0; - obj *result = 0; - obj *current_obj = 0, *next_obj = 0; - - if (nobjs == 1){//È¡³öµÄ¿Õ¼äÖ»¹»Ò»¸ö¶ÔÏóʹÓà - return chunk; - }else{ - my_free_list = free_list + FREELIST_INDEX(bytes); - result = (obj *)(chunk); - *my_free_list = next_obj = (obj *)(chunk + bytes); - //½«È¡³öµÄ¶àÓàµÄ¿Õ¼ä¼ÓÈëµ½ÏàÓ¦µÄfree listÀïÃæÈ¥ - 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; - } - } - //¼ÙÉèbytesÒѾ­Éϵ÷Ϊ8µÄ±¶Êý - 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){//ÄÚ´æ³ØÊ£Óà¿Õ¼äÍêÈ«Âú×ãÐèÒª - result = start_free; - start_free = start_free + total_bytes; - return result; - }else if(bytes_left >= bytes){//ÄÚ´æ³ØÊ£Óà¿Õ¼ä²»ÄÜÍêÈ«Âú×ãÐèÒª£¬µ«×ã¹»¹©Ó¦Ò»¸ö»òÒÔÉϵÄÇø¿é - nobjs = bytes_left / bytes; - total_bytes = nobjs * bytes; - 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 > 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 \ No newline at end of file diff --git a/TinySTL/TinySTL.vcxproj b/TinySTL/TinySTL.vcxproj index 6e08251..98e8322 100644 --- a/TinySTL/TinySTL.vcxproj +++ b/TinySTL/TinySTL.vcxproj @@ -79,9 +79,12 @@ + + + @@ -110,6 +113,8 @@ + + diff --git a/TinySTL/TinySTL.vcxproj.filters b/TinySTL/TinySTL.vcxproj.filters index 5bc680a..ec33b71 100644 --- a/TinySTL/TinySTL.vcxproj.filters +++ b/TinySTL/TinySTL.vcxproj.filters @@ -54,6 +54,15 @@ Test + + Test + + + Test + + + 头文件 + @@ -149,6 +158,12 @@ Test + + Test + + + Test +