Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:01:53

0001 /*<html><pre>  -<a                             href="qh-mem.htm"
0002   >-------------------------------</a><a name="TOP">-</a>
0003 
0004    mem.h
0005      prototypes for memory management functions
0006 
0007    see qh-mem.htm, mem.c and qset.h
0008 
0009    for error handling, writes message and calls
0010      qh_errexit(qhmem_ERRmem, NULL, NULL) if insufficient memory
0011        and
0012      qh_errexit(qhmem_ERRqhull, NULL, NULL) otherwise
0013 
0014    Copyright (c) 1993-2020 The Geometry Center.
0015    $Id: //main/2019/qhull/src/libqhull/mem.h#2 $$Change: 2953 $
0016    $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
0017 */
0018 
0019 #ifndef qhDEFmem
0020 #define qhDEFmem 1
0021 
0022 #include <stdio.h>
0023 
0024 /*-<a                             href="qh-mem.htm#TOC"
0025   >-------------------------------</a><a name="NOmem">-</a>
0026 
0027   qh_NOmem
0028     turn off quick-fit memory allocation
0029 
0030   notes:
0031     mem.c implements Quickfit memory allocation for about 20% time
0032     savings.  If it fails on your machine, try to locate the
0033     problem, and send the answer to qhull@qhull.org.  If this can
0034     not be done, define qh_NOmem to use malloc/free instead.
0035 
0036   #define qh_NOmem
0037 */
0038 
0039 /*-<a                             href="qh-mem.htm#TOC"
0040 >-------------------------------</a><a name="TRACEshort">-</a>
0041 
0042 qh_TRACEshort
0043 Trace short and quick memory allocations at T5
0044 
0045 */
0046 #define qh_TRACEshort
0047 
0048 /*-------------------------------------------
0049     to avoid bus errors, memory allocation must consider alignment requirements.
0050     malloc() automatically takes care of alignment.   Since mem.c manages
0051     its own memory, we need to explicitly specify alignment in
0052     qh_meminitbuffers().
0053 
0054     A safe choice is sizeof(double).  sizeof(float) may be used if doubles
0055     do not occur in data structures and pointers are the same size.  Be careful
0056     of machines (e.g., DEC Alpha) with large pointers.  If gcc is available,
0057     use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)).
0058 
0059    see <a href="user.h#MEMalign">qh_MEMalign</a> in user.h for qhull's alignment
0060 */
0061 
0062 #define qhmem_ERRmem 4    /* matches qh_ERRmem in libqhull.h */
0063 #define qhmem_ERRqhull 5  /* matches qh_ERRqhull in libqhull.h */
0064 
0065 /*-<a                             href="qh-mem.htm#TOC"
0066   >--------------------------------</a><a name="ptr_intT">-</a>
0067 
0068   ptr_intT
0069     for casting a void * to an integer-type that holds a pointer
0070     Used for integer expressions (e.g., computing qh_gethash() in poly.c)
0071 
0072   notes:
0073     WARN64 -- these notes indicate 64-bit issues
0074     On 64-bit machines, a pointer may be larger than an 'int'.
0075     qh_meminit()/mem.c checks that 'ptr_intT' holds a 'void*'
0076     ptr_intT is typically a signed value, but not necessarily so
0077     size_t is typically unsigned, but should match the parameter type
0078     Qhull uses int instead of size_t except for system calls such as malloc, qsort, qh_malloc, etc.
0079     This matches Qt convention and is easier to work with.
0080 */
0081 #if (defined(__MINGW64__)) && defined(_WIN64)
0082 typedef long long ptr_intT;
0083 #elif defined(_MSC_VER) && defined(_WIN64)
0084 typedef long long ptr_intT;
0085 #else
0086 typedef long ptr_intT;
0087 #endif
0088 
0089 /*-<a                             href="qh-mem.htm#TOC"
0090   >--------------------------------</a><a name="qhmemT">-</a>
0091 
0092   qhmemT
0093     global memory structure for mem.c
0094 
0095  notes:
0096    users should ignore qhmem except for writing extensions
0097    qhmem is allocated in mem.c
0098 
0099    qhmem could be swapable like qh and qhstat, but then
0100    multiple qh's and qhmem's would need to keep in synch.
0101    A swapable qhmem would also waste memory buffers.  As long
0102    as memory operations are atomic, there is no problem with
0103    multiple qh structures being active at the same time.
0104    If you need separate address spaces, you can swap the
0105    contents of qhmem.
0106 */
0107 typedef struct qhmemT qhmemT;
0108 extern qhmemT qhmem;
0109 
0110 #ifndef DEFsetT
0111 #define DEFsetT 1
0112 typedef struct setT setT;          /* defined in qset.h */
0113 #endif
0114 
0115 /* mem.c -- Update static initializer list for qhmem if add or remove fields */
0116 struct qhmemT {               /* global memory management variables */
0117   int      BUFsize;           /* size of memory allocation buffer */
0118   int      BUFinit;           /* initial size of memory allocation buffer */
0119   int      TABLEsize;         /* actual number of sizes in free list table */
0120   int      NUMsizes;          /* maximum number of sizes in free list table */
0121   int      LASTsize;          /* last size in free list table */
0122   int      ALIGNmask;         /* worst-case alignment, must be 2^n-1 */
0123   void   **freelists;          /* free list table, linked by offset 0 */
0124   int     *sizetable;         /* size of each freelist */
0125   int     *indextable;        /* size->index table */
0126   void    *curbuffer;         /* current buffer, linked by offset 0 */
0127   void    *freemem;           /*   free memory in curbuffer */
0128   int      freesize;          /*   size of freemem in bytes */
0129   setT    *tempstack;         /* stack of temporary memory, managed by users */
0130   FILE    *ferr;              /* file for reporting errors when 'qh' may be undefined */
0131   int      IStracing;         /* =5 if tracing memory allocations */
0132   int      cntquick;          /* count of quick allocations */
0133                               /* Note: removing statistics doesn't effect speed */
0134   int      cntshort;          /* count of short allocations */
0135   int      cntlong;           /* count of long allocations */
0136   int      freeshort;         /* count of short memfrees */
0137   int      freelong;          /* count of long memfrees */
0138   int      totbuffer;         /* total short memory buffers minus buffer links */
0139   int      totdropped;        /* total dropped memory at end of short memory buffers (e.g., freesize) */
0140   int      totfree;           /* total size of free, short memory on freelists */
0141   int      totlong;           /* total size of long memory in use */
0142   int      maxlong;           /*   maximum totlong */
0143   int      totshort;          /* total size of short memory in use */
0144   int      totunused;         /* total unused short memory (estimated, short size - request size of first allocations) */
0145   int      cntlarger;         /* count of setlarger's */
0146   int      totlarger;         /* total copied by setlarger */
0147 };
0148 
0149 
0150 /*==================== -macros ====================*/
0151 
0152 /*-<a                             href="qh-mem.htm#TOC"
0153   >--------------------------------</a><a name="memalloc_">-</a>
0154 
0155   qh_memalloc_(insize, freelistp, object, type)
0156     returns object of size bytes
0157         assumes size<=qhmem.LASTsize and void **freelistp is a temp
0158 */
0159 
0160 #if defined qh_NOmem
0161 #define qh_memalloc_(insize, freelistp, object, type) {\
0162   (void)freelistp; /* Avoid warnings */ \
0163   object= (type *)qh_memalloc(insize); }
0164 #elif defined qh_TRACEshort
0165 #define qh_memalloc_(insize, freelistp, object, type) {\
0166   (void)freelistp; /* Avoid warnings */ \
0167   object= (type *)qh_memalloc(insize); }
0168 #else /* !qh_NOmem */
0169 
0170 #define qh_memalloc_(insize, freelistp, object, type) {\
0171   freelistp= qhmem.freelists + qhmem.indextable[insize];\
0172   if ((object= (type *)*freelistp)) {\
0173     qhmem.totshort += qhmem.sizetable[qhmem.indextable[insize]]; \
0174     qhmem.totfree -= qhmem.sizetable[qhmem.indextable[insize]]; \
0175     qhmem.cntquick++;  \
0176     *freelistp= *((void **)*freelistp);\
0177   }else object= (type *)qh_memalloc(insize);}
0178 #endif
0179 
0180 /*-<a                             href="qh-mem.htm#TOC"
0181   >--------------------------------</a><a name="memfree_">-</a>
0182 
0183   qh_memfree_(object, insize, freelistp)
0184     free up an object
0185 
0186   notes:
0187     object may be NULL
0188     assumes size<=qhmem.LASTsize and void **freelistp is a temp
0189 */
0190 #if defined qh_NOmem
0191 #define qh_memfree_(object, insize, freelistp) {\
0192   (void)freelistp; /* Avoid warnings */ \
0193   qh_memfree(object, insize); }
0194 #elif defined qh_TRACEshort
0195 #define qh_memfree_(object, insize, freelistp) {\
0196   (void)freelistp; /* Avoid warnings */ \
0197   qh_memfree(object, insize); }
0198 #else /* !qh_NOmem */
0199 
0200 #define qh_memfree_(object, insize, freelistp) {\
0201   if (object) { \
0202     qhmem.freeshort++;\
0203     freelistp= qhmem.freelists + qhmem.indextable[insize];\
0204     qhmem.totshort -= qhmem.sizetable[qhmem.indextable[insize]]; \
0205     qhmem.totfree += qhmem.sizetable[qhmem.indextable[insize]]; \
0206     *((void **)object)= *freelistp;\
0207     *freelistp= object;}}
0208 #endif
0209 
0210 /*=============== prototypes in alphabetical order ============*/
0211 
0212 void *qh_memalloc(int insize);
0213 void qh_memcheck(void);
0214 void qh_memfree(void *object, int insize);
0215 void qh_memfreeshort(int *curlong, int *totlong);
0216 void qh_meminit(FILE *ferr);
0217 void qh_meminitbuffers(int tracelevel, int alignment, int numsizes,
0218                         int bufsize, int bufinit);
0219 void qh_memsetup(void);
0220 void qh_memsize(int size);
0221 void qh_memstatistics(FILE *fp);
0222 void qh_memtotal(int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer);
0223 
0224 #endif /* qhDEFmem */