1
/*<html><pre> -<a href="qh-mem.htm"
2
>-------------------------------</a><a name="TOP">-</a>
5
prototypes for memory management functions
7
see qh-mem.htm, mem.c and qset.h
9
for error handling, writes message and calls
10
qh_errexit (qhmem_ERRmem, NULL, NULL) if insufficient memory
12
qh_errexit (qhmem_ERRqhull, NULL, NULL) otherwise
14
copyright (c) 1993-2002, The Geometry Center
20
/*-<a href="qh-mem.htm#TOC"
21
>-------------------------------</a><a name="NOmem">-</a>
24
turn off quick-fit memory allocation
27
mem.c implements Quickfit memory allocation for about 20% time
28
savings. If it fails on your machine, try to locate the
29
problem, and send the answer to qhull@geom.umn.edu. If this can
30
not be done, define qh_NOmem to use malloc/free instead.
35
/*-------------------------------------------
36
to avoid bus errors, memory allocation must consider alignment requirements.
37
malloc() automatically takes care of alignment. Since mem.c manages
38
its own memory, we need to explicitly specify alignment in
41
A safe choice is sizeof(double). sizeof(float) may be used if doubles
42
do not occur in data structures and pointers are the same size. Be careful
43
of machines (e.g., DEC Alpha) with large pointers. If gcc is available,
44
use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)).
46
see <a href="user.h#MEMalign">qh_MEMalign</a> in user.h for qhull's alignment
49
#define qhmem_ERRmem 4 /* matches qh_ERRmem in qhull.h */
50
#define qhmem_ERRqhull 5 /* matches qh_ERRqhull in qhull.h */
52
/*-<a href="qh-mem.htm#TOC"
53
>--------------------------------</a><a name="ptr_intT">-</a>
56
for casting a void* to an integer-type
59
On 64-bit machines, a pointer may be larger than an 'int'.
60
qh_meminit() checks that 'long' holds a 'void*'
62
typedef unsigned long ptr_intT;
64
/*-<a href="qh-mem.htm#TOC"
65
>--------------------------------</a><a name="qhmemT">-</a>
68
global memory structure for mem.c
71
users should ignore qhmem except for writing extensions
72
qhmem is allocated in mem.c
74
qhmem could be swapable like qh and qhstat, but then
75
multiple qh's and qhmem's would need to keep in synch.
76
A swapable qhmem would also waste memory buffers. As long
77
as memory operations are atomic, there is no problem with
78
multiple qh structures being active at the same time.
79
If you need separate address spaces, you can swap the
82
typedef struct qhmemT qhmemT;
85
struct qhmemT { /* global memory management variables */
86
int BUFsize; /* size of memory allocation buffer */
87
int BUFinit; /* initial size of memory allocation buffer */
88
int TABLEsize; /* actual number of sizes in free list table */
89
int NUMsizes; /* maximum number of sizes in free list table */
90
int LASTsize; /* last size in free list table */
91
int ALIGNmask; /* worst-case alignment, must be 2^n-1 */
92
void **freelists; /* free list table, linked by offset 0 */
93
int *sizetable; /* size of each freelist */
94
int *indextable; /* size->index table */
95
void *curbuffer; /* current buffer, linked by offset 0 */
96
void *freemem; /* free memory in curbuffer */
97
int freesize; /* size of free memory in bytes */
98
void *tempstack; /* stack of temporary memory, managed by users */
99
FILE *ferr; /* file for reporting errors */
100
int IStracing; /* =5 if tracing memory allocations */
101
int cntquick; /* count of quick allocations */
102
/* remove statistics doesn't effect speed */
103
int cntshort; /* count of short allocations */
104
int cntlong; /* count of long allocations */
105
int curlong; /* current count of inuse, long allocations */
106
int freeshort; /* count of short memfrees */
107
int freelong; /* count of long memfrees */
108
int totshort; /* total size of short allocations */
109
int totlong; /* total size of long allocations */
110
int maxlong; /* maximum totlong */
111
int cntlarger; /* count of setlarger's */
112
int totlarger; /* total copied by setlarger */
116
/*==================== -macros ====================*/
118
/*-<a href="qh-mem.htm#TOC"
119
>--------------------------------</a><a name="memalloc_">-</a>
121
qh_memalloc_(size, object, type)
122
returns object of size bytes
123
assumes size<=qhmem.LASTsize and void **freelistp is a temp
127
#define qh_memalloc_(size, freelistp, object, type) {\
128
object= (type*)qh_memalloc (size); }
129
#else /* !qh_NOmem */
131
#define qh_memalloc_(size, freelistp, object, type) {\
132
freelistp= qhmem.freelists + qhmem.indextable[size];\
133
if ((object= (type*)*freelistp)) {\
135
*freelistp= *((void **)*freelistp);\
136
}else object= (type*)qh_memalloc (size);}
139
/*-<a href="qh-mem.htm#TOC"
140
>--------------------------------</a><a name="memfree_">-</a>
142
qh_memfree_(object, size)
147
assumes size<=qhmem.LASTsize and void **freelistp is a temp
150
#define qh_memfree_(object, size, freelistp) {\
151
qh_memfree (object, size); }
152
#else /* !qh_NOmem */
154
#define qh_memfree_(object, size, freelistp) {\
157
freelistp= qhmem.freelists + qhmem.indextable[size];\
158
*((void **)object)= *freelistp;\
159
*freelistp= object;}}
162
/*=============== prototypes in alphabetical order ============*/
164
void *qh_memalloc(int insize);
165
void qh_memfree (void *object, int size);
166
void qh_memfreeshort (int *curlong, int *totlong);
167
void qh_meminit (FILE *ferr);
168
void qh_meminitbuffers (int tracelevel, int alignment, int numsizes,
169
int bufsize, int bufinit);
170
void qh_memsetup (void);
171
void qh_memsize(int size);
172
void qh_memstatistics (FILE *fp);
174
#endif /* qhDEFmem */