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-2011 The Geometry Center. 00015 $Id: //main/2011/qhull/src/libqhull/mem.h#3 $$Change: 1356 $ 00016 $DateTime: 2011/04/03 09:01:22 $$Author: bbarber $ 00017 */ 00018 00019 #ifndef qhDEFmem 00020 #define qhDEFmem 1 00021 00022 #include <stdio.h> 00023 00024 /*-<a href="qh-mem.htm#TOC" 00025 >-------------------------------</a><a name="NOmem">-</a> 00026 00027 qh_NOmem 00028 turn off quick-fit memory allocation 00029 00030 notes: 00031 mem.c implements Quickfit memory allocation for about 20% time 00032 savings. If it fails on your machine, try to locate the 00033 problem, and send the answer to qhull@qhull.org. If this can 00034 not be done, define qh_NOmem to use malloc/free instead. 00035 00036 #define qh_NOmem 00037 */ 00038 00039 /*-<a href="qh-mem.htm#TOC" 00040 >-------------------------------</a><a name="TRACEshort">-</a> 00041 00042 qh_TRACEshort 00043 Trace short and quick memory allocations at T5 00044 00045 */ 00046 #define qh_TRACEshort 00047 00048 /*------------------------------------------- 00049 to avoid bus errors, memory allocation must consider alignment requirements. 00050 malloc() automatically takes care of alignment. Since mem.c manages 00051 its own memory, we need to explicitly specify alignment in 00052 qh_meminitbuffers(). 00053 00054 A safe choice is sizeof(double). sizeof(float) may be used if doubles 00055 do not occur in data structures and pointers are the same size. Be careful 00056 of machines (e.g., DEC Alpha) with large pointers. If gcc is available, 00057 use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)). 00058 00059 see <a href="user.h#MEMalign">qh_MEMalign</a> in user.h for qhull's alignment 00060 */ 00061 00062 #define qhmem_ERRmem 4 /* matches qh_ERRmem in libqhull.h */ 00063 #define qhmem_ERRqhull 5 /* matches qh_ERRqhull in libqhull.h */ 00064 00065 /*-<a href="qh-mem.htm#TOC" 00066 >--------------------------------</a><a name="ptr_intT">-</a> 00067 00068 ptr_intT 00069 for casting a void * to an integer-type that holds a pointer 00070 Used for integer expressions (e.g., computing qh_gethash() in poly.c) 00071 00072 notes: 00073 WARN64 -- these notes indicate 64-bit issues 00074 On 64-bit machines, a pointer may be larger than an 'int'. 00075 qh_meminit()/mem.c checks that 'ptr_intT' holds a 'void*' 00076 ptr_intT is typically a signed value, but not necessarily so 00077 size_t is typically unsigned, but should match the parameter type 00078 Qhull uses int instead of size_t except for system calls such as malloc, qsort, qh_malloc, etc. 00079 This matches Qt convention and is easier to work with. 00080 */ 00081 #if _MSC_VER && defined(_WIN64) 00082 typedef long long ptr_intT; 00083 #else 00084 typedef long ptr_intT; 00085 #endif 00086 00087 /*-<a href="qh-mem.htm#TOC" 00088 >--------------------------------</a><a name="qhmemT">-</a> 00089 00090 qhmemT 00091 global memory structure for mem.c 00092 00093 notes: 00094 users should ignore qhmem except for writing extensions 00095 qhmem is allocated in mem.c 00096 00097 qhmem could be swapable like qh and qhstat, but then 00098 multiple qh's and qhmem's would need to keep in synch. 00099 A swapable qhmem would also waste memory buffers. As long 00100 as memory operations are atomic, there is no problem with 00101 multiple qh structures being active at the same time. 00102 If you need separate address spaces, you can swap the 00103 contents of qhmem. 00104 */ 00105 typedef struct qhmemT qhmemT; 00106 extern qhmemT qhmem; 00107 00108 #ifndef DEFsetT 00109 #define DEFsetT 1 00110 typedef struct setT setT; /* defined in qset.h */ 00111 #endif 00112 00113 /* Update qhmem in mem.c if add or remove fields */ 00114 struct qhmemT { /* global memory management variables */ 00115 int BUFsize; /* size of memory allocation buffer */ 00116 int BUFinit; /* initial size of memory allocation buffer */ 00117 int TABLEsize; /* actual number of sizes in free list table */ 00118 int NUMsizes; /* maximum number of sizes in free list table */ 00119 int LASTsize; /* last size in free list table */ 00120 int ALIGNmask; /* worst-case alignment, must be 2^n-1 */ 00121 void **freelists; /* free list table, linked by offset 0 */ 00122 int *sizetable; /* size of each freelist */ 00123 int *indextable; /* size->index table */ 00124 void *curbuffer; /* current buffer, linked by offset 0 */ 00125 void *freemem; /* free memory in curbuffer */ 00126 int freesize; /* size of freemem in bytes */ 00127 setT *tempstack; /* stack of temporary memory, managed by users */ 00128 FILE *ferr; /* file for reporting errors, only user is qh_fprintf() */ 00129 int IStracing; /* =5 if tracing memory allocations */ 00130 int cntquick; /* count of quick allocations */ 00131 /* Note: removing statistics doesn't effect speed */ 00132 int cntshort; /* count of short allocations */ 00133 int cntlong; /* count of long allocations */ 00134 int freeshort; /* count of short memfrees */ 00135 int freelong; /* count of long memfrees */ 00136 int totbuffer; /* total short memory buffers minus buffer links */ 00137 int totdropped; /* total dropped memory at end of short memory buffers (e.g., freesize) */ 00138 int totfree; /* total size of free, short memory on freelists */ 00139 int totlong; /* total size of long memory in use */ 00140 int maxlong; /* maximum totlong */ 00141 int totshort; /* total size of short memory in use */ 00142 int totunused; /* total unused short memory (estimated, short size - request size of first allocations) */ 00143 int cntlarger; /* count of setlarger's */ 00144 int totlarger; /* total copied by setlarger */ 00145 }; 00146 00147 00148 /*==================== -macros ====================*/ 00149 00150 /*-<a href="qh-mem.htm#TOC" 00151 >--------------------------------</a><a name="memalloc_">-</a> 00152 00153 qh_memalloc_(insize, object, type) 00154 returns object of size bytes 00155 assumes size<=qhmem.LASTsize and void **freelistp is a temp 00156 */ 00157 00158 #if defined qh_NOmem 00159 #define qh_memalloc_(insize, freelistp, object, type) {\ 00160 object= (type*)qh_memalloc(insize); } 00161 #elif defined qh_TRACEshort 00162 #define qh_memalloc_(insize, freelistp, object, type) {\ 00163 freelistp= NULL; /* Avoid warnings */ \ 00164 object= (type*)qh_memalloc(insize); } 00165 #else /* !qh_NOmem */ 00166 00167 #define qh_memalloc_(insize, freelistp, object, type) {\ 00168 freelistp= qhmem.freelists + qhmem.indextable[insize];\ 00169 if ((object= (type*)*freelistp)) {\ 00170 qhmem.totshort += qhmem.sizetable[qhmem.indextable[insize]]; \ 00171 qhmem.totfree -= qhmem.sizetable[qhmem.indextable[insize]]; \ 00172 qhmem.cntquick++; \ 00173 *freelistp= *((void **)*freelistp);\ 00174 }else object= (type*)qh_memalloc(insize);} 00175 #endif 00176 00177 /*-<a href="qh-mem.htm#TOC" 00178 >--------------------------------</a><a name="memfree_">-</a> 00179 00180 qh_memfree_(object, insize) 00181 free up an object 00182 00183 notes: 00184 object may be NULL 00185 assumes size<=qhmem.LASTsize and void **freelistp is a temp 00186 */ 00187 #if defined qh_NOmem 00188 #define qh_memfree_(object, insize, freelistp) {\ 00189 qh_memfree(object, insize); } 00190 #elif defined qh_TRACEshort 00191 #define qh_memfree_(object, insize, freelistp) {\ 00192 freelistp= NULL; /* Avoid warnings */ \ 00193 qh_memfree(object, insize); } 00194 #else /* !qh_NOmem */ 00195 00196 #define qh_memfree_(object, insize, freelistp) {\ 00197 if (object) { \ 00198 qhmem .freeshort++;\ 00199 freelistp= qhmem.freelists + qhmem.indextable[insize];\ 00200 qhmem.totshort -= qhmem.sizetable[qhmem.indextable[insize]]; \ 00201 qhmem.totfree += qhmem.sizetable[qhmem.indextable[insize]]; \ 00202 *((void **)object)= *freelistp;\ 00203 *freelistp= object;}} 00204 #endif 00205 00206 /*=============== prototypes in alphabetical order ============*/ 00207 00208 void *qh_memalloc(int insize); 00209 void qh_memfree(void *object, int insize); 00210 void qh_memfreeshort(int *curlong, int *totlong); 00211 void qh_meminit(FILE *ferr); 00212 void qh_meminitbuffers(int tracelevel, int alignment, int numsizes, 00213 int bufsize, int bufinit); 00214 void qh_memsetup(void); 00215 void qh_memsize(int size); 00216 void qh_memstatistics(FILE *fp); 00217 void qh_memtotal(int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer); 00218 00219 #endif /* qhDEFmem */