00001
00002
00003 #include "region.h"
00004 #include <string.h>
00005 #ifdef REGION_MALLOC
00006
00007 Region *make_region(size_t is, jmp_buf *label) {
00008 Region *r = (Region *)malloc(sizeof(Region));
00009 if(r == NULL)
00010 return NULL;
00011 struct region_node *node = (struct region_node *)malloc(sizeof(struct region_node));
00012 node->next = NULL;
00013 node->ptr = NULL;
00014 node->size = 0;
00015 r->head = r->tail = node;
00016 return r;
00017 }
00018 unsigned char *region_alloc_nodesc(Region *r, size_t s, size_t *alloc_size) {
00019 *alloc_size =
00020 s>DEFAULT_BLOCK_SIZE?
00021 s:
00022 roundToAlignment(s);
00023 unsigned char *pointer = (unsigned char *)malloc(*alloc_size);
00024 struct region_node *node = (struct region_node *)malloc(sizeof(struct region_node));
00025 node->next = NULL;
00026 node->ptr = pointer;
00027 node->size = s;
00028 r->tail->next = node;
00029 r->tail = node;
00030 return pointer;
00031
00032 }
00033 void *region_alloc(Region *r, size_t size) {
00034 size_t allocSize;
00035 unsigned char *mem = region_alloc_nodesc(r, size + CACHE_SIZE(RegionDesc, 1), &allocSize);
00036 ((RegionDesc *)mem)->region = r;
00037 ((RegionDesc *)mem)->size = allocSize;
00038 ((RegionDesc *)mem)->del = 0;
00039 return mem + CACHE_SIZE(RegionDesc, 1);
00040 }
00041 void region_free(Region *r) {
00042 while(r->head!=NULL) {
00043 struct region_node *node = r->head;
00044 r->head = node->next;
00045 memset(node->ptr, 0, node->size);
00046 if(node->ptr!=NULL) free(node->ptr);
00047 free(node);
00048 }
00049 free(r);
00050 }
00051 size_t region_size(Region *r) {
00052 size_t s = 0;
00053 struct region_node *node = r->head;
00054 while(node!=NULL) {
00055 s += node->size;
00056 node = node->next;
00057 }
00058 return s;
00059 }
00060 #else
00061
00062 struct region_node *make_region_node(size_t is) {
00063 struct region_node *node = (struct region_node *)malloc(sizeof(Region));
00064 if(node == NULL) {
00065 return NULL;
00066 }
00067
00068 node->block = (unsigned char *)malloc(is);
00069 memset(node->block, 0, is);
00070 if(node->block == NULL) {
00071 free(node);
00072 return NULL;
00073 }
00074
00075 node->size = is;
00076 node->used = 0;
00077 node->next = NULL;
00078
00079 return node;
00080 }
00081 Region *make_region(size_t is, jmp_buf *label) {
00082 Region *r = (Region *)malloc(sizeof(Region));
00083 if(r == NULL)
00084 return NULL;
00085
00086 if(is == 0)
00087 is = DEFAULT_BLOCK_SIZE;
00088 struct region_node *node = make_region_node(is);
00089 if(node == NULL) {
00090 free(r);
00091 return NULL;
00092 }
00093
00094 r->head = r->active = node;
00095 r->label = label;
00096 r->error.code = 0;
00097 return r;
00098 }
00099 unsigned char *region_alloc_nodesc(Region *r, size_t s, size_t *alloc_size) {
00100 if(s > r->active->size - r->active->used) {
00101 int blocksize;
00102 if(s > DEFAULT_BLOCK_SIZE) {
00103 blocksize=s;
00104
00105 } else {
00106 blocksize= DEFAULT_BLOCK_SIZE;
00107 }
00108 struct region_node *next = make_region_node(blocksize);
00109 if(next == NULL) {
00110 if(r->label == NULL) {
00111 return NULL;
00112 } else {
00113 longjmp(*(r->label), -1);
00114 }
00115 }
00116 r->active->next = next;
00117 r->active = next;
00118
00119 }
00120
00121 *alloc_size =
00122 s>DEFAULT_BLOCK_SIZE?
00123 s:
00124 roundToAlignment(s);
00125 unsigned char *pointer = r->active->block + r->active->used;
00126 r->active->used+=*alloc_size;
00127 return pointer;
00128
00129 }
00130 void *region_alloc(Region *r, size_t size) {
00131 size_t allocSize;
00132 unsigned char *mem = region_alloc_nodesc(r, size + CACHE_SIZE(RegionDesc, 1), &allocSize);
00133 ((RegionDesc *)mem)->region = r;
00134 ((RegionDesc *)mem)->size = allocSize;
00135 ((RegionDesc *)mem)->del = 0;
00136 return mem + CACHE_SIZE(RegionDesc, 1);
00137 }
00138 void region_free(Region *r) {
00139 while(r->head!=NULL) {
00140 struct region_node *node = r->head;
00141 r->head = node->next;
00142
00143 free(node->block);
00144 free(node);
00145 }
00146 free(r->label);
00147 free(r);
00148 }
00149 size_t region_size(Region *r) {
00150 size_t s = 0;
00151 struct region_node *node = r->head;
00152 while(node!=NULL) {
00153 s += node->used;
00154 node = node->next;
00155 }
00156 return s;
00157 }
00158 #endif
00159
00160
00161 void assert(int res) {
00162 if(!res) {
00163 printf("error");
00164 }
00165 }
00166 void test() {
00167 Region *r = make_region(0, NULL);
00168 assert(region_alloc(r, 16)!=NULL);
00169 assert(region_alloc(r, 20)!=NULL);
00170 assert(region_alloc(r,1000)!=NULL);
00171 assert(region_alloc(r,10000)!=NULL);
00172 assert(region_alloc(r,16)!=NULL);
00173 assert(region_alloc(r,10)!=NULL);
00174 assert(region_alloc(r,1024-16-10)!=NULL);
00175 region_free(r);
00176 }