1 /*************************************************************************/
2 /* */
3 /* Language Technologies Institute */
4 /* Carnegie Mellon University */
5 /* Copyright (c) 1999 */
6 /* All Rights Reserved. */
7 /* */
8 /* Permission is hereby granted, free of charge, to use and distribute */
9 /* this software and its documentation without restriction, including */
10 /* without limitation the rights to use, copy, modify, merge, publish, */
11 /* distribute, sublicense, and/or sell copies of this work, and to */
12 /* permit persons to whom this work is furnished to do so, subject to */
13 /* the following conditions: */
14 /* 1. The code must retain the above copyright notice, this list of */
15 /* conditions and the following disclaimer. */
16 /* 2. Any modifications must be clearly marked as such. */
17 /* 3. Original authors' names are not deleted. */
18 /* 4. The authors' names are not used to endorse or promote products */
19 /* derived from this software without specific prior written */
20 /* permission. */
21 /* */
22 /* CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK */
23 /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24 /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25 /* SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE */
26 /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27 /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28 /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29 /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30 /* THIS SOFTWARE. */
31 /* */
32 /*************************************************************************/
33 /* Author: Alan W Black (awb@cs.cmu.edu) */
34 /* Date: July 1999 */
35 /*************************************************************************/
36 /* */
37 /* Basic wraparounds for malloc and free */
38 /* */
39 /*************************************************************************/
40 #include "cst_file.h"
41 #include "cst_alloc.h"
42 #include "cst_error.h"
43
44 #ifdef UNDER_CE
45 #include <windows.h>
46 #endif /* UNDER_CE */
47
48 /* define this if you want to trace memory usage */
49 /* #define CST_DEBUG_MALLOC */
50 /* #define CST_DEBUG_MALLOC_TRACE */
51 #ifdef CST_DEBUG_MALLOC
52 int cst_allocated = 0;
53 int cst_freed = 0;
54 int cst_alloc_max = 0;
55 int cst_alloc_imax = 0;
56 int cst_alloc_num_calls = 0;
57 int cst_alloc_out = 0;
58 #ifdef CST_DEBUG_MALLOC_TRACE
59 /* This is a crude memory tracer to find leaks */
60 int cst_alloc_ckpt = -1;
61 /* You have to know how big this should be to use it, its for debuging only */
62 #define NUM_CHUNKS 10000000
63 void *cst_alloc_cunks[NUM_CHUNKS];
64 #endif
65 #endif
66
cst_safe_alloc(int size)67 void *cst_safe_alloc(int size)
68 {
69 /* returns pointer to memory all set 0 */
70 void *p = NULL;
71 if (size < 0)
72 {
73 cst_errmsg("alloc: asked for negative size %d\n", size);
74 cst_error();
75 }
76 else if (size == 0) /* some mallocs return NULL for this */
77 size++;
78
79 #ifdef CST_DEBUG_MALLOC
80 if (size > cst_alloc_imax)
81 {
82 cst_alloc_imax = size;
83 }
84 cst_allocated += size;
85 cst_alloc_out += size;
86 size += 2 * sizeof(int);
87 #endif
88
89 #ifdef UNDER_CE
90 p = (void *)LocalAlloc(LPTR, size);
91 #else
92 p = (void *)calloc(size,1);
93 #endif
94
95 #ifdef CST_DEBUG_MALLOC
96 #ifdef CST_DEBUG_MALLOC_TRACE
97 if (cst_alloc_num_calls == cst_alloc_ckpt)
98 cst_dbgmsg("cst_malloc: %d\n", cst_alloc_ckpt);
99 cst_alloc_cunks[cst_alloc_num_calls] = p;
100 #endif
101 cst_alloc_num_calls++;
102 *(int *)p = 1314;
103 p = (int *)p + 1;
104 *(int *)p = size - (2 * sizeof(int));
105 if ((cst_allocated - cst_freed) > cst_alloc_max)
106 cst_alloc_max = cst_allocated - cst_freed;
107 p = (int *)p + 1;
108 #endif
109
110 if (p == NULL)
111 {
112 cst_errmsg("alloc: can't alloc %d bytes\n", size);
113 cst_error();
114 }
115
116 return p;
117 }
118
cst_safe_calloc(int size)119 void *cst_safe_calloc(int size)
120 {
121 return cst_safe_alloc(size);
122 }
123
cst_safe_realloc(void * p,int size)124 void *cst_safe_realloc(void *p,int size)
125 {
126 void *np=0;
127
128 #ifdef CST_DEBUG_MALLOC
129 cst_free(p);
130 return cst_safe_alloc(size);
131 #endif
132
133 if (size == 0)
134 size++; /* as some mallocs do strange things with 0 */
135
136 if (p == NULL)
137 np = cst_safe_alloc(size);
138 else
139 #ifdef UNDER_CE
140 np = LocalReAlloc((HLOCAL)p, size, LMEM_MOVEABLE|LMEM_ZEROINIT);
141 #else
142 np = realloc(p,size);
143 #endif
144
145 if (np == NULL)
146 {
147 cst_errmsg("CST_REALLOC failed for %d bytes\n",size);
148 cst_error();
149 }
150
151 return np;
152 }
153
cst_free(void * p)154 void cst_free(void *p)
155 {
156 if (p != NULL)
157 {
158 #ifdef CST_DEBUG_MALLOC
159 if (*((int *)p - 2) != 1314)
160 {
161 cst_dbgmsg("CST_MALLOC_DEBUG freeing non-malloc memory\n");
162 return;
163 }
164 if (*((int *)p - 1) <= 0)
165 {
166 cst_dbgmsg("CST_MALLOC_DEBUG re-freeing memory\n");
167 return;
168 }
169 cst_freed += *((int *)p - 1);
170 cst_alloc_out -= *((int *)p - 1);
171 *((int *)p - 1) = 0; /* mark it as freed */
172 p = (int *)p - 2;
173 #endif
174 #ifndef CST_DEBUG_MALLOC_TRACE
175 #ifdef UNDER_CE
176 if (LocalFree(p) != NULL)
177 {
178 cst_errmsg("LocalFree(%p) failed with code %x\n",
179 p, GetLastError());
180 cst_error();
181 }
182 #else
183 free(p);
184 #endif
185 #endif
186 }
187 }
188
189 #ifdef CST_DEBUG_MALLOC_TRACE
190
cst_find_unfreed()191 void cst_find_unfreed()
192 {
193 int i, t;
194
195
196 for (i = 0, t = 0;
197 i < NUM_CHUNKS
198 && i < cst_alloc_num_calls
199 && cst_alloc_cunks[i];
200 i++)
201 {
202 if (((int *)cst_alloc_cunks[i])[1] != 0)
203 {
204 cst_dbgmsg("unfreed at %d\n", i);
205 t++;
206 }
207 }
208 cst_dbgmsg("total unfreed %d\n", t);
209 }
210
cst_alloc_debug_summary()211 void cst_alloc_debug_summary()
212 {
213 cst_find_unfreed();
214 printf("allocated %d freed %d max %d imax %d calls %d out %d\n",
215 cst_allocated, cst_freed, cst_alloc_max,
216 cst_alloc_imax, cst_alloc_num_calls, cst_alloc_out);
217 }
218 #endif
219
220 #ifdef UNDER_CE
new_alloc_context(int size)221 cst_alloc_context new_alloc_context(int size)
222 {
223 HANDLE h;
224
225 h = HeapCreate(0, size, 0);
226 return (cst_alloc_context) h;
227 }
228
delete_alloc_context(cst_alloc_context ctx)229 void delete_alloc_context(cst_alloc_context ctx)
230 {
231 HANDLE h;
232
233 h = (HANDLE)ctx;
234 HeapDestroy(h);
235 }
236
cst_local_alloc(cst_alloc_context ctx,int size)237 void *cst_local_alloc(cst_alloc_context ctx, int size)
238 {
239 HANDLE h;
240
241 h = (HANDLE)ctx;
242 if (h)
243 return HeapAlloc(h, HEAP_ZERO_MEMORY, size);
244 else
245 return LocalAlloc(LPTR, size);
246 }
247
cst_local_free(cst_alloc_context ctx,void * p)248 void cst_local_free(cst_alloc_context ctx, void *p)
249 {
250 HANDLE h;
251
252 h = (HANDLE)ctx;
253 if (h)
254 HeapFree(h, 0, p);
255 else
256 LocalFree(p);
257 }
258 #endif
259
260
261