LCOV - code coverage report
Current view: top level - alg/internal_libqhull - mem_r.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 128 191 67.0 %
Date: 2024-05-02 00:41:30 Functions: 9 11 81.8 %

          Line data    Source code
       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.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_r.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-2020 The Geometry Center.
      33             :   $Id: //main/2019/qhull/src/libqhull_r/mem_r.c#7 $$Change: 2953 $
      34             :   $DateTime: 2020/05/21 22:05:32 $$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          44 : static int qh_intcompare(const void *i, const void *j) {
      58          44 :   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_r.c
      91             : */
      92     1084450 : 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     1084450 :   if (insize<0) {
      99           0 :       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           0 :       qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
     101             :   }
     102     1084450 :   if (insize>=0 && insize <= qh->qhmem.LASTsize) {
     103     1043970 :     idx= qh->qhmem.indextable[insize];
     104     1043970 :     outsize= qh->qhmem.sizetable[idx];
     105     1043970 :     qh->qhmem.totshort += outsize;
     106     1043970 :     freelistp= qh->qhmem.freelists+idx;
     107     1043970 :     if ((object= *freelistp)) {
     108      659885 :       qh->qhmem.cntquick++;
     109      659885 :       qh->qhmem.totfree -= outsize;
     110      659885 :       *freelistp= *((void **)*freelistp);  /* replace freelist with next object */
     111             : #ifdef qh_TRACEshort
     112      659885 :       n= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
     113      659885 :       if (qh->qhmem.IStracing >= 5)
     114           0 :           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      659885 :       return(object);
     117             :     }else {
     118      384088 :       qh->qhmem.cntshort++;
     119      384088 :       if (outsize > qh->qhmem.freesize) {
     120         349 :         qh->qhmem.totdropped += qh->qhmem.freesize;
     121         349 :         if (!qh->qhmem.curbuffer)
     122           4 :           bufsize= qh->qhmem.BUFinit;
     123             :         else
     124         345 :           bufsize= qh->qhmem.BUFsize;
     125         349 :         if (!(newbuffer= qh_malloc((size_t)bufsize))) {
     126           0 :           qh_fprintf(qh, qh->qhmem.ferr, 6080, "qhull error (qh_memalloc): insufficient memory to allocate short memory buffer (%d bytes)\n", bufsize);
     127           0 :           qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
     128             :         }
     129         349 :         *((void **)newbuffer)= qh->qhmem.curbuffer;  /* prepend newbuffer to curbuffer
     130             :                                                     list.  newbuffer!=0 by QH6080 */
     131         349 :         qh->qhmem.curbuffer= newbuffer;
     132         349 :         size= ((int)sizeof(void **) + qh->qhmem.ALIGNmask) & ~qh->qhmem.ALIGNmask;
     133         349 :         qh->qhmem.freemem= (void *)((char *)newbuffer+size);
     134         349 :         qh->qhmem.freesize= bufsize - size;
     135         349 :         qh->qhmem.totbuffer += bufsize - size; /* easier to check */
     136             :         /* Periodically test totbuffer.  It matches at beginning and exit of every call */
     137         349 :         n= qh->qhmem.totshort + qh->qhmem.totfree + qh->qhmem.totdropped + qh->qhmem.freesize - outsize;
     138         349 :         if (qh->qhmem.totbuffer != n) {
     139           0 :             qh_fprintf(qh, qh->qhmem.ferr, 6212, "qhull internal error (qh_memalloc): short totbuffer %d != totshort+totfree... %d\n", qh->qhmem.totbuffer, n);
     140           0 :             qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
     141             :         }
     142             :       }
     143      384088 :       object= qh->qhmem.freemem;
     144      384088 :       qh->qhmem.freemem= (void *)((char *)qh->qhmem.freemem + outsize);
     145      384088 :       qh->qhmem.freesize -= outsize;
     146      384088 :       qh->qhmem.totunused += outsize - insize;
     147             : #ifdef qh_TRACEshort
     148      384088 :       n= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
     149      384088 :       if (qh->qhmem.IStracing >= 5)
     150           0 :           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      384088 :       return object;
     153             :     }
     154             :   }else {                     /* long allocation */
     155       40473 :     if (!qh->qhmem.indextable) {
     156           0 :       qh_fprintf(qh, qh->qhmem.ferr, 6081, "qhull internal error (qh_memalloc): qhmem has not been initialized.\n");
     157           0 :       qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
     158             :     }
     159       40473 :     outsize= insize;
     160       40473 :     qh->qhmem.cntlong++;
     161       40473 :     qh->qhmem.totlong += outsize;
     162       40473 :     if (qh->qhmem.maxlong < qh->qhmem.totlong)
     163       10011 :       qh->qhmem.maxlong= qh->qhmem.totlong;
     164       40473 :     if (!(object= qh_malloc((size_t)outsize))) {
     165           0 :       qh_fprintf(qh, qh->qhmem.ferr, 6082, "qhull error (qh_memalloc): insufficient memory to allocate %d bytes\n", outsize);
     166           0 :       qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
     167             :     }
     168       40473 :     if (qh->qhmem.IStracing >= 5)
     169           0 :       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       40473 :   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             : */
     180          10 : void qh_memcheck(qhT *qh) {
     181          10 :   int i, count, totfree= 0;
     182             :   void *object;
     183             : 
     184          10 :   if (!qh) {
     185           0 :     qh_fprintf_stderr(6243, "qhull internal error (qh_memcheck): qh is 0.  It does not point to a qhT\n");
     186           0 :     qh_exit(qhmem_ERRqhull);  /* can not use qh_errexit() */
     187             :   }
     188          10 :   if (qh->qhmem.ferr == 0 || qh->qhmem.IStracing < 0 || qh->qhmem.IStracing > 10 || (((qh->qhmem.ALIGNmask+1) & qh->qhmem.ALIGNmask) != 0)) {
     189           0 :     qh_fprintf_stderr(6244, "qhull internal error (qh_memcheck): either qh->qhmem is overwritten or qh->qhmem is not initialized.  Call qh_meminit or qh_new_qhull before calling qh_mem routines.  ferr %p, IsTracing %d, ALIGNmask 0x%x\n",
     190             :           qh->qhmem.ferr, qh->qhmem.IStracing, qh->qhmem.ALIGNmask);
     191           0 :     qh_exit(qhmem_ERRqhull);  /* can not use qh_errexit() */
     192             :   }
     193          10 :   if (qh->qhmem.IStracing != 0)
     194           0 :     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");
     195          10 :   for (i=0; i < qh->qhmem.TABLEsize; i++) {
     196           0 :     count=0;
     197           0 :     for (object= qh->qhmem.freelists[i]; object; object= *((void **)object))
     198           0 :       count++;
     199           0 :     totfree += qh->qhmem.sizetable[i] * count;
     200             :   }
     201          10 :   if (totfree != qh->qhmem.totfree) {
     202           0 :     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);
     203           0 :     qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
     204             :   }
     205          10 :   if (qh->qhmem.IStracing != 0)
     206           0 :     qh_fprintf(qh, qh->qhmem.ferr, 8144, "qh_memcheck: total size of freelists totfree is the same as qh->qhmem.totfree\n", totfree);
     207          10 : } /* memcheck */
     208             : 
     209             : /*-<a                             href="qh-mem_r.htm#TOC"
     210             :   >--------------------------------</a><a name="memfree">-</a>
     211             : 
     212             :   qh_memfree(qh, object, insize )
     213             :     free up an object of size bytes
     214             :     size is insize from qh_memalloc
     215             : 
     216             :   notes:
     217             :     object may be NULL
     218             :     type checking warns if using (void **)object
     219             :     use qh_memfree_() for quick free's of small objects
     220             : 
     221             :   design:
     222             :     if size <= qh->qhmem.LASTsize
     223             :       append object to corresponding freelist
     224             :     else
     225             :       call qh_free(object)
     226             : */
     227     1019820 : void qh_memfree(qhT *qh, void *object, int insize) {
     228             :   void **freelistp;
     229             :   int idx, outsize;
     230             : 
     231     1019820 :   if (!object)
     232       75090 :     return;
     233      944728 :   if (insize <= qh->qhmem.LASTsize) {
     234      904255 :     qh->qhmem.freeshort++;
     235      904255 :     idx= qh->qhmem.indextable[insize];
     236      904255 :     outsize= qh->qhmem.sizetable[idx];
     237      904255 :     qh->qhmem.totfree += outsize;
     238      904255 :     qh->qhmem.totshort -= outsize;
     239      904255 :     freelistp= qh->qhmem.freelists + idx;
     240      904255 :     *((void **)object)= *freelistp;
     241      904255 :     *freelistp= object;
     242             : #ifdef qh_TRACEshort
     243      904255 :     idx= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
     244      904255 :     if (qh->qhmem.IStracing >= 5)
     245           0 :         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);
     246             : #endif
     247             :   }else {
     248       40473 :     qh->qhmem.freelong++;
     249       40473 :     qh->qhmem.totlong -= insize;
     250       40473 :     if (qh->qhmem.IStracing >= 5)
     251           0 :       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);
     252       40473 :     qh_free(object);
     253             :   }
     254             : } /* memfree */
     255             : 
     256             : 
     257             : /*-<a                             href="qh-mem_r.htm#TOC"
     258             :   >-------------------------------</a><a name="memfreeshort">-</a>
     259             : 
     260             :   qh_memfreeshort(qh, curlong, totlong )
     261             :     frees up all short and qhmem memory allocations
     262             : 
     263             :   returns:
     264             :     number and size of current long allocations
     265             : 
     266             :   notes:
     267             :     if qh_NOmem (qh_malloc() for all allocations),
     268             :        short objects (e.g., facetT) are not recovered.
     269             :        use qh_freeqhull(qh, qh_ALL) instead.
     270             : 
     271             :   see:
     272             :     qh_freeqhull(qh, allMem)
     273             :     qh_memtotal(qh, curlong, totlong, curshort, totshort, maxlong, totbuffer);
     274             : */
     275           5 : void qh_memfreeshort(qhT *qh, int *curlong, int *totlong) {
     276             :   void *buffer, *nextbuffer;
     277             :   FILE *ferr;
     278             : 
     279           5 :   *curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
     280           5 :   *totlong= qh->qhmem.totlong;
     281         354 :   for (buffer=qh->qhmem.curbuffer; buffer; buffer= nextbuffer) {
     282         349 :     nextbuffer= *((void **) buffer);
     283         349 :     qh_free(buffer);
     284             :   }
     285           5 :   qh->qhmem.curbuffer= NULL;
     286           5 :   if (qh->qhmem.LASTsize) {
     287           4 :     qh_free(qh->qhmem.indextable);
     288           4 :     qh_free(qh->qhmem.freelists);
     289           4 :     qh_free(qh->qhmem.sizetable);
     290             :   }
     291           5 :   ferr= qh->qhmem.ferr;
     292           5 :   memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem));  /* every field is 0, FALSE, NULL */
     293           5 :   qh->qhmem.ferr= ferr;
     294           5 : } /* memfreeshort */
     295             : 
     296             : 
     297             : /*-<a                             href="qh-mem_r.htm#TOC"
     298             :   >--------------------------------</a><a name="meminit">-</a>
     299             : 
     300             :   qh_meminit(qh, ferr )
     301             :     initialize qhmem and test sizeof(void *)
     302             :     Does not throw errors.  qh_exit on failure
     303             : */
     304           5 : void qh_meminit(qhT *qh, FILE *ferr) {
     305             : 
     306           5 :   memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem));  /* every field is 0, FALSE, NULL */
     307           5 :   if (ferr)
     308           0 :     qh->qhmem.ferr= ferr;
     309             :   else
     310           5 :     qh->qhmem.ferr= stderr;
     311             :   if (sizeof(void *) < sizeof(int)) {
     312             :     qh_fprintf(qh, qh->qhmem.ferr, 6083, "qhull internal error (qh_meminit): sizeof(void *) %d < sizeof(int) %d.  qset_r.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
     313             :     qh_exit(qhmem_ERRqhull);  /* can not use qh_errexit() */
     314             :   }
     315             :   if (sizeof(void *) > sizeof(ptr_intT)) {
     316             :     qh_fprintf(qh, qh->qhmem.ferr, 6084, "qhull internal error (qh_meminit): sizeof(void *) %d > sizeof(ptr_intT) %d. Change ptr_intT in mem_r.h to 'long long'\n", (int)sizeof(void*), (int)sizeof(ptr_intT));
     317             :     qh_exit(qhmem_ERRqhull);  /* can not use qh_errexit() */
     318             :   }
     319           5 :   qh_memcheck(qh);
     320           5 : } /* meminit */
     321             : 
     322             : /*-<a                             href="qh-mem_r.htm#TOC"
     323             :   >-------------------------------</a><a name="meminitbuffers">-</a>
     324             : 
     325             :   qh_meminitbuffers(qh, tracelevel, alignment, numsizes, bufsize, bufinit )
     326             :     initialize qhmem
     327             :     if tracelevel >= 5, trace memory allocations
     328             :     alignment= desired address alignment for memory allocations
     329             :     numsizes= number of freelists
     330             :     bufsize=  size of additional memory buffers for short allocations
     331             :     bufinit=  size of initial memory buffer for short allocations
     332             : */
     333           4 : void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
     334             : 
     335           4 :   qh->qhmem.IStracing= tracelevel;
     336           4 :   qh->qhmem.NUMsizes= numsizes;
     337           4 :   qh->qhmem.BUFsize= bufsize;
     338           4 :   qh->qhmem.BUFinit= bufinit;
     339           4 :   qh->qhmem.ALIGNmask= alignment-1;
     340             :   if (qh->qhmem.ALIGNmask & ~qh->qhmem.ALIGNmask) {
     341             :     qh_fprintf(qh, qh->qhmem.ferr, 6085, "qhull internal error (qh_meminit): memory alignment %d is not a power of 2\n", alignment);
     342             :     qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
     343             :   }
     344           4 :   qh->qhmem.sizetable= (int *) calloc((size_t)numsizes, sizeof(int));
     345           4 :   qh->qhmem.freelists= (void **) calloc((size_t)numsizes, sizeof(void *));
     346           4 :   if (!qh->qhmem.sizetable || !qh->qhmem.freelists) {
     347           0 :     qh_fprintf(qh, qh->qhmem.ferr, 6086, "qhull error (qh_meminit): insufficient memory\n");
     348           0 :     qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
     349             :   }
     350           4 :   if (qh->qhmem.IStracing >= 1)
     351           0 :     qh_fprintf(qh, qh->qhmem.ferr, 8059, "qh_meminitbuffers: memory initialized with alignment %d\n", alignment);
     352           4 : } /* meminitbuffers */
     353             : 
     354             : /*-<a                             href="qh-mem_r.htm#TOC"
     355             :   >-------------------------------</a><a name="memsetup">-</a>
     356             : 
     357             :   qh_memsetup(qh)
     358             :     set up memory after running memsize()
     359             : */
     360           4 : void qh_memsetup(qhT *qh) {
     361             :   int k,i;
     362             : 
     363           4 :   qsort(qh->qhmem.sizetable, (size_t)qh->qhmem.TABLEsize, sizeof(int), qh_intcompare);
     364           4 :   qh->qhmem.LASTsize= qh->qhmem.sizetable[qh->qhmem.TABLEsize-1];
     365           4 :   if (qh->qhmem.LASTsize >= qh->qhmem.BUFsize || qh->qhmem.LASTsize >= qh->qhmem.BUFinit) {
     366           0 :     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",
     367             :             qh->qhmem.LASTsize, qh->qhmem.BUFsize, qh->qhmem.BUFinit);
     368           0 :     qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
     369             :   }
     370           4 :   if (!(qh->qhmem.indextable= (int *)qh_malloc((size_t)(qh->qhmem.LASTsize+1) * sizeof(int)))) {
     371           0 :     qh_fprintf(qh, qh->qhmem.ferr, 6088, "qhull error (qh_memsetup): insufficient memory\n");
     372           0 :     qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
     373             :   }
     374         488 :   for (k=qh->qhmem.LASTsize+1; k--; )
     375         484 :     qh->qhmem.indextable[k]= k;
     376           4 :   i= 0;
     377         488 :   for (k=0; k <= qh->qhmem.LASTsize; k++) {
     378         484 :     if (qh->qhmem.indextable[k] <= qh->qhmem.sizetable[i])
     379         464 :       qh->qhmem.indextable[k]= i;
     380             :     else
     381          20 :       qh->qhmem.indextable[k]= ++i;
     382             :   }
     383           4 : } /* memsetup */
     384             : 
     385             : /*-<a                             href="qh-mem_r.htm#TOC"
     386             :   >-------------------------------</a><a name="memsize">-</a>
     387             : 
     388             :   qh_memsize(qh, size )
     389             :     define a free list for this size
     390             : */
     391          28 : void qh_memsize(qhT *qh, int size) {
     392             :   int k;
     393             : 
     394          28 :   if (qh->qhmem.LASTsize) {
     395           0 :     qh_fprintf(qh, qh->qhmem.ferr, 6089, "qhull internal error (qh_memsize): qh_memsize called after qh_memsetup\n");
     396           0 :     qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
     397             :   }
     398          28 :   size= (size + qh->qhmem.ALIGNmask) & ~qh->qhmem.ALIGNmask;
     399          28 :   if (qh->qhmem.IStracing >= 3)
     400           0 :     qh_fprintf(qh, qh->qhmem.ferr, 3078, "qh_memsize: quick memory of %d bytes\n", size);
     401          96 :   for (k=qh->qhmem.TABLEsize; k--; ) {
     402          72 :     if (qh->qhmem.sizetable[k] == size)
     403           4 :       return;
     404             :   }
     405          24 :   if (qh->qhmem.TABLEsize < qh->qhmem.NUMsizes)
     406          24 :     qh->qhmem.sizetable[qh->qhmem.TABLEsize++]= size;
     407             :   else
     408           0 :     qh_fprintf(qh, qh->qhmem.ferr, 7060, "qhull warning (qh_memsize): free list table has room for only %d sizes\n", qh->qhmem.NUMsizes);
     409             : } /* memsize */
     410             : 
     411             : 
     412             : /*-<a                             href="qh-mem_r.htm#TOC"
     413             :   >-------------------------------</a><a name="memstatistics">-</a>
     414             : 
     415             :   qh_memstatistics(qh, fp )
     416             :     print out memory statistics
     417             : 
     418             :     Verifies that qh->qhmem.totfree == sum of freelists
     419             : */
     420           0 : void qh_memstatistics(qhT *qh, FILE *fp) {
     421             :   int i;
     422             :   int count;
     423             :   void *object;
     424             : 
     425           0 :   qh_memcheck(qh);
     426           0 :   qh_fprintf(qh, fp, 9278, "\nmemory statistics:\n\
     427             : %7d quick allocations\n\
     428             : %7d short allocations\n\
     429             : %7d long allocations\n\
     430             : %7d short frees\n\
     431             : %7d long frees\n\
     432             : %7d bytes of short memory in use\n\
     433             : %7d bytes of short memory in freelists\n\
     434             : %7d bytes of dropped short memory\n\
     435             : %7d bytes of unused short memory (estimated)\n\
     436             : %7d bytes of long memory allocated (max, except for input)\n\
     437             : %7d bytes of long memory in use (in %d pieces)\n\
     438             : %7d bytes of short memory buffers (minus links)\n\
     439             : %7d bytes per short memory buffer (initially %d bytes)\n",
     440             :            qh->qhmem.cntquick, qh->qhmem.cntshort, qh->qhmem.cntlong,
     441             :            qh->qhmem.freeshort, qh->qhmem.freelong,
     442             :            qh->qhmem.totshort, qh->qhmem.totfree,
     443           0 :            qh->qhmem.totdropped + qh->qhmem.freesize, qh->qhmem.totunused,
     444           0 :            qh->qhmem.maxlong, qh->qhmem.totlong, qh->qhmem.cntlong - qh->qhmem.freelong,
     445             :            qh->qhmem.totbuffer, qh->qhmem.BUFsize, qh->qhmem.BUFinit);
     446           0 :   if (qh->qhmem.cntlarger) {
     447           0 :     qh_fprintf(qh, fp, 9279, "%7d calls to qh_setlarger\n%7.2g     average copy size\n",
     448           0 :            qh->qhmem.cntlarger, ((double)qh->qhmem.totlarger)/(double)qh->qhmem.cntlarger);
     449           0 :     qh_fprintf(qh, fp, 9280, "  freelists(bytes->count):");
     450             :   }
     451           0 :   for (i=0; i < qh->qhmem.TABLEsize; i++) {
     452           0 :     count=0;
     453           0 :     for (object= qh->qhmem.freelists[i]; object; object= *((void **)object))
     454           0 :       count++;
     455           0 :     qh_fprintf(qh, fp, 9281, " %d->%d", qh->qhmem.sizetable[i], count);
     456             :   }
     457           0 :   qh_fprintf(qh, fp, 9282, "\n\n");
     458           0 : } /* memstatistics */
     459             : 
     460             : 
     461             : /*-<a                             href="qh-mem_r.htm#TOC"
     462             :   >-------------------------------</a><a name="NOmem">-</a>
     463             : 
     464             :   qh_NOmem
     465             :     turn off quick-fit memory allocation
     466             : 
     467             :   notes:
     468             :     uses qh_malloc() and qh_free() instead
     469             : */
     470             : #else /* qh_NOmem */
     471             : 
     472             : void *qh_memalloc(qhT *qh, int insize) {
     473             :   void *object;
     474             : 
     475             :   if (!(object= qh_malloc((size_t)insize))) {
     476             :     qh_fprintf(qh, qh->qhmem.ferr, 6090, "qhull error (qh_memalloc): insufficient memory\n");
     477             :     qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
     478             :   }
     479             :   qh->qhmem.cntlong++;
     480             :   qh->qhmem.totlong += insize;
     481             :   if (qh->qhmem.maxlong < qh->qhmem.totlong)
     482             :       qh->qhmem.maxlong= qh->qhmem.totlong;
     483             :   if (qh->qhmem.IStracing >= 5)
     484             :     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);
     485             :   return object;
     486             : }
     487             : 
     488             : void qh_memcheck(qhT *qh) {
     489             : }
     490             : 
     491             : void qh_memfree(qhT *qh, void *object, int insize) {
     492             : 
     493             :   if (!object)
     494             :     return;
     495             :   qh_free(object);
     496             :   qh->qhmem.freelong++;
     497             :   qh->qhmem.totlong -= insize;
     498             :   if (qh->qhmem.IStracing >= 5)
     499             :     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);
     500             : }
     501             : 
     502             : void qh_memfreeshort(qhT *qh, int *curlong, int *totlong) {
     503             :   *totlong= qh->qhmem.totlong;
     504             :   *curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
     505             :   memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem));  /* every field is 0, FALSE, NULL */
     506             : }
     507             : 
     508             : void qh_meminit(qhT *qh, FILE *ferr) {
     509             : 
     510             :   memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem));  /* every field is 0, FALSE, NULL */
     511             :   if (ferr)
     512             :       qh->qhmem.ferr= ferr;
     513             :   else
     514             :       qh->qhmem.ferr= stderr;
     515             :   if (sizeof(void *) < sizeof(int)) {
     516             :     qh_fprintf(qh, qh->qhmem.ferr, 6091, "qhull internal error (qh_meminit): sizeof(void *) %d < sizeof(int) %d.  qset_r.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
     517             :     qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
     518             :   }
     519             : }
     520             : 
     521             : void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
     522             : 
     523             :   qh->qhmem.IStracing= tracelevel;
     524             : }
     525             : 
     526             : void qh_memsetup(qhT *qh) {
     527             : }
     528             : 
     529             : void qh_memsize(qhT *qh, int size) {
     530             : }
     531             : 
     532             : void qh_memstatistics(qhT *qh, FILE *fp) {
     533             : 
     534             :   qh_fprintf(qh, fp, 9409, "\nmemory statistics:\n\
     535             : %7d long allocations\n\
     536             : %7d long frees\n\
     537             : %7d bytes of long memory allocated (max, except for input)\n\
     538             : %7d bytes of long memory in use (in %d pieces)\n",
     539             :            qh->qhmem.cntlong,
     540             :            qh->qhmem.freelong,
     541             :            qh->qhmem.maxlong, qh->qhmem.totlong, qh->qhmem.cntlong - qh->qhmem.freelong);
     542             : }
     543             : 
     544             : #endif /* qh_NOmem */
     545             : 
     546             : /*-<a                             href="qh-mem_r.htm#TOC"
     547             : >-------------------------------</a><a name="memtotlong">-</a>
     548             : 
     549             :   qh_memtotal(qh, totlong, curlong, totshort, curshort, maxlong, totbuffer )
     550             :     Return the total, allocated long and short memory
     551             : 
     552             :   returns:
     553             :     Returns the total current bytes of long and short allocations
     554             :     Returns the current count of long and short allocations
     555             :     Returns the maximum long memory and total short buffer (minus one link per buffer)
     556             :     Does not error (for deprecated UsingLibQhull.cpp in libqhullpcpp)
     557             : */
     558           0 : void qh_memtotal(qhT *qh, int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer) {
     559           0 :     *totlong= qh->qhmem.totlong;
     560           0 :     *curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
     561           0 :     *totshort= qh->qhmem.totshort;
     562           0 :     *curshort= qh->qhmem.cntshort + qh->qhmem.cntquick - qh->qhmem.freeshort;
     563           0 :     *maxlong= qh->qhmem.maxlong;
     564           0 :     *totbuffer= qh->qhmem.totbuffer;
     565           0 : } /* memtotlong */
     566             : 

Generated by: LCOV version 1.14