mem_r.c
Go to the documentation of this file.
1 /*<html><pre> -<a href="qh-mem_r.htm"
2  >-------------------------------</a><a name="TOP">-</a>
3 
4  mem_r.c
5  memory management routines for qhull
6 
7  See libqhull/mem_r.c for a standalone program.
8 
9  To initialize memory:
10 
11  qh_meminit(qh, stderr);
12  qh_meminitbuffers(qh, qh->IStracing, qh_MEMalign, 7, qh_MEMbufsize,qh_MEMinitbuf);
13  qh_memsize(qh, (int)sizeof(facetT));
14  qh_memsize(qh, (int)sizeof(facetT));
15  ...
16  qh_memsetup(qh);
17 
18  To free up all memory buffers:
19  qh_memfreeshort(qh, &curlong, &totlong);
20 
21  if qh_NOmem,
22  malloc/free is used instead of mem.c
23 
24  notes:
25  uses Quickfit algorithm (freelists for commonly allocated sizes)
26  assumes small sizes for freelists (it discards the tail of memory buffers)
27 
28  see:
29  qh-mem_r.htm and mem_r.h
30  global_r.c (qh_initbuffers) for an example of using mem_r.c
31 
32  Copyright (c) 1993-2015 The Geometry Center.
33  $Id: //main/2015/qhull/src/libqhull_r/mem_r.c#5 $$Change: 2065 $
34  $DateTime: 2016/01/18 13:51:04 $$Author: bbarber $
35 */
36 
37 #include "libqhull_r.h" /* includes user_r.h and mem_r.h */
38 
39 #include <string.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 
43 #ifndef qh_NOmem
44 
45 /*============= internal functions ==============*/
46 
47 static int qh_intcompare(const void *i, const void *j);
48 
49 /*========== functions in alphabetical order ======== */
50 
51 /*-<a href="qh-mem_r.htm#TOC"
52  >-------------------------------</a><a name="intcompare">-</a>
53 
54  qh_intcompare( i, j )
55  used by qsort and bsearch to compare two integers
56 */
57 static int qh_intcompare(const void *i, const void *j) {
58  return(*((const int *)i) - *((const int *)j));
59 } /* intcompare */
60 
61 
62 /*-<a href="qh-mem_r.htm#TOC"
63  >--------------------------------</a><a name="memalloc">-</a>
64 
65  qh_memalloc( qh, insize )
66  returns object of insize bytes
67  qhmem is the global memory structure
68 
69  returns:
70  pointer to allocated memory
71  errors if insufficient memory
72 
73  notes:
74  use explicit type conversion to avoid type warnings on some compilers
75  actual object may be larger than insize
76  use qh_memalloc_() for inline code for quick allocations
77  logs allocations if 'T5'
78  caller is responsible for freeing the memory.
79  short memory is freed on shutdown by qh_memfreeshort unless qh_NOmem
80 
81  design:
82  if size < qh->qhmem.LASTsize
83  if qh->qhmem.freelists[size] non-empty
84  return first object on freelist
85  else
86  round up request to size of qh->qhmem.freelists[size]
87  allocate new allocation buffer if necessary
88  allocate object from allocation buffer
89  else
90  allocate object with qh_malloc() in user.c
91 */
92 void *qh_memalloc(qhT *qh, int insize) {
93  void **freelistp, *newbuffer;
94  int idx, size, n;
95  int outsize, bufsize;
96  void *object;
97 
98  if (insize<0) {
99  qh_fprintf(qh, qh->qhmem.ferr, 6235, "qhull error (qh_memalloc): negative request size (%d). Did int overflow due to high-D?\n", insize); /* WARN64 */
100  qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
101  }
102  if (insize>=0 && insize <= qh->qhmem.LASTsize) {
103  idx= qh->qhmem.indextable[insize];
104  outsize= qh->qhmem.sizetable[idx];
105  qh->qhmem.totshort += outsize;
106  freelistp= qh->qhmem.freelists+idx;
107  if ((object= *freelistp)) {
108  qh->qhmem.cntquick++;
109  qh->qhmem.totfree -= outsize;
110  *freelistp= *((void **)*freelistp); /* replace freelist with next object */
111 #ifdef qh_TRACEshort
112  n= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
113  if (qh->qhmem.IStracing >= 5)
114  qh_fprintf(qh, qh->qhmem.ferr, 8141, "qh_mem %p n %8d alloc quick: %d bytes (tot %d cnt %d)\n", object, n, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
115 #endif
116  return(object);
117  }else {
118  qh->qhmem.cntshort++;
119  if (outsize > qh->qhmem.freesize) {
120  qh->qhmem.totdropped += qh->qhmem.freesize;
121  if (!qh->qhmem.curbuffer)
122  bufsize= qh->qhmem.BUFinit;
123  else
124  bufsize= qh->qhmem.BUFsize;
125  if (!(newbuffer= qh_malloc((size_t)bufsize))) {
126  qh_fprintf(qh, qh->qhmem.ferr, 6080, "qhull error (qh_memalloc): insufficient memory to allocate short memory buffer (%d bytes)\n", bufsize);
127  qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
128  }
129  *((void **)newbuffer)= qh->qhmem.curbuffer; /* prepend newbuffer to curbuffer
130  list. newbuffer!=0 by QH6080 */
131  qh->qhmem.curbuffer= newbuffer;
132  size= (sizeof(void **) + qh->qhmem.ALIGNmask) & ~qh->qhmem.ALIGNmask;
133  qh->qhmem.freemem= (void *)((char *)newbuffer+size);
134  qh->qhmem.freesize= bufsize - size;
135  qh->qhmem.totbuffer += bufsize - size; /* easier to check */
136  /* Periodically test totbuffer. It matches at beginning and exit of every call */
137  n = qh->qhmem.totshort + qh->qhmem.totfree + qh->qhmem.totdropped + qh->qhmem.freesize - outsize;
138  if (qh->qhmem.totbuffer != n) {
139  qh_fprintf(qh, qh->qhmem.ferr, 6212, "qh_memalloc internal error: short totbuffer %d != totshort+totfree... %d\n", qh->qhmem.totbuffer, n);
140  qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
141  }
142  }
143  object= qh->qhmem.freemem;
144  qh->qhmem.freemem= (void *)((char *)qh->qhmem.freemem + outsize);
145  qh->qhmem.freesize -= outsize;
146  qh->qhmem.totunused += outsize - insize;
147 #ifdef qh_TRACEshort
148  n= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
149  if (qh->qhmem.IStracing >= 5)
150  qh_fprintf(qh, qh->qhmem.ferr, 8140, "qh_mem %p n %8d alloc short: %d bytes (tot %d cnt %d)\n", object, n, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
151 #endif
152  return object;
153  }
154  }else { /* long allocation */
155  if (!qh->qhmem.indextable) {
156  qh_fprintf(qh, qh->qhmem.ferr, 6081, "qhull internal error (qh_memalloc): qhmem has not been initialized.\n");
157  qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
158  }
159  outsize= insize;
160  qh->qhmem.cntlong++;
161  qh->qhmem.totlong += outsize;
162  if (qh->qhmem.maxlong < qh->qhmem.totlong)
163  qh->qhmem.maxlong= qh->qhmem.totlong;
164  if (!(object= qh_malloc((size_t)outsize))) {
165  qh_fprintf(qh, qh->qhmem.ferr, 6082, "qhull error (qh_memalloc): insufficient memory to allocate %d bytes\n", outsize);
166  qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
167  }
168  if (qh->qhmem.IStracing >= 5)
169  qh_fprintf(qh, qh->qhmem.ferr, 8057, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, outsize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
170  }
171  return(object);
172 } /* memalloc */
173 
174 
175 /*-<a href="qh-mem_r.htm#TOC"
176  >--------------------------------</a><a name="memcheck">-</a>
177 
178  qh_memcheck(qh)
179 */
181  int i, count, totfree= 0;
182  void *object;
183 
184  if (!qh) {
185  qh_fprintf_stderr(6243, "qh_memcheck(qh) error: qh is 0. It does not point to a qhT");
186  qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
187  }
188  if (qh->qhmem.ferr == 0 || qh->qhmem.IStracing < 0 || qh->qhmem.IStracing > 10 || (((qh->qhmem.ALIGNmask+1) & qh->qhmem.ALIGNmask) != 0)) {
189  qh_fprintf_stderr(6244, "qh_memcheck error: either qh->qhmem is overwritten or qh->qhmem is not initialized. Call qh_mem_new() or qh_new_qhull() before calling qh_mem routines. ferr 0x%x IsTracing %d ALIGNmask 0x%x", qh->qhmem.ferr, qh->qhmem.IStracing, qh->qhmem.ALIGNmask);
190  qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
191  }
192  if (qh->qhmem.IStracing != 0)
193  qh_fprintf(qh, qh->qhmem.ferr, 8143, "qh_memcheck: check size of freelists on qh->qhmem\nqh_memcheck: A segmentation fault indicates an overwrite of qh->qhmem\n");
194  for (i=0; i < qh->qhmem.TABLEsize; i++) {
195  count=0;
196  for (object= qh->qhmem.freelists[i]; object; object= *((void **)object))
197  count++;
198  totfree += qh->qhmem.sizetable[i] * count;
199  }
200  if (totfree != qh->qhmem.totfree) {
201  qh_fprintf(qh, qh->qhmem.ferr, 6211, "Qhull internal error (qh_memcheck): totfree %d not equal to freelist total %d\n", qh->qhmem.totfree, totfree);
202  qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
203  }
204  if (qh->qhmem.IStracing != 0)
205  qh_fprintf(qh, qh->qhmem.ferr, 8144, "qh_memcheck: total size of freelists totfree is the same as qh->qhmem.totfree\n", totfree);
206 } /* memcheck */
207 
208 /*-<a href="qh-mem_r.htm#TOC"
209  >--------------------------------</a><a name="memfree">-</a>
210 
211  qh_memfree(qh, object, insize )
212  free up an object of size bytes
213  size is insize from qh_memalloc
214 
215  notes:
216  object may be NULL
217  type checking warns if using (void **)object
218  use qh_memfree_() for quick free's of small objects
219 
220  design:
221  if size <= qh->qhmem.LASTsize
222  append object to corresponding freelist
223  else
224  call qh_free(object)
225 */
226 void qh_memfree(qhT *qh, void *object, int insize) {
227  void **freelistp;
228  int idx, outsize;
229 
230  if (!object)
231  return;
232  if (insize <= qh->qhmem.LASTsize) {
233  qh->qhmem.freeshort++;
234  idx= qh->qhmem.indextable[insize];
235  outsize= qh->qhmem.sizetable[idx];
236  qh->qhmem.totfree += outsize;
237  qh->qhmem.totshort -= outsize;
238  freelistp= qh->qhmem.freelists + idx;
239  *((void **)object)= *freelistp;
240  *freelistp= object;
241 #ifdef qh_TRACEshort
242  idx= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
243  if (qh->qhmem.IStracing >= 5)
244  qh_fprintf(qh, qh->qhmem.ferr, 8142, "qh_mem %p n %8d free short: %d bytes (tot %d cnt %d)\n", object, idx, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
245 #endif
246  }else {
247  qh->qhmem.freelong++;
248  qh->qhmem.totlong -= insize;
249  if (qh->qhmem.IStracing >= 5)
250  qh_fprintf(qh, qh->qhmem.ferr, 8058, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
251  qh_free(object);
252  }
253 } /* memfree */
254 
255 
256 /*-<a href="qh-mem_r.htm#TOC"
257  >-------------------------------</a><a name="memfreeshort">-</a>
258 
259  qh_memfreeshort(qh, curlong, totlong )
260  frees up all short and qhmem memory allocations
261 
262  returns:
263  number and size of current long allocations
264 
265  notes:
266  if qh_NOmem (qh_malloc() for all allocations),
267  short objects (e.g., facetT) are not recovered.
268  use qh_freeqhull(qh, qh_ALL) instead.
269 
270  see:
271  qh_freeqhull(qh, allMem)
272  qh_memtotal(qh, curlong, totlong, curshort, totshort, maxlong, totbuffer);
273 */
274 void qh_memfreeshort(qhT *qh, int *curlong, int *totlong) {
275  void *buffer, *nextbuffer;
276  FILE *ferr;
277 
278  *curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
279  *totlong= qh->qhmem.totlong;
280  for (buffer= qh->qhmem.curbuffer; buffer; buffer= nextbuffer) {
281  nextbuffer= *((void **) buffer);
282  qh_free(buffer);
283  }
284  qh->qhmem.curbuffer= NULL;
285  if (qh->qhmem.LASTsize) {
286  qh_free(qh->qhmem.indextable);
287  qh_free(qh->qhmem.freelists);
288  qh_free(qh->qhmem.sizetable);
289  }
290  ferr= qh->qhmem.ferr;
291  memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
292  qh->qhmem.ferr= ferr;
293 } /* memfreeshort */
294 
295 
296 /*-<a href="qh-mem_r.htm#TOC"
297  >--------------------------------</a><a name="meminit">-</a>
298 
299  qh_meminit(qh, ferr )
300  initialize qhmem and test sizeof( void*)
301  Does not throw errors. qh_exit on failure
302 */
303 void qh_meminit(qhT *qh, FILE *ferr) {
304 
305  memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
306  if (ferr)
307  qh->qhmem.ferr= ferr;
308  else
309  qh->qhmem.ferr= stderr;
310  if (sizeof(void*) < sizeof(int)) {
311  qh_fprintf(qh, qh->qhmem.ferr, 6083, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d. qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
312  qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
313  }
314  if (sizeof(void*) > sizeof(ptr_intT)) {
315  qh_fprintf(qh, qh->qhmem.ferr, 6084, "qhull internal error (qh_meminit): sizeof(void*) %d > sizeof(ptr_intT) %d. Change ptr_intT in mem.h to 'long long'\n", (int)sizeof(void*), (int)sizeof(ptr_intT));
316  qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
317  }
318  qh_memcheck(qh);
319 } /* meminit */
320 
321 /*-<a href="qh-mem_r.htm#TOC"
322  >-------------------------------</a><a name="meminitbuffers">-</a>
323 
324  qh_meminitbuffers(qh, tracelevel, alignment, numsizes, bufsize, bufinit )
325  initialize qhmem
326  if tracelevel >= 5, trace memory allocations
327  alignment= desired address alignment for memory allocations
328  numsizes= number of freelists
329  bufsize= size of additional memory buffers for short allocations
330  bufinit= size of initial memory buffer for short allocations
331 */
332 void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
333 
334  qh->qhmem.IStracing= tracelevel;
335  qh->qhmem.NUMsizes= numsizes;
336  qh->qhmem.BUFsize= bufsize;
337  qh->qhmem.BUFinit= bufinit;
338  qh->qhmem.ALIGNmask= alignment-1;
339  if (qh->qhmem.ALIGNmask & ~qh->qhmem.ALIGNmask) {
340  qh_fprintf(qh, qh->qhmem.ferr, 6085, "qhull internal error (qh_meminit): memory alignment %d is not a power of 2\n", alignment);
341  qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
342  }
343  qh->qhmem.sizetable= (int *) calloc((size_t)numsizes, sizeof(int));
344  qh->qhmem.freelists= (void **) calloc((size_t)numsizes, sizeof(void *));
345  if (!qh->qhmem.sizetable || !qh->qhmem.freelists) {
346  qh_fprintf(qh, qh->qhmem.ferr, 6086, "qhull error (qh_meminit): insufficient memory\n");
347  qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
348  }
349  if (qh->qhmem.IStracing >= 1)
350  qh_fprintf(qh, qh->qhmem.ferr, 8059, "qh_meminitbuffers: memory initialized with alignment %d\n", alignment);
351 } /* meminitbuffers */
352 
353 /*-<a href="qh-mem_r.htm#TOC"
354  >-------------------------------</a><a name="memsetup">-</a>
355 
356  qh_memsetup(qh)
357  set up memory after running memsize()
358 */
360  int k,i;
361 
362  qsort(qh->qhmem.sizetable, (size_t)qh->qhmem.TABLEsize, sizeof(int), qh_intcompare);
363  qh->qhmem.LASTsize= qh->qhmem.sizetable[qh->qhmem.TABLEsize-1];
364  if(qh->qhmem.LASTsize >= qh->qhmem.BUFsize || qh->qhmem.LASTsize >= qh->qhmem.BUFinit) {
365  qh_fprintf(qh, qh->qhmem.ferr, 6087, "qhull error (qh_memsetup): largest mem size %d is >= buffer size %d or initial buffer size %d\n",
366  qh->qhmem.LASTsize, qh->qhmem.BUFsize, qh->qhmem.BUFinit);
367  qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
368  }
369  if (!(qh->qhmem.indextable= (int *)qh_malloc((qh->qhmem.LASTsize+1) * sizeof(int)))) {
370  qh_fprintf(qh, qh->qhmem.ferr, 6088, "qhull error (qh_memsetup): insufficient memory\n");
371  qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
372  }
373  for (k=qh->qhmem.LASTsize+1; k--; )
374  qh->qhmem.indextable[k]= k;
375  i= 0;
376  for (k=0; k <= qh->qhmem.LASTsize; k++) {
377  if (qh->qhmem.indextable[k] <= qh->qhmem.sizetable[i])
378  qh->qhmem.indextable[k]= i;
379  else
380  qh->qhmem.indextable[k]= ++i;
381  }
382 } /* memsetup */
383 
384 /*-<a href="qh-mem_r.htm#TOC"
385  >-------------------------------</a><a name="memsize">-</a>
386 
387  qh_memsize(qh, size )
388  define a free list for this size
389 */
390 void qh_memsize(qhT *qh, int size) {
391  int k;
392 
393  if(qh->qhmem.LASTsize) {
394  qh_fprintf(qh, qh->qhmem.ferr, 6089, "qhull error (qh_memsize): called after qhmem_setup\n");
395  qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
396  }
397  size= (size + qh->qhmem.ALIGNmask) & ~qh->qhmem.ALIGNmask;
398  for (k=qh->qhmem.TABLEsize; k--; ) {
399  if (qh->qhmem.sizetable[k] == size)
400  return;
401  }
402  if (qh->qhmem.TABLEsize < qh->qhmem.NUMsizes)
403  qh->qhmem.sizetable[qh->qhmem.TABLEsize++]= size;
404  else
405  qh_fprintf(qh, qh->qhmem.ferr, 7060, "qhull warning (memsize): free list table has room for only %d sizes\n", qh->qhmem.NUMsizes);
406 } /* memsize */
407 
408 
409 /*-<a href="qh-mem_r.htm#TOC"
410  >-------------------------------</a><a name="memstatistics">-</a>
411 
412  qh_memstatistics(qh, fp )
413  print out memory statistics
414 
415  Verifies that qh->qhmem.totfree == sum of freelists
416 */
417 void qh_memstatistics(qhT *qh, FILE *fp) {
418  int i;
419  int count;
420  void *object;
421 
422  qh_memcheck(qh);
423  qh_fprintf(qh, fp, 9278, "\nmemory statistics:\n\
424 %7d quick allocations\n\
425 %7d short allocations\n\
426 %7d long allocations\n\
427 %7d short frees\n\
428 %7d long frees\n\
429 %7d bytes of short memory in use\n\
430 %7d bytes of short memory in freelists\n\
431 %7d bytes of dropped short memory\n\
432 %7d bytes of unused short memory (estimated)\n\
433 %7d bytes of long memory allocated (max, except for input)\n\
434 %7d bytes of long memory in use (in %d pieces)\n\
435 %7d bytes of short memory buffers (minus links)\n\
436 %7d bytes per short memory buffer (initially %d bytes)\n",
437  qh->qhmem.cntquick, qh->qhmem.cntshort, qh->qhmem.cntlong,
438  qh->qhmem.freeshort, qh->qhmem.freelong,
439  qh->qhmem.totshort, qh->qhmem.totfree,
440  qh->qhmem.totdropped + qh->qhmem.freesize, qh->qhmem.totunused,
441  qh->qhmem.maxlong, qh->qhmem.totlong, qh->qhmem.cntlong - qh->qhmem.freelong,
442  qh->qhmem.totbuffer, qh->qhmem.BUFsize, qh->qhmem.BUFinit);
443  if (qh->qhmem.cntlarger) {
444  qh_fprintf(qh, fp, 9279, "%7d calls to qh_setlarger\n%7.2g average copy size\n",
445  qh->qhmem.cntlarger, ((float)qh->qhmem.totlarger)/(float)qh->qhmem.cntlarger);
446  qh_fprintf(qh, fp, 9280, " freelists(bytes->count):");
447  }
448  for (i=0; i < qh->qhmem.TABLEsize; i++) {
449  count=0;
450  for (object= qh->qhmem.freelists[i]; object; object= *((void **)object))
451  count++;
452  qh_fprintf(qh, fp, 9281, " %d->%d", qh->qhmem.sizetable[i], count);
453  }
454  qh_fprintf(qh, fp, 9282, "\n\n");
455 } /* memstatistics */
456 
457 
458 /*-<a href="qh-mem_r.htm#TOC"
459  >-------------------------------</a><a name="NOmem">-</a>
460 
461  qh_NOmem
462  turn off quick-fit memory allocation
463 
464  notes:
465  uses qh_malloc() and qh_free() instead
466 */
467 #else /* qh_NOmem */
468 
469 void *qh_memalloc(qhT *qh, int insize) {
470  void *object;
471 
472  if (!(object= qh_malloc((size_t)insize))) {
473  qh_fprintf(qh, qh->qhmem.ferr, 6090, "qhull error (qh_memalloc): insufficient memory\n");
474  qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
475  }
476  qh->qhmem.cntlong++;
477  qh->qhmem.totlong += insize;
478  if (qh->qhmem.maxlong < qh->qhmem.totlong)
479  qh->qhmem.maxlong= qh->qhmem.totlong;
480  if (qh->qhmem.IStracing >= 5)
481  qh_fprintf(qh, qh->qhmem.ferr, 8060, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
482  return object;
483 }
484 
485 void qh_memfree(qhT *qh, void *object, int insize) {
486 
487  if (!object)
488  return;
489  qh_free(object);
490  qh->qhmem.freelong++;
491  qh->qhmem.totlong -= insize;
492  if (qh->qhmem.IStracing >= 5)
493  qh_fprintf(qh, qh->qhmem.ferr, 8061, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
494 }
495 
496 void qh_memfreeshort(qhT *qh, int *curlong, int *totlong) {
497  *totlong= qh->qhmem.totlong;
498  *curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
499  memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
500 }
501 
502 void qh_meminit(qhT *qh, FILE *ferr) {
503 
504  memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
505  if (ferr)
506  qh->qhmem.ferr= ferr;
507  else
508  qh->qhmem.ferr= stderr;
509  if (sizeof(void*) < sizeof(int)) {
510  qh_fprintf(qh, qh->qhmem.ferr, 6091, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d. qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
511  qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
512  }
513 }
514 
515 void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
516 
517  qh->qhmem.IStracing= tracelevel;
518 }
519 
520 void qh_memsetup(qhT *qh) {
521 
522 }
523 
524 void qh_memsize(qhT *qh, int size) {
525 
526 }
527 
528 void qh_memstatistics(qhT *qh, FILE *fp) {
529 
530  qh_fprintf(qh, fp, 9409, "\nmemory statistics:\n\
531 %7d long allocations\n\
532 %7d long frees\n\
533 %7d bytes of long memory allocated (max, except for input)\n\
534 %7d bytes of long memory in use (in %d pieces)\n",
535  qh->qhmem.cntlong,
536  qh->qhmem.freelong,
537  qh->qhmem.maxlong, qh->qhmem.totlong, qh->qhmem.cntlong - qh->qhmem.freelong);
538 }
539 
540 #endif /* qh_NOmem */
541 
542 /*-<a href="qh-mem_r.htm#TOC"
543 >-------------------------------</a><a name="memtotlong">-</a>
544 
545  qh_memtotal(qh, totlong, curlong, totshort, curshort, maxlong, totbuffer )
546  Return the total, allocated long and short memory
547 
548  returns:
549  Returns the total current bytes of long and short allocations
550  Returns the current count of long and short allocations
551  Returns the maximum long memory and total short buffer (minus one link per buffer)
552  Does not error (for deprecated UsingLibQhull.cpp (libqhullpcpp))
553 */
554 void qh_memtotal(qhT *qh, int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer) {
555  *totlong= qh->qhmem.totlong;
556  *curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
557  *totshort= qh->qhmem.totshort;
558  *curshort= qh->qhmem.cntshort + qh->qhmem.cntquick - qh->qhmem.freeshort;
559  *maxlong= qh->qhmem.maxlong;
560  *totbuffer= qh->qhmem.totbuffer;
561 } /* memtotlong */
562 
Definition: libqhull.h:465
int TABLEsize
Definition: mem.h:119
int NUMsizes
Definition: mem.h:120
void * qh_malloc(size_t size)
Definition: usermem.c:90
int freelong
Definition: mem.h:137
int totunused
Definition: mem.h:144
int cntlong
Definition: mem.h:135
void qh_fprintf_stderr(int msgcode, const char *fmt,...)
Definition: usermem.c:57
void qh_free(void *mem)
Definition: usermem.c:77
long ptr_intT
Definition: mem.h:86
qhmemT qhmem
Definition: mem.c:62
int totdropped
Definition: mem.h:139
int cntlarger
Definition: mem.h:145
int totlarger
Definition: mem.h:146
void qh_fprintf(FILE *fp, int msgcode, const char *fmt,...)
Definition: userprintf.c:42
int BUFinit
Definition: mem.h:118
int totshort
Definition: mem.h:143
void qh_memfreeshort(qhT *qh, int *curlong, int *totlong)
Definition: mem_r.c:274
#define qhmem_ERRmem
Definition: mem.h:62
int maxlong
Definition: mem.h:142
void * curbuffer
Definition: mem.h:126
int cntquick
Definition: mem.h:132
void qh_memsetup(qhT *qh)
Definition: mem_r.c:359
#define qh
Definition: libqhull.h:457
#define qhmem_ERRqhull
Definition: mem.h:63
int cntshort
Definition: mem.h:134
void qh_memfree(qhT *qh, void *object, int insize)
Definition: mem_r.c:226
int LASTsize
Definition: mem.h:121
int totfree
Definition: mem.h:140
int freesize
Definition: mem.h:128
int ALIGNmask
Definition: mem.h:122
void qh_memsize(qhT *qh, int size)
Definition: mem_r.c:390
int * sizetable
Definition: mem.h:124
void qh_exit(int exitcode)
int * indextable
Definition: mem.h:125
void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit)
Definition: mem_r.c:332
void * qh_memalloc(qhT *qh, int insize)
Definition: mem_r.c:92
int totbuffer
Definition: mem.h:138
void qh_memtotal(qhT *qh, int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer)
Definition: mem_r.c:554
void ** freelists
Definition: mem.h:123
int IStracing
Definition: mem.h:131
int BUFsize
Definition: mem.h:117
void qh_memstatistics(qhT *qh, FILE *fp)
Definition: mem_r.c:417
qhmemT qhmem
Definition: libqhull_r.h:785
void * freemem
Definition: mem.h:127
void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge)
Definition: user.c:213
int totlong
Definition: mem.h:141
FILE * ferr
Definition: mem.h:130
static int qh_intcompare(const void *i, const void *j)
Definition: mem_r.c:57
void qh_memcheck(qhT *qh)
Definition: mem_r.c:180
void qh_meminit(qhT *qh, FILE *ferr)
Definition: mem_r.c:303
int freeshort
Definition: mem.h:136


hpp-fcl
Author(s):
autogenerated on Fri Jun 2 2023 02:39:01