00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "xode.h"
00043
00044
00045 #define _xode_pool__malloc malloc
00046 #define _xode_pool__free free
00047
00048
00049
00050 struct xode_pool_free
00051 {
00052 xode_pool_cleaner f;
00053 void *arg;
00054 struct xode_pool_heap *heap;
00055 struct xode_pool_free *next;
00056 };
00057
00058
00059 xode_pool _xode_pool_new(void)
00060 {
00061 xode_pool p;
00062 while((p = _xode_pool__malloc(sizeof(_xode_pool))) == NULL) sleep(1);
00063 p->cleanup = NULL;
00064 p->heap = NULL;
00065 p->size = 0;
00066
00067 return p;
00068 }
00069
00070
00071 void _xode_pool_heapfree(void *arg)
00072 {
00073 struct xode_pool_heap *h = (struct xode_pool_heap *)arg;
00074
00075 _xode_pool__free(h->block);
00076 _xode_pool__free(h);
00077 }
00078
00079
00080 void _xode_pool_cleanup_append(xode_pool p, struct xode_pool_free *pf)
00081 {
00082 struct xode_pool_free *cur;
00083
00084 if(p->cleanup == NULL)
00085 {
00086 p->cleanup = pf;
00087 return;
00088 }
00089
00090
00091 for(cur = p->cleanup; cur->next != NULL; cur = cur->next);
00092
00093 cur->next = pf;
00094 }
00095
00096
00097 struct xode_pool_free *_xode_pool_free(xode_pool p, xode_pool_cleaner f, void *arg)
00098 {
00099 struct xode_pool_free *ret;
00100
00101
00102 while((ret = _xode_pool__malloc(sizeof(struct xode_pool_free))) == NULL) sleep(1);
00103 ret->f = f;
00104 ret->arg = arg;
00105 ret->next = NULL;
00106
00107 return ret;
00108 }
00109
00110
00111 struct xode_pool_heap *_xode_pool_heap(xode_pool p, int size)
00112 {
00113 struct xode_pool_heap *ret;
00114 struct xode_pool_free *clean;
00115
00116
00117 while((ret = _xode_pool__malloc(sizeof(struct xode_pool_heap))) == NULL) sleep(1);
00118 while((ret->block = _xode_pool__malloc(size)) == NULL) sleep(1);
00119 ret->size = size;
00120 p->size += size;
00121 ret->used = 0;
00122
00123
00124 clean = _xode_pool_free(p, _xode_pool_heapfree, (void *)ret);
00125 clean->heap = ret;
00126 _xode_pool_cleanup_append(p, clean);
00127
00128 return ret;
00129 }
00130
00131 xode_pool _xode_pool_newheap(int bytes)
00132 {
00133 xode_pool p;
00134 p = _xode_pool_new();
00135 p->heap = _xode_pool_heap(p,bytes);
00136 return p;
00137 }
00138
00139 void *xode_pool_malloc(xode_pool p, int size)
00140 {
00141 void *block;
00142
00143 if(p == NULL)
00144 {
00145 fprintf(stderr,"Memory Leak! xode_pmalloc received NULL pool, unable to track allocation, exiting]\n");
00146 abort();
00147 }
00148
00149
00150 if(p->heap == NULL || size > (p->heap->size / 2))
00151 {
00152 while((block = _xode_pool__malloc(size)) == NULL) sleep(1);
00153 p->size += size;
00154 _xode_pool_cleanup_append(p, _xode_pool_free(p, _xode_pool__free, block));
00155 return block;
00156 }
00157
00158
00159 if(size >= 4)
00160 while(p->heap->used&7) p->heap->used++;
00161
00162
00163 if(size > (p->heap->size - p->heap->used))
00164 p->heap = _xode_pool_heap(p, p->heap->size);
00165
00166
00167 block = (char *)p->heap->block + p->heap->used;
00168 p->heap->used += size;
00169 return block;
00170 }
00171
00172 void *xode_pool_mallocx(xode_pool p, int size, char c)
00173 {
00174 void* result = xode_pool_malloc(p, size);
00175 if (result != NULL)
00176 memset(result, c, size);
00177 return result;
00178 }
00179
00180
00181 void *xode_pool_malloco(xode_pool p, int size)
00182 {
00183 void *block = xode_pool_malloc(p, size);
00184 memset(block, 0, size);
00185 return block;
00186 }
00187
00188
00189 char *xode_pool_strdup(xode_pool p, const char *src)
00190 {
00191 char *ret;
00192
00193 if(src == NULL)
00194 return NULL;
00195
00196 ret = xode_pool_malloc(p,strlen(src) + 1);
00197 strcpy(ret,src);
00198
00199 return ret;
00200 }
00201
00202
00203 char *xode_pool_strdupx(xode_pool p, const char *src)
00204 {
00205 return xode_pool_strdup(p, src);
00206 }
00207
00208 int xode_pool_size(xode_pool p)
00209 {
00210 if(p == NULL) return 0;
00211
00212 return p->size;
00213 }
00214
00215 void xode_pool_free(xode_pool p)
00216 {
00217 struct xode_pool_free *cur, *stub;
00218
00219 if(p == NULL) return;
00220
00221 cur = p->cleanup;
00222 while(cur != NULL)
00223 {
00224 (*cur->f)(cur->arg);
00225 stub = cur->next;
00226 _xode_pool__free(cur);
00227 cur = stub;
00228 }
00229
00230 _xode_pool__free(p);
00231 }
00232
00233
00234 void xode_pool_cleanup(xode_pool p, xode_pool_cleaner f, void *arg)
00235 {
00236 struct xode_pool_free *clean;
00237
00238 clean = _xode_pool_free(p, f, arg);
00239 clean->next = p->cleanup;
00240 p->cleanup = clean;
00241 }
00242
00243 xode_pool xode_pool_new(void)
00244 {
00245 return _xode_pool_new();
00246 }
00247
00248 xode_pool xode_pool_heap(const int bytes)
00249 {
00250 return _xode_pool_newheap(bytes);
00251 }