00001 /*<html><pre> -<a href="qh-mem.htm" 00002 >-------------------------------</a><a name="TOP">-</a> 00003 00004 mem.h 00005 prototypes for memory management functions 00006 00007 see qh-mem.htm, mem.c and qset.h 00008 00009 for error handling, writes message and calls 00010 qh_errexit (qhmem_ERRmem, NULL, NULL) if insufficient memory 00011 and 00012 qh_errexit (qhmem_ERRqhull, NULL, NULL) otherwise 00013 00014 copyright (c) 1993-2003, The Geometry Center 00015 */ 00016 00017 #ifndef qhDEFmem 00018 #define qhDEFmem 00019 00020 /*-<a href="qh-mem.htm#TOC" 00021 >-------------------------------</a><a name="NOmem">-</a> 00022 00023 qh_NOmem 00024 turn off quick-fit memory allocation 00025 00026 notes: 00027 mem.c implements Quickfit memory allocation for about 20% time 00028 savings. If it fails on your machine, try to locate the 00029 problem, and send the answer to qhull@qhull.org. If this can 00030 not be done, define qh_NOmem to use malloc/free instead. 00031 00032 #define qh_NOmem 00033 */ 00034 00035 /*------------------------------------------- 00036 to avoid bus errors, memory allocation must consider alignment requirements. 00037 malloc() automatically takes care of alignment. Since mem.c manages 00038 its own memory, we need to explicitly specify alignment in 00039 qh_meminitbuffers(). 00040 00041 A safe choice is sizeof(double). sizeof(float) may be used if doubles 00042 do not occur in data structures and pointers are the same size. Be careful 00043 of machines (e.g., DEC Alpha) with large pointers. If gcc is available, 00044 use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)). 00045 00046 see <a href="user.h#MEMalign">qh_MEMalign</a> in user.h for qhull's alignment 00047 */ 00048 00049 #define qhmem_ERRmem 4 /* matches qh_ERRmem in qhull.h */ 00050 #define qhmem_ERRqhull 5 /* matches qh_ERRqhull in qhull.h */ 00051 00052 /*-<a href="qh-mem.htm#TOC" 00053 >--------------------------------</a><a name="ptr_intT">-</a> 00054 00055 ptr_intT 00056 for casting a void* to an integer-type 00057 00058 notes: 00059 On 64-bit machines, a pointer may be larger than an 'int'. 00060 qh_meminit() checks that 'long' holds a 'void*' 00061 */ 00062 typedef unsigned long ptr_intT; 00063 00064 /*-<a href="qh-mem.htm#TOC" 00065 >--------------------------------</a><a name="qhmemT">-</a> 00066 00067 qhmemT 00068 global memory structure for mem.c 00069 00070 notes: 00071 users should ignore qhmem except for writing extensions 00072 qhmem is allocated in mem.c 00073 00074 qhmem could be swapable like qh and qhstat, but then 00075 multiple qh's and qhmem's would need to keep in synch. 00076 A swapable qhmem would also waste memory buffers. As long 00077 as memory operations are atomic, there is no problem with 00078 multiple qh structures being active at the same time. 00079 If you need separate address spaces, you can swap the 00080 contents of qhmem. 00081 */ 00082 typedef struct qhmemT qhmemT; 00083 extern qhmemT qhmem; 00084 00085 struct qhmemT { /* global memory management variables */ 00086 int BUFsize; /* size of memory allocation buffer */ 00087 int BUFinit; /* initial size of memory allocation buffer */ 00088 int TABLEsize; /* actual number of sizes in free list table */ 00089 int NUMsizes; /* maximum number of sizes in free list table */ 00090 int LASTsize; /* last size in free list table */ 00091 int ALIGNmask; /* worst-case alignment, must be 2^n-1 */ 00092 void **freelists; /* free list table, linked by offset 0 */ 00093 int *sizetable; /* size of each freelist */ 00094 int *indextable; /* size->index table */ 00095 void *curbuffer; /* current buffer, linked by offset 0 */ 00096 void *freemem; /* free memory in curbuffer */ 00097 int freesize; /* size of free memory in bytes */ 00098 void *tempstack; /* stack of temporary memory, managed by users */ 00099 FILE *ferr; /* file for reporting errors */ 00100 int IStracing; /* =5 if tracing memory allocations */ 00101 int cntquick; /* count of quick allocations */ 00102 /* remove statistics doesn't effect speed */ 00103 int cntshort; /* count of short allocations */ 00104 int cntlong; /* count of long allocations */ 00105 int curlong; /* current count of inuse, long allocations */ 00106 int freeshort; /* count of short memfrees */ 00107 int freelong; /* count of long memfrees */ 00108 int totshort; /* total size of short allocations */ 00109 int totlong; /* total size of long allocations */ 00110 int maxlong; /* maximum totlong */ 00111 int cntlarger; /* count of setlarger's */ 00112 int totlarger; /* total copied by setlarger */ 00113 }; 00114 00115 00116 /*==================== -macros ====================*/ 00117 00118 /*-<a href="qh-mem.htm#TOC" 00119 >--------------------------------</a><a name="memalloc_">-</a> 00120 00121 qh_memalloc_(size, object, type) 00122 returns object of size bytes 00123 assumes size<=qhmem.LASTsize and void **freelistp is a temp 00124 */ 00125 00126 #ifdef qh_NOmem 00127 #define qh_memalloc_(size, freelistp, object, type) {\ 00128 object= (type*)qh_memalloc (size); } 00129 #else /* !qh_NOmem */ 00130 00131 #define qh_memalloc_(size, freelistp, object, type) {\ 00132 freelistp= qhmem.freelists + qhmem.indextable[size];\ 00133 if ((object= (type*)*freelistp)) {\ 00134 qhmem.cntquick++; \ 00135 *freelistp= *((void **)*freelistp);\ 00136 }else object= (type*)qh_memalloc (size);} 00137 #endif 00138 00139 /*-<a href="qh-mem.htm#TOC" 00140 >--------------------------------</a><a name="memfree_">-</a> 00141 00142 qh_memfree_(object, size) 00143 free up an object 00144 00145 notes: 00146 object may be NULL 00147 assumes size<=qhmem.LASTsize and void **freelistp is a temp 00148 */ 00149 #ifdef qh_NOmem 00150 #define qh_memfree_(object, size, freelistp) {\ 00151 qh_memfree (object, size); } 00152 #else /* !qh_NOmem */ 00153 00154 #define qh_memfree_(object, size, freelistp) {\ 00155 if (object) { \ 00156 qhmem .freeshort++;\ 00157 freelistp= qhmem.freelists + qhmem.indextable[size];\ 00158 *((void **)object)= *freelistp;\ 00159 *freelistp= object;}} 00160 #endif 00161 00162 /*=============== prototypes in alphabetical order ============*/ 00163 00164 void *qh_memalloc(int insize); 00165 void qh_memfree (void *object, int size); 00166 void qh_memfreeshort (int *curlong, int *totlong); 00167 void qh_meminit (FILE *ferr); 00168 void qh_meminitbuffers (int tracelevel, int alignment, int numsizes, 00169 int bufsize, int bufinit); 00170 void qh_memsetup (void); 00171 void qh_memsize(int size); 00172 void qh_memstatistics (FILE *fp); 00173 00174 #endif /* qhDEFmem */