00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006 #include "vnl_alloc.h"
00007
00008 #include <vcl_cstring.h>
00009 #include <vcl_cstdlib.h>
00010
00011 char*
00012 vnl_alloc::chunk_alloc(vcl_size_t size, int& nobjs)
00013 {
00014 char * result;
00015 vcl_size_t total_bytes = size * nobjs;
00016 vcl_size_t bytes_left = end_free - start_free;
00017
00018 if (bytes_left >= total_bytes) {
00019 result = start_free;
00020 start_free += total_bytes;
00021 return result;
00022 }
00023 else if (bytes_left >= size) {
00024 nobjs = int(bytes_left/size);
00025 total_bytes = size * nobjs;
00026 result = start_free;
00027 start_free += total_bytes;
00028 return result;
00029 }
00030 else
00031 {
00032 vcl_size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
00033
00034 if (bytes_left > 0) {
00035 obj * * my_free_list =
00036 free_list + FREELIST_INDEX(bytes_left);
00037 ((obj *)start_free) -> free_list_link = *my_free_list;
00038 *my_free_list = (obj *)start_free;
00039 }
00040 start_free = (char*)vcl_malloc(bytes_to_get);
00041 if (0 == start_free)
00042 {
00043 obj * * my_free_list, *p;
00044
00045
00046
00047 for (vcl_size_t i = size; i <= VNL_ALLOC_MAX_BYTES; i += VNL_ALLOC_ALIGN)
00048 {
00049 my_free_list = free_list + FREELIST_INDEX(i);
00050 p = *my_free_list;
00051 if (0 != p) {
00052 *my_free_list = p -> free_list_link;
00053 start_free = (char *)p;
00054 end_free = start_free + i;
00055 return chunk_alloc(size, nobjs);
00056
00057
00058 }
00059 }
00060 start_free = (char*)vcl_malloc(bytes_to_get);
00061
00062
00063
00064 }
00065 heap_size += bytes_to_get;
00066 end_free = start_free + bytes_to_get;
00067 return chunk_alloc(size, nobjs);
00068 }
00069 }
00070
00071
00072
00073
00074
00075 void* vnl_alloc::refill(vcl_size_t n)
00076 {
00077 int nobjs = 20;
00078 char * chunk = chunk_alloc(n, nobjs);
00079 obj * * my_free_list;
00080 obj * result;
00081 obj * current_obj, * next_obj;
00082 int i;
00083
00084 if (1 == nobjs) return chunk;
00085 my_free_list = free_list + FREELIST_INDEX(n);
00086
00087
00088 result = (obj *)chunk;
00089 *my_free_list = next_obj = (obj *)(chunk + n);
00090 for (i = 1; ; i++) {
00091 current_obj = next_obj;
00092 next_obj = (obj *)((char *)next_obj + n);
00093 if (nobjs - 1 == i) {
00094 current_obj -> free_list_link = 0;
00095 break;
00096 }
00097 else {
00098 current_obj -> free_list_link = next_obj;
00099 }
00100 }
00101 return result;
00102 }
00103
00104 void*
00105 vnl_alloc::reallocate(void *p,
00106 vcl_size_t old_sz,
00107 vcl_size_t new_sz)
00108 {
00109 void * result;
00110 vcl_size_t copy_sz;
00111
00112 if (old_sz > VNL_ALLOC_MAX_BYTES && new_sz > VNL_ALLOC_MAX_BYTES) {
00113 return vcl_realloc(p, new_sz);
00114 }
00115 if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return p;
00116 result = allocate(new_sz);
00117 copy_sz = new_sz > old_sz? old_sz : new_sz;
00118 vcl_memcpy(result, p, copy_sz);
00119 deallocate(p, old_sz);
00120 return result;
00121 }
00122
00123 char *vnl_alloc::start_free = 0;
00124 char *vnl_alloc::end_free = 0;
00125 vcl_size_t vnl_alloc::heap_size = 0;
00126
00127 vnl_alloc::obj *
00128 vnl_alloc::free_list[VNL_ALLOC_NFREELISTS] =
00129 {
00130 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00132 };
00133
00134
00135
00136
00137 #ifdef TEST
00138 #include <vcl_iostream.h>
00139 int main()
00140 {
00141 char* p = (char*)vnl_alloc::allocate(10);
00142 vcl_strcpy(p, "fred\n");
00143 vcl_cerr << p << '\n';
00144 vnl_alloc::deallocate(p,10);
00145 }
00146
00147 #endif // TEST