mem_r.h 8.9 KB

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