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