00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __ALLOCRUS_H__
00024 #define __ALLOCRUS_H__
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 extern int ILLTRACE_MALLOC;
00045
00046 #ifndef USEDMALLOC
00047 #define ILL_UTIL_SAFE_MALLOC(nnum,type,varname) \
00048 (((ILLTRACE_MALLOC) ? printf("%s.%d: %s: ILL_UTIL_SAFE_MALLOC: %s = %d * %s\n", __FILE__, __LINE__, __DEV_FUNCTION__, #varname, nnum, #type) : 0), \
00049 (type *) ILLutil_allocrus (((size_t) (nnum)) * sizeof (type)))
00050 #else
00051 #define ILL_UTIL_SAFE_MALLOC(nnum,type,varname) \
00052 (((ILLTRACE_MALLOC) ? printf("%s.%d: %s: ILL_UTIL_SAFE_MALLOC: %s = %d * %s\n", __FILE__, __LINE__, __DEV_FUNCTION__, #varname, nnum, #type) : 0), \
00053 (type *) malloc (((size_t) (nnum)) * sizeof (type)))
00054 #endif
00055
00056 #define ILL_IFFREE(object,type) { \
00057 if ((object)) { \
00058 ILLutil_freerus ((void *) (object)); \
00059 object = (type *) NULL; \
00060 }}
00061
00062 #define ILL_PTRWORLD_ALLOC_ROUTINE(type, ptr_alloc_r, ptr_bulkalloc_r) \
00063 \
00064 static int ptr_bulkalloc_r (ILLptrworld *world, int nalloc) \
00065 { \
00066 ILLbigchunkptr *bp; \
00067 int i; \
00068 int count = ILL_BIGCHUNK / sizeof ( type ); \
00069 type *p; \
00070 \
00071 while (nalloc > 0) { \
00072 bp = ILLutil_bigchunkalloc (); \
00073 if (bp == (ILLbigchunkptr *) NULL) { \
00074 fprintf (stderr, "ptr alloc failed\n"); \
00075 return 1; \
00076 } \
00077 bp->next = world->chunklist ; \
00078 world->chunklist = bp; \
00079 \
00080 p = ( type * ) bp->this_one; \
00081 for (i=count-2; i>=0; i--) { \
00082 p[i].next = &p[i+1]; \
00083 } \
00084 p[count - 1].next = (type *) world->freelist; \
00085 world->freelist = (void *) p; \
00086 nalloc -= count; \
00087 } \
00088 return 0; \
00089 } \
00090 \
00091 static type *ptr_alloc_r (ILLptrworld *world) \
00092 { \
00093 type *p; \
00094 \
00095 if (world->freelist == (void *) NULL) { \
00096 if (ptr_bulkalloc_r (world, 1)) { \
00097 fprintf (stderr, "ptr alloc failed\n"); \
00098 return ( type * ) NULL; \
00099 } \
00100 } \
00101 p = (type *) world->freelist ; \
00102 world->freelist = (void *) p->next; \
00103 \
00104 return p; \
00105 }
00106
00107 #define ILL_PTRWORLD_FREE_ROUTINE(type, ptr_free_r) \
00108 \
00109 static void ptr_free_r (ILLptrworld *world, type *p) \
00110 { \
00111 p->next = (type *) world->freelist ; \
00112 world->freelist = (void *) p; \
00113 }
00114
00115 #define ILL_PTRWORLD_LISTADD_ROUTINE(type, entrytype, ptr_listadd_r, ptr_alloc_r) \
00116 \
00117 static int ptr_listadd_r (type **list, entrytype x, ILLptrworld *world) \
00118 { \
00119 if (list != (type **) NULL) { \
00120 type *p = ptr_alloc_r (world); \
00121 \
00122 if (p == (type *) NULL) { \
00123 fprintf (stderr, "ptr list add failed\n"); \
00124 return 1; \
00125 } \
00126 p->this = x; \
00127 p->next = *list; \
00128 *list = p; \
00129 } \
00130 return 0; \
00131 }
00132
00133 #define ILL_PTRWORLD_LISTFREE_ROUTINE(type, ptr_listfree_r, ptr_free_r) \
00134 \
00135 static void ptr_listfree_r (ILLptrworld *world, type *p) \
00136 { \
00137 type *next; \
00138 \
00139 while (p != (type *) NULL) { \
00140 next = p->next; \
00141 ptr_free_r (world, p); \
00142 p = next; \
00143 } \
00144 }
00145
00146 #define ILL_PTRWORLD_LEAKS_ROUTINE(type, ptr_leaks_r, field, fieldtype) \
00147 \
00148 static int ptr_leaks_r (ILLptrworld *world, int *total, int *onlist) \
00149 { \
00150 int count = ILL_BIGCHUNK / sizeof ( type ); \
00151 int duplicates = 0; \
00152 type * p; \
00153 ILLbigchunkptr *bp; \
00154 \
00155 *total = 0; \
00156 *onlist = 0; \
00157 \
00158 for (bp = world->chunklist ; bp; bp = bp->next) \
00159 (*total) += count; \
00160 \
00161 for (p = (type *) world->freelist ; p; p = p->next) { \
00162 (*onlist)++; \
00163 p-> field = ( fieldtype ) 0; \
00164 } \
00165 for (p = (type *) world->freelist ; p; p = p->next) { \
00166 if ((unsigned long) p-> field == (unsigned long) (size_t) 1) \
00167 duplicates++; \
00168 else \
00169 p-> field = ( fieldtype ) (size_t) 1; \
00170 } \
00171 if (duplicates) { \
00172 fprintf (stderr, "WARNING: %d duplicates on ptr free list \n", \
00173 duplicates); \
00174 } \
00175 return *total - *onlist; \
00176 }
00177
00178 #define ILL_PTRWORLD_ROUTINES(type, ptr_alloc_r, ptr_bulkalloc_r, ptr_free_r) \
00179 ILL_PTRWORLD_ALLOC_ROUTINE (type, ptr_alloc_r, ptr_bulkalloc_r) \
00180 ILL_PTRWORLD_FREE_ROUTINE (type, ptr_free_r)
00181
00182 #define ILL_PTRWORLD_LIST_ROUTINES(type, entrytype, ptr_alloc_r, ptr_bulkalloc_r, ptr_free_r, ptr_listadd_r, ptr_listfree_r) \
00183 ILL_PTRWORLD_ROUTINES (type, ptr_alloc_r, ptr_bulkalloc_r, ptr_free_r) \
00184 ILL_PTRWORLD_LISTADD_ROUTINE (type, entrytype, ptr_listadd_r, ptr_alloc_r) \
00185 ILL_PTRWORLD_LISTFREE_ROUTINE (type, ptr_listfree_r, ptr_free_r)
00186
00187 #define ILL_BIGCHUNK ((int) ((1<<16) - sizeof (ILLbigchunkptr) - 16))
00188
00189 struct ILLbigchunk;
00190
00191 typedef struct ILLbigchunkptr
00192 {
00193 void *this_one;
00194 struct ILLbigchunk *this_chunk;
00195 struct ILLbigchunkptr *next;
00196 }
00197 ILLbigchunkptr;
00198
00199
00200 typedef struct ILLptrworld
00201 {
00202 int refcount;
00203 void *freelist;
00204 ILLbigchunkptr *chunklist;
00205 }
00206 ILLptrworld;
00207
00208
00209
00210 void *ILLutil_allocrus (
00211 size_t size),
00212 *ILLutil_reallocrus (
00213 void *ptr,
00214 size_t size),
00215 ILLutil_freerus (
00216 void *p),
00217 ILLutil_bigchunkfree (
00218 ILLbigchunkptr * bp),
00219 ILLptrworld_init (
00220 ILLptrworld * world),
00221 ILLptrworld_add (
00222 ILLptrworld * world),
00223 ILLptrworld_delete (
00224 ILLptrworld * world);
00225
00226 int ILLutil_reallocrus_scale (
00227 void **pptr,
00228 int *pnnum,
00229 int count,
00230 double scale,
00231 size_t size),
00232 ILLutil_reallocrus_count (
00233 void **pptr,
00234 int count,
00235 size_t size);
00236
00237 ILLbigchunkptr *ILLutil_bigchunkalloc (
00238 void);
00239
00240
00241
00242 #endif