1 /*<html><pre> -<a href="qh-mem.htm" 2 >-------------------------------</a><a name="TOP">-</a> 3 4 mem.h 5 prototypes for memory management functions 6 7 see qh-mem.htm, mem.c and qset.h 8 9 for error handling, writes message and calls 10 qh_errexit(qhmem_ERRmem, NULL, NULL) if insufficient memory 11 and 12 qh_errexit(qhmem_ERRqhull, NULL, NULL) otherwise 13 14 Copyright (c) 1993-2015 The Geometry Center. 15 $Id: //main/2015/qhull/src/libqhull/mem.h#2 $$Change: 2062 $ 16 $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $ 17 */ 18 19 #ifndef qhDEFmem 20 #define qhDEFmem 1 21 22 #include <stdio.h> 23 24 /*-<a href="qh-mem.htm#TOC" 25 >-------------------------------</a><a name="NOmem">-</a> 26 27 qh_NOmem 28 turn off quick-fit memory allocation 29 30 notes: 31 mem.c implements Quickfit memory allocation for about 20% time 32 savings. If it fails on your machine, try to locate the 33 problem, and send the answer to qhull@qhull.org. If this can 34 not be done, define qh_NOmem to use malloc/free instead. 35 36 #define qh_NOmem 37 */ 38 39 /*-<a href="qh-mem.htm#TOC" 40 >-------------------------------</a><a name="TRACEshort">-</a> 41 42 qh_TRACEshort 43 Trace short and quick memory allocations at T5 44 45 */ 46 #define qh_TRACEshort 47 48 /*------------------------------------------- 49 to avoid bus errors, memory allocation must consider alignment requirements. 50 malloc() automatically takes care of alignment. Since mem.c manages 51 its own memory, we need to explicitly specify alignment in 52 qh_meminitbuffers(). 53 54 A safe choice is sizeof(double). sizeof(float) may be used if doubles 55 do not occur in data structures and pointers are the same size. Be careful 56 of machines (e.g., DEC Alpha) with large pointers. If gcc is available, 57 use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)). 58 59 see <a href="user.h#MEMalign">qh_MEMalign</a> in user.h for qhull's alignment 60 */ 61 62 #define qhmem_ERRmem 4 /* matches qh_ERRmem in libqhull.h */ 63 #define qhmem_ERRqhull 5 /* matches qh_ERRqhull in libqhull.h */ 64 65 /*-<a href="qh-mem.htm#TOC" 66 >--------------------------------</a><a name="ptr_intT">-</a> 67 68 ptr_intT 69 for casting a void * to an integer-type that holds a pointer 70 Used for integer expressions (e.g., computing qh_gethash() in poly.c) 71 72 notes: 73 WARN64 -- these notes indicate 64-bit issues 74 On 64-bit machines, a pointer may be larger than an 'int'. 75 qh_meminit()/mem.c checks that 'ptr_intT' holds a 'void*' 76 ptr_intT is typically a signed value, but not necessarily so 77 size_t is typically unsigned, but should match the parameter type 78 Qhull uses int instead of size_t except for system calls such as malloc, qsort, qh_malloc, etc. 79 This matches Qt convention and is easier to work with. 80 */ 81 #if (defined(__MINGW64__)) && defined(_WIN64) 82 typedef long long ptr_intT; 83 #elif (_MSC_VER) && defined(_WIN64) 84 typedef long long ptr_intT; 85 #else 86 typedef long ptr_intT; 87 #endif 88 89 /*-<a href="qh-mem.htm#TOC" 90 >--------------------------------</a><a name="qhmemT">-</a> 91 92 qhmemT 93 global memory structure for mem.c 94 95 notes: 96 users should ignore qhmem except for writing extensions 97 qhmem is allocated in mem.c 98 99 qhmem could be swapable like qh and qhstat, but then 100 multiple qh's and qhmem's would need to keep in synch. 101 A swapable qhmem would also waste memory buffers. As long 102 as memory operations are atomic, there is no problem with 103 multiple qh structures being active at the same time. 104 If you need separate address spaces, you can swap the 105 contents of qhmem. 106 */ 107 typedef struct qhmemT qhmemT; 108 extern qhmemT qhmem; 109 110 #ifndef DEFsetT 111 #define DEFsetT 1 112 typedef struct setT setT; /* defined in qset.h */ 113 #endif 114 115 /* Update qhmem in mem.c if add or remove fields */ 116 struct qhmemT { /* global memory management variables */ 117 int BUFsize; /* size of memory allocation buffer */ 118 int BUFinit; /* initial size of memory allocation buffer */ 119 int TABLEsize; /* actual number of sizes in free list table */ 120 int NUMsizes; /* maximum number of sizes in free list table */ 121 int LASTsize; /* last size in free list table */ 122 int ALIGNmask; /* worst-case alignment, must be 2^n-1 */ 123 void **freelists; /* free list table, linked by offset 0 */ 124 int *sizetable; /* size of each freelist */ 125 int *indextable; /* size->index table */ 126 void *curbuffer; /* current buffer, linked by offset 0 */ 127 void *freemem; /* free memory in curbuffer */ 128 int freesize; /* size of freemem in bytes */ 129 setT *tempstack; /* stack of temporary memory, managed by users */ 130 FILE *ferr; /* file for reporting errors when 'qh' may be undefined */ 131 int IStracing; /* =5 if tracing memory allocations */ 132 int cntquick; /* count of quick allocations */ 133 /* Note: removing statistics doesn't effect speed */ 134 int cntshort; /* count of short allocations */ 135 int cntlong; /* count of long allocations */ 136 int freeshort; /* count of short memfrees */ 137 int freelong; /* count of long memfrees */ 138 int totbuffer; /* total short memory buffers minus buffer links */ 139 int totdropped; /* total dropped memory at end of short memory buffers (e.g., freesize) */ 140 int totfree; /* total size of free, short memory on freelists */ 141 int totlong; /* total size of long memory in use */ 142 int maxlong; /* maximum totlong */ 143 int totshort; /* total size of short memory in use */ 144 int totunused; /* total unused short memory (estimated, short size - request size of first allocations) */ 145 int cntlarger; /* count of setlarger's */ 146 int totlarger; /* total copied by setlarger */ 147 }; 148 149 150 /*==================== -macros ====================*/ 151 152 /*-<a href="qh-mem.htm#TOC" 153 >--------------------------------</a><a name="memalloc_">-</a> 154 155 qh_memalloc_(insize, freelistp, object, type) 156 returns object of size bytes 157 assumes size<=qhmem.LASTsize and void **freelistp is a temp 158 */ 159 160 #if defined qh_NOmem 161 #define qh_memalloc_(insize, freelistp, object, type) {\ 162 object= (type*)qh_memalloc(insize); } 163 #elif defined qh_TRACEshort 164 #define qh_memalloc_(insize, freelistp, object, type) {\ 165 freelistp= NULL; /* Avoid warnings */ \ 166 object= (type*)qh_memalloc(insize); } 167 #else /* !qh_NOmem */ 168 169 #define qh_memalloc_(insize, freelistp, object, type) {\ 170 freelistp= qhmem.freelists + qhmem.indextable[insize];\ 171 if ((object= (type*)*freelistp)) {\ 172 qhmem.totshort += qhmem.sizetable[qhmem.indextable[insize]]; \ 173 qhmem.totfree -= qhmem.sizetable[qhmem.indextable[insize]]; \ 174 qhmem.cntquick++; \ 175 *freelistp= *((void **)*freelistp);\ 176 }else object= (type*)qh_memalloc(insize);} 177 #endif 178 179 /*-<a href="qh-mem.htm#TOC" 180 >--------------------------------</a><a name="memfree_">-</a> 181 182 qh_memfree_(object, insize, freelistp) 183 free up an object 184 185 notes: 186 object may be NULL 187 assumes size<=qhmem.LASTsize and void **freelistp is a temp 188 */ 189 #if defined qh_NOmem 190 #define qh_memfree_(object, insize, freelistp) {\ 191 qh_memfree(object, insize); } 192 #elif defined qh_TRACEshort 193 #define qh_memfree_(object, insize, freelistp) {\ 194 freelistp= NULL; /* Avoid warnings */ \ 195 qh_memfree(object, insize); } 196 #else /* !qh_NOmem */ 197 198 #define qh_memfree_(object, insize, freelistp) {\ 199 if (object) { \ 200 qhmem.freeshort++;\ 201 freelistp= qhmem.freelists + qhmem.indextable[insize];\ 202 qhmem.totshort -= qhmem.sizetable[qhmem.indextable[insize]]; \ 203 qhmem.totfree += qhmem.sizetable[qhmem.indextable[insize]]; \ 204 *((void **)object)= *freelistp;\ 205 *freelistp= object;}} 206 #endif 207 208 /*=============== prototypes in alphabetical order ============*/ 209 210 void *qh_memalloc(int insize); 211 void qh_memcheck(void); 212 void qh_memfree(void *object, int insize); 213 void qh_memfreeshort(int *curlong, int *totlong); 214 void qh_meminit(FILE *ferr); 215 void qh_meminitbuffers(int tracelevel, int alignment, int numsizes, 216 int bufsize, int bufinit); 217 void qh_memsetup(void); 218 void qh_memsize(int size); 219 void qh_memstatistics(FILE *fp); 220 void qh_memtotal(int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer); 221 222 #endif /* qhDEFmem */ 223