Jabber WindowGram Client (JWGC)

Introduction Screenshots Installation Downloads
Documentation Browse Source Resources Project Site

Stable Version
-none-

Latest Version
beta5



Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

pool.c

Go to the documentation of this file.
00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00015  *
00016  *  Jabber
00017  *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
00018  *  
00019  *  2/27/00:3am, random plans by jer
00020  *  
00021  *  ok based on gprof, we really need some innovation here... my thoughs are this:
00022  *  
00023  *  most things are strings, so have a string-based true-blue garbage collector
00024  *  one big global hash containing all the strings created by any pstrdup, returning const char *
00025  *  a refcount on each string block
00026  *  when a pool is freed, it moves down the refcount
00027  *  garbage collector collects pools on the free stack, and runs through the hash for unused strings
00028  *  j_strcmp can check for == (if they are both from a pstrdup)
00029  *  
00030  *  let's see... this would change:
00031  *  pstrdup: do a hash lookup, success=return, fail=pmalloc & hash put
00032  *  pool_free: 
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 /* xode_pfree - a linked list node which stores an
00047    allocation chunk, plus a callback */
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 /* make an empty pool */
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 /* free a heap */
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 /* mem should always be freed last */
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     /* fast forward to end of list */
00089     for(cur = p->cleanup; cur->next != NULL; cur = cur->next);
00090 
00091     cur->next = pf;
00092 }
00093 
00094 /* create a cleanup tracker */
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     /* make the storage for the tracker */
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 /* create a heap and make sure it get's cleaned up */
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     /* make the return heap */
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     /* append to the cleanup list */
00122     clean = _xode_pool_free(p, _xode_pool_heapfree, (void *)ret);
00123     clean->heap = ret; /* for future use in finding used mem for pstrdup */
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     /* if there is no heap for this pool or it's a big request, just raw, I like how we clean this :) */
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     /* we have to preserve boundaries, long story :) */
00157     if(size >= 4)
00158         while(p->heap->used&7) p->heap->used++;
00159 
00160     /* if we don't fit in the old heap, replace it */
00161     if(size > (p->heap->size - p->heap->used))
00162         p->heap = _xode_pool_heap(p, p->heap->size);
00163 
00164     /* the current heap has room */
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 /* easy safety utility (for creating blank mem for structs, etc) */
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 /* XXX efficient: move this to const char * and then loop throug the existing heaps to see if src is within a block in this pool */
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 /* when move above, this one would actually return a new block */
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 /* public cleanup utils, insert in a way that they are run FIFO, before mem frees */
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 }


Last updated at Tue Dec 18 21:07:42 PST 2007. This site and project hosted by...SourceForge.net Logo
Source Perspective by Fisheye