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