1 |
/* ASCEND modelling environment |
2 |
Copyright (C) 2006 Carnegie Mellon University |
3 |
|
4 |
This program is free software; you can redistribute it and/or modify |
5 |
it under the terms of the GNU General Public License as published by |
6 |
the Free Software Foundation; either version 2, or (at your option) |
7 |
any later version. |
8 |
|
9 |
This program is distributed in the hope that it will be useful, |
10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 |
GNU General Public License for more details. |
13 |
|
14 |
You should have received a copy of the GNU General Public License |
15 |
along with this program; if not, write to the Free Software |
16 |
Foundation, Inc., 59 Temple Place - Suite 330, |
17 |
Boston, MA 02111-1307, USA. |
18 |
*//** @file |
19 |
ASCEND memory allocation & reporting routines. |
20 |
|
21 |
@TODO |
22 |
An attempt is being made here to remove some of the complexity here |
23 |
and migrate to the external tool 'dmalloc' (http://dmalloc.com/) |
24 |
|
25 |
These functions provide tracking of memory events and assist |
26 |
finding and debugging memory errors. Memory tracking options are |
27 |
selected using the macros MALLOC_DEBUG and ALLOCATED_TESTS discussed |
28 |
below. This allows the enhanced functionality to be used or turned |
29 |
off as desired. This functionality adds considerable run-time overhead, |
30 |
and so should generally be used for debugging purposes only. There are |
31 |
also routines for reporting on the status of memory blocks as well as |
32 |
for the memory manager itself.<br><br> |
33 |
|
34 |
To use the memory tracking features, you need to use the provided |
35 |
allocation and deallocation functions (ascmalloc(), asccalloc(), |
36 |
ascrealloc(), ascfree()). Direct calls to the corresponding system |
37 |
routines will by-pass the memory manager and not be tracked. Memory |
38 |
allocations which return NULL are not tracked or recorded.<br><br> |
39 |
|
40 |
This module also standardizes critical implementation-specific features |
41 |
such as behavior when an allocation of zero bytes is requested |
42 |
(see MOD_ASCMALLOC), and the behavior of realloc() under purify |
43 |
(see MOD_REALLOC).<br><br> |
44 |
|
45 |
The following macros affect the compilation and run-time behavior |
46 |
of Ascend memory management. |
47 |
|
48 |
<pre> |
49 |
MOD_ASCMALLOC Forces the memory allocation functions to always |
50 |
allocate at least 1 byte and return a non-NULL |
51 |
pointer. This macro should be defined if your |
52 |
allocator returns NULL when a zero-sized block is |
53 |
requested (e.g. alpha or rs6000; Borland and Watcom |
54 |
on Windows). It need not be defined if your |
55 |
allocator returns a non-NULL pointer to a zero-length |
56 |
block, saving you a few bytes of memory. |
57 |
|
58 |
MALLOC_DEBUG Causes all calls to memory allocation routines |
59 |
to be tracked and logged to an output file. |
60 |
This really slows down the memory management |
61 |
system, and so should be used for debugging only. |
62 |
|
63 |
ALLOCATED_TESTS Forces a lot of extra assertions when defined |
64 |
along with MALLOC_DEBUG. |
65 |
|
66 |
MOD_REALLOC If defined, ascreallocPURE() uses a homegrown |
67 |
realloc() that behaves properly with purify. |
68 |
This is more expensive, and should be used |
69 |
for debugging only. |
70 |
|
71 |
Requires: |
72 |
#include "utilities/ascConfig.h" |
73 |
#include "utilities/ascPanic.h" |
74 |
</pre> |
75 |
*//* |
76 |
by Tom Epperly |
77 |
Created: 2/6/90 |
78 |
Last in CVS: $Revision: 1.2 $ $Date: 1997/07/18 11:44:50 $ $Author: mthomas $ |
79 |
*/ |
80 |
|
81 |
#ifndef ASC_ASCMALLOC_H |
82 |
#define ASC_ASCMALLOC_H |
83 |
|
84 |
/* MALLOC_DEBUG and ASC_WITH_DMALLOC will be defined in config.h... */ |
85 |
#include <utilities/config.h> |
86 |
#include <utilities/ascConfig.h> |
87 |
|
88 |
/*------------------------------------------------------------------------------ |
89 |
C++-ish ASC_NEW* macros |
90 |
*/ |
91 |
/** |
92 |
Shorthand for creating pointers to newly allocated data of a given type |
93 |
*/ |
94 |
#define ASC_NEW(TYPE) (TYPE*)ascmalloc(sizeof(TYPE)) |
95 |
#define ASC_NEW_CLEAR(TYPE) (TYPE*)asccalloc(1,sizeof(TYPE)) |
96 |
|
97 |
/** |
98 |
Shorthand for creating pointer to an array of newly allocated data of a |
99 |
given type. 'ascmalloc' is used for the allocation. |
100 |
*/ |
101 |
#define ASC_NEW_ARRAY(TYPE,COUNT) (TYPE*)ascmalloc(sizeof(TYPE)*(COUNT)) |
102 |
|
103 |
/** |
104 |
Shorthand for creating a pointer to allocated data, using asccalloc (to zero |
105 |
the allocated space). |
106 |
*/ |
107 |
#define ASC_NEW_ARRAY_CLEAR(TYPE,COUNT) (TYPE*)asccalloc((COUNT),sizeof(TYPE)) |
108 |
|
109 |
/** |
110 |
Shorthand for creating a pointer to an array of allocated data. If the |
111 |
specified length is zero, no space is allocated, and a NULL is returned |
112 |
instead. |
113 |
*/ |
114 |
#define ASC_NEW_ARRAY_OR_NULL(TYPE,COUNT) \ |
115 |
((COUNT)>0 ? ASC_NEW_ARRAY(TYPE,COUNT) : NULL) |
116 |
|
117 |
#define ASC_NEW_ARRAY_OR_NULL_CLEAR(TYPE,COUNT) \ |
118 |
((COUNT)>0 ? ASC_NEW_ARRAY_CLEAR(TYPE,COUNT) : NULL) |
119 |
|
120 |
/* regular expressions for fixing up mallocs (in regexxer) |
121 |
\(([^\*\)]+) ?\*\)\s*ascmalloc\(sizeof\(\1\)\s*\*\s*([a-zA-Z][a-zA-Z_0-9]*)\) |
122 |
\(([^\*\)]+) ?\*\)\s*asccalloc\(([a-zA-Z][a-zA-Z_0-9]*)\s*,\s*sizeof\(\1\)\s*\) |
123 |
*/ |
124 |
|
125 |
#define ASC_FREE(PTR) ascfree(PTR) |
126 |
|
127 |
#define ASC_REALLOC(PTR,SIZE) ascrealloc(PTR,SIZE) |
128 |
|
129 |
#define ASC_STRDUP(STR) ascstrdup(STR) |
130 |
|
131 |
ASC_DLLSPEC char *ascstrdupf(CONST char *str); |
132 |
/**< |
133 |
* Implementation function for ascstrdup() if MALLOC_DEBUG |
134 |
* is not defined. Do not call this function directly - use |
135 |
* ascstrdup() instead. |
136 |
*/ |
137 |
|
138 |
/*------------------------------------------------------------------------------ |
139 |
MACROS FOR THE CASE WHERE 'DMALLOC' IS AVAILABLE |
140 |
*/ |
141 |
|
142 |
#ifdef ASC_WITH_DMALLOC |
143 |
|
144 |
#include <stdlib.h> |
145 |
#include <dmalloc.h> |
146 |
|
147 |
#define ascstrdup(str) ascstrdupf(str) |
148 |
#define ascmalloc(SIZE) malloc(SIZE) |
149 |
#define asccalloc(COUNT,SIZE) calloc((COUNT),(SIZE)) |
150 |
#define ascfree(ADDR) free(ADDR) |
151 |
#define asc_memcpy(DEST,SRC,SIZE) memcpy((DEST),(SRC),(SIZE)) |
152 |
#define ascstatus(MSG) /* empty */ |
153 |
#define ascstatus_detail(msg) /* empty */ |
154 |
#define ascmeminuse() (0) |
155 |
#define ascshutdown(ARG) /* empty */ |
156 |
#define ascrealloc(PTR,SIZE) realloc((PTR),(SIZE)) |
157 |
#define ascreallocPURE(PTR,OLD,NEWP) ascrealloc((PTR),(NEWP)) |
158 |
#define ascbcopy(SRC,DEST,SIZE) memcpy((void *)(DEST), (void *)(SRC), (SIZE)) |
159 |
#define ascbzero(DEST,LENGTH) memset((char *)(DEST), 0, (LENGTH)) |
160 |
#define ascbfill(DEST,LENGTH) memset((char *)(DEST), 255, (LENGTH)) |
161 |
|
162 |
/* some assertions, all ignored in this case */ |
163 |
#define AllocatedMemory(ptr,size) (1) |
164 |
#define InMemoryBlock(ptr1,ptr2) (1) |
165 |
#define AssertAllocatedMemory(ptr,size) |
166 |
#define AssertMemory(ptr) |
167 |
#define AssertContainedMemory(ptr,size) |
168 |
#define AssertContainedIn(ptr,ptr2) |
169 |
|
170 |
/*------------------------------------------------------------------------------ |
171 |
ORIGINAL ASCEND 'MALLOC' IMPLEMENTATION |
172 |
*/ |
173 |
#else /* ASC_WITH_DMALLOC */ |
174 |
|
175 |
#ifdef MALLOC_DEBUG |
176 |
# define ascstrdup(str) ascstrdupf_dbg(str) |
177 |
#else |
178 |
# define ascstrdup(str) ascstrdupf(str) |
179 |
#endif |
180 |
/**< |
181 |
* Returns a new copy of string str. |
182 |
* This is the ASCEND rendition of strdup(). The caller is |
183 |
* responsible for deallocating the new string when finished |
184 |
* using ascfree(). Returns NULL if str is NULL or memory |
185 |
* cannot be allocated for the new copy. If MALLOC_DEBUG is |
186 |
* defined, the allocation is tracked. |
187 |
* |
188 |
* @param str The 0-terminated string to copy. |
189 |
* @return A new copy of str as a char *, or NULL if an error occurs. |
190 |
*/ |
191 |
|
192 |
ASC_DLLSPEC char *ascstrdupf_dbg(CONST char *str); |
193 |
/**< |
194 |
* Implementation function for ascstrdup() if MALLOC_DEBUG |
195 |
* is defined. Do not call this function directly - define |
196 |
* MALLOC_DEBUG and use ascstrdup() instead. |
197 |
*/ |
198 |
|
199 |
ASC_DLLSPEC char *asc_memcpy(char *dest, char *src, size_t n); |
200 |
/**< |
201 |
* Copies n bytes from memory address src to dest. |
202 |
* This version of memcpy handles overlapping memory ranges |
203 |
* properly. It could be more efficient internally. As it is, |
204 |
* it moves data a char at a time. Unless n is 0, neither dest |
205 |
* nor src may be NULL (checked by asc_assertion). |
206 |
* |
207 |
* @param dest Pointer to address to which to copy (non-NULL). |
208 |
* @param src Pointer to address from which to copy (non-NULL). |
209 |
* @param n Number of bytes to copy. |
210 |
* @return Returns dest. |
211 |
*/ |
212 |
|
213 |
#ifndef MOD_REALLOC |
214 |
# define ascreallocPURE(ptr,nold,nnew) ascrealloc((ptr),(nnew)) |
215 |
#else |
216 |
# ifdef MALLOC_DEBUG |
217 |
# define ascreallocPURE(ptr,nold,nnew) ascreallocPUREF_dbg((ptr),(nold),(nnew)) |
218 |
# else |
219 |
# define ascreallocPURE(ptr,nold,nnew) ascreallocPUREF((ptr),(nold),(nnew)) |
220 |
# endif |
221 |
#endif |
222 |
/**< |
223 |
* purify realloc() function for debugging purposes. |
224 |
* In some OS, realloc() fools purify into thinking there |
225 |
* is a memory leak. If MOD_REALLOC is defined at compile |
226 |
* time for all software referencing this header, then all |
227 |
* calls to ascreallocPURE() will use a homegrown realloc |
228 |
* that does not fool purify. Leaks of memory reported |
229 |
* around realloc() when MOD_REALLOC is defined should be |
230 |
* real leaks and not OS noise.<br><br> |
231 |
* |
232 |
* The custom function is somewhat more expensive than most |
233 |
* system-supplied realloc()'s, so should only be used for |
234 |
* debugging. Note that ascreallocPURE() will provide memory |
235 |
* event tracking if MALLOC_DEBUG is also defined when this |
236 |
* header is included. |
237 |
* |
238 |
* @see ascreallocPUREF() |
239 |
* @param ptr Pointer to the memory block to reallocate. |
240 |
* @param nold Old block size in bytes. |
241 |
* @param nnew New block size in bytes. |
242 |
* @return A pointer to the new memory block, or NULL if an error occurred. |
243 |
*/ |
244 |
|
245 |
extern char *ascreallocPUREF(char *ptr, size_t oldbytes, size_t newbytes); |
246 |
/**< |
247 |
* Implementation function for release version of ascreallocPURE(). |
248 |
* Do not call this function directly - use ascreallocPURE() |
249 |
* (by #defining MOD_REALLOC) instead. This version does not have |
250 |
* its memory tracked. This is a custom realloc() which behaves |
251 |
* properly with purify. It bypasses the standard realloc() function. |
252 |
* The caller must indicate the old size of the memory region. |
253 |
* |
254 |
* @param ptr Pointer to the memory block to reallocate. |
255 |
* @param oldbytes Old block size in bytes. |
256 |
* @param newbytes New block size in bytes. |
257 |
* @return A pointer to the new memory block, or NULL if an error occurred. |
258 |
*/ |
259 |
|
260 |
extern char *ascreallocPUREF_dbg(char *ptr, size_t oldbytes, size_t newbytes); |
261 |
/**< |
262 |
* Implementation function for debug version of ascreallocPURE(). |
263 |
* Do not call this function directly - use ascreallocPURE() |
264 |
* (by #defining MOD_REALLOC and MALLOC_DEBUG) instead. This version |
265 |
* has it's allocations tracked by the memory manager. This is |
266 |
* a custom realloc() which behaves properly with purify. It |
267 |
* bypasses the standard realloc() function. The caller must indicate |
268 |
* the old size of the memory region. |
269 |
* |
270 |
* @param ptr Pointer to the memory block to reallocate. |
271 |
* @param oldbytes Old block size in bytes. |
272 |
* @param newbytes New block size in bytes. |
273 |
* @return A pointer to the new memory block, or NULL if an error occurred. |
274 |
*/ |
275 |
|
276 |
#ifdef MALLOC_DEBUG |
277 |
# define ascstatus(msg) ascstatusf(msg) |
278 |
#else |
279 |
# define ascstatus(msg) |
280 |
#endif |
281 |
/**< |
282 |
* Prints a summary of the memory manager status (iff MALLOC_DEBUG |
283 |
* is defined) The msg is first printed, followed by a newline and |
284 |
* then the summary memory report. These are printed both to the |
285 |
* memory log file, as well as to the screen. If MALLOC_DEBUG is |
286 |
* not defined, then nothing is printed. |
287 |
* |
288 |
* @see ascstatus_detail(), ascshutdown() |
289 |
* @param msg The message to print before the summary report. |
290 |
*/ |
291 |
|
292 |
extern void ascstatusf(CONST char *msg); |
293 |
/**< |
294 |
* Implementation function for ascstatus() if MALLOC_DEBUG |
295 |
* is defined. Do not call this function directly - define |
296 |
* MALLOC_DEBUG and use ascstatus() instead. |
297 |
*/ |
298 |
|
299 |
#ifdef MALLOC_DEBUG |
300 |
# define ascstatus_detail(msg) ascstatus_detailf(msg) |
301 |
#else |
302 |
# define ascstatus_detail(msg) |
303 |
#endif |
304 |
/**< |
305 |
* Prints a more detailed report of the memory manager status (iff |
306 |
* MALLOC_DEBUG is defined) The msg is first printed, followed by |
307 |
* a newline and then the memory report. This report includes both |
308 |
* the summary information printed by ascstatus(), as well as a listing |
309 |
* of memory blocks currently allocated. These are printed both to the |
310 |
* memory log file, as well as to the screen. If MALLOC_DEBUG is |
311 |
* not defined, then nothing is printed. |
312 |
* |
313 |
* @see ascstatus(), ascshutdown() |
314 |
* @param msg The message to print before the detail report. |
315 |
*/ |
316 |
|
317 |
extern void ascstatus_detailf(CONST char *msg); |
318 |
/**< |
319 |
* Implementation function for ascstatus_detail() if MALLOC_DEBUG |
320 |
* is defined. Do not call this function directly - define |
321 |
* MALLOC_DEBUG and use ascstatus_detail() instead. |
322 |
*/ |
323 |
|
324 |
#ifdef MALLOC_DEBUG |
325 |
# define ascshutdown(msg) ascshutdownf(msg) |
326 |
#else |
327 |
# define ascshutdown(msg) |
328 |
#endif |
329 |
/**< |
330 |
* Prints a detailed report of the memory manager status and cleans |
331 |
* up after memory logging (iff MALLOC_DEBUG is defined). The |
332 |
* reporting is the same as ascstatus_detail(). After this function |
333 |
* is called, subsequent allocation/deallocation activity will be |
334 |
* logged in a different log file than previously. If MALLOC_DEBUG |
335 |
* is not defined, then this function does nothing. |
336 |
* |
337 |
* @see ascstatus(), ascstatus_detail() |
338 |
* @param msg The message to print before the detail report. |
339 |
*/ |
340 |
|
341 |
ASC_DLLSPEC void ascshutdownf(CONST char *msg); |
342 |
/**< |
343 |
* Implementation function for ascshutdown() if MALLOC_DEBUG |
344 |
* is defined. Do not call this function directly - define |
345 |
* MALLOC_DEBUG and use ascshutdown() instead. |
346 |
*/ |
347 |
|
348 |
#ifdef MALLOC_DEBUG |
349 |
# define ascmeminuse() ascmeminusef() |
350 |
#else |
351 |
# define ascmeminuse() (0) |
352 |
#endif |
353 |
|
354 |
ASC_DLLSPEC unsigned long ascmeminusef(void); |
355 |
/**< |
356 |
* Returns the current total amount of allocated memory (iff |
357 |
* MALLOC_DEBUG is #defined). If MALLOC_DEBUG is not #defined, |
358 |
* the return value is 0 regardless of the actual amount of |
359 |
* allocated memory. |
360 |
*/ |
361 |
|
362 |
#ifdef MOD_ASCMALLOC |
363 |
# define AT_LEAST_1(x) MAX((x),1) |
364 |
#else |
365 |
# define AT_LEAST_1(x) (x) |
366 |
#endif |
367 |
/**< |
368 |
* Macro to ensure at least 1 byte is requested when MOD_ASCMALLOC |
369 |
* is defined. Requires a define for MAX(), which is located in |
370 |
* utilities/ascConfig.h. |
371 |
*/ |
372 |
|
373 |
#ifdef MALLOC_DEBUG |
374 |
# define asccalloc(nelem, size) \ |
375 |
asccallocf(AT_LEAST_1(nelem), (size), __FILE__, __LINE__) |
376 |
#else |
377 |
# define asccalloc(nelem,size) calloc(AT_LEAST_1(nelem),(size)) |
378 |
#endif |
379 |
/**< |
380 |
* ASCEND calloc() function. |
381 |
* If MALLOC_DEBUG is defined, the allocation is tracked. |
382 |
* If not, then the standard system calloc() is used. |
383 |
* |
384 |
* @see asccallocf() |
385 |
* @param nelem size_t, number of elements to allocate. |
386 |
* @param size size_t, size of each element. |
387 |
* @return A (void *) to the newly-allocated block, or NULL on error. |
388 |
*/ |
389 |
|
390 |
ASC_DLLSPEC VOIDPTR asccallocf(size_t nelem, size_t elsize, |
391 |
CONST char *file, int line); |
392 |
/**< |
393 |
* Implementation function for asccalloc() when MALLOC_DEBUG |
394 |
* is defined. Do not call this function directly - use |
395 |
* asccalloc() instead. |
396 |
*/ |
397 |
|
398 |
#ifdef MALLOC_DEBUG |
399 |
# define ascmalloc(size) \ |
400 |
ascmallocf(AT_LEAST_1(size), __FILE__, __LINE__) |
401 |
#else |
402 |
# define ascmalloc(size) malloc(AT_LEAST_1(size)) |
403 |
#endif |
404 |
/**< |
405 |
* ASCEND malloc() function. |
406 |
* If MALLOC_DEBUG is defined, the allocation is tracked. |
407 |
* If not, then the standard system malloc() is used. |
408 |
* |
409 |
* @see ascmallocf() |
410 |
* @param size size_t, size of each element. |
411 |
* @return A (void *) to the newly-allocated block, or NULL on error. |
412 |
*/ |
413 |
|
414 |
ASC_DLLSPEC VOIDPTR ascmallocf(size_t size, CONST char * file, int line); |
415 |
/**< |
416 |
* Implementation function for ascmalloc() when MALLOC_DEBUG |
417 |
* is defined. Do not call this function directly - define |
418 |
* MALLOC_DEBUG and use ascmalloc() instead. |
419 |
*/ |
420 |
|
421 |
#ifdef MALLOC_DEBUG |
422 |
# define ascrealloc(ptr, size) \ |
423 |
ascreallocf((ptr), AT_LEAST_1(size), __FILE__, __LINE__) |
424 |
#else |
425 |
# if (defined(sun) && !defined(__SVR4)) |
426 |
# define ascrealloc(ptr,size) \ |
427 |
((ptr)!=NULL ? realloc((ptr), AT_LEAST_1(size)) : malloc(AT_LEAST_1(size))) |
428 |
# else |
429 |
# define ascrealloc(ptr,size) realloc((ptr), AT_LEAST_1(size)) |
430 |
# endif |
431 |
#endif |
432 |
/**< |
433 |
* ASCEND realloc() function. |
434 |
* If MALLOC_DEBUG is defined, the allocation is tracked. |
435 |
* If not, then the standard system realloc() is used. |
436 |
* |
437 |
* @see ascreallocf(), ascreallocPURE() |
438 |
* @param ptr Pointer to memory block to reallocate. |
439 |
* @param size size_t, size of each element. |
440 |
* @return A (void *) to the newly-allocated block, or NULL on error. |
441 |
*/ |
442 |
|
443 |
ASC_DLLSPEC VOIDPTR ascreallocf(VOIDPTR ptr, size_t size, |
444 |
CONST char *file, int line); |
445 |
/**< |
446 |
* Implementation function for ascrealloc() when MALLOC_DEBUG |
447 |
* is defined. Do not call this function directly - define |
448 |
* MALLOC_DEBUG and use ascrealloc() instead. |
449 |
*/ |
450 |
|
451 |
#ifdef MALLOC_DEBUG |
452 |
# define ascfree(ptr) ascfreef((ptr), __FILE__, __LINE__) |
453 |
#else |
454 |
# define ascfree(ptr) free(ptr) |
455 |
#endif |
456 |
/**< |
457 |
* ASCEND free() function. |
458 |
* If MALLOC_DEBUG is defined, the deallocation is tracked. |
459 |
* If not, then the standard system free() is used. |
460 |
* |
461 |
* @see ascfreef() |
462 |
* @param ptr Pointer to the memory block to free. |
463 |
*/ |
464 |
|
465 |
ASC_DLLSPEC void ascfreef(VOIDPTR ptr, CONST char *file, int line); |
466 |
/**< |
467 |
* Implementation function for ascfree() when MALLOC_DEBUG |
468 |
* is defined. Do not call this function directly - define |
469 |
* MALLOC_DEBUG and use ascfree() instead. |
470 |
*/ |
471 |
|
472 |
#ifdef MALLOC_DEBUG |
473 |
# define ascbcopy(src,dest,size) \ |
474 |
ascbcopyf((src), (dest), (size), __FILE__, __LINE__) |
475 |
#else |
476 |
# define ascbcopy(src,dest,size) \ |
477 |
memcpy((void *)(dest), (void *)(src), (size)) |
478 |
#endif |
479 |
/**< |
480 |
* ASCEND bcopy() function. |
481 |
* Copies size bytes from src to dest. If MALLOC_DEBUG is |
482 |
* defined, this uses custom function ascbcopyf(). If not, |
483 |
* then memcpy() is used. |
484 |
* |
485 |
* @see asc_memcpy(), ascbcopyf(), ascbzero(), ascbfill() |
486 |
* @param src Pointer to memory block to copy. |
487 |
* @param dest Pointer to memory block to receive copy. |
488 |
* @param size size_t, number of bytes to copy. |
489 |
* @return A (void *) to dest. |
490 |
*/ |
491 |
|
492 |
ASC_DLLSPEC VOIDPTR ascbcopyf(CONST VOIDPTR src, VOIDPTR dest, size_t size, |
493 |
CONST char *file, int line); |
494 |
/**< |
495 |
* Implementation function for ascbcopy() when MALLOC_DEBUG |
496 |
* is defined. Do not call this function directly - define |
497 |
* MALLOC_DEBUG and use ascbcopy() instead. |
498 |
*/ |
499 |
|
500 |
#ifdef MALLOC_DEBUG |
501 |
# define ascbzero(dest,length) \ |
502 |
ascbzerof((dest), (length), __FILE__, __LINE__) |
503 |
#else |
504 |
# define ascbzero(dest,length) memset((char *)(dest), 0, (length)) |
505 |
#endif |
506 |
/**< |
507 |
* ASCEND bzero() function. |
508 |
* Sets length bytes of memory at dest to zero. If MALLOC_DEBUG |
509 |
* is defined, this uses custom function ascbzerof(). If not, |
510 |
* then memset() is used. |
511 |
* |
512 |
* @see ascbzerof(), ascbcopy(), ascbfill() |
513 |
* @param dest Pointer to memory block to be cleared. |
514 |
* @param length size_t, number of bytes to set to zero. |
515 |
* @return A (void *) to dest. |
516 |
*/ |
517 |
|
518 |
ASC_DLLSPEC VOIDPTR ascbzerof(VOIDPTR dest, size_t length, CONST char *file, int line); |
519 |
/**< |
520 |
* Implementation function for ascbzero() when MALLOC_DEBUG |
521 |
* is defined. Do not call this function directly - define |
522 |
* MALLOC_DEBUG and use ascbzero() instead. |
523 |
*/ |
524 |
|
525 |
#ifdef MALLOC_DEBUG |
526 |
# define AllocatedMemory(ptr,size) AllocatedMemoryF((ptr), (size)) |
527 |
#else |
528 |
# define AllocatedMemory(ptr,size) (1) |
529 |
#endif |
530 |
/**< |
531 |
* Evaluate a memory block for allocation status. |
532 |
* Return values if MALLOC is defined: |
533 |
* - 0 no memory in the block is currently allocated |
534 |
* - 1 the memory block is wholly contained in an allocated block |
535 |
* - 2 the memory block equals an element of the memory list |
536 |
* - -1 the memory block is partially contained in an allocated block |
537 |
* If MALLOC_DEBUG is not defined, always returns 1. |
538 |
* |
539 |
* @param ptr Pointer to memory block to look up |
540 |
* @param size size_t, size of the memory block to look up. |
541 |
*/ |
542 |
|
543 |
ASC_DLLSPEC int AllocatedMemoryF(CONST VOIDPTR ptr, size_t size); |
544 |
/**< |
545 |
* Implementation function for AllocatedMemory() when |
546 |
* MALLOC_DEBUG is defined. Do not call this function |
547 |
* directly - define MALLOC_DEBUG and use |
548 |
* AllocatedMemory() instead. |
549 |
*/ |
550 |
|
551 |
#ifdef MALLOC_DEBUG |
552 |
# define InMemoryBlock(ptr1,ptr2) InMemoryBlockF((ptr1), (ptr2)) |
553 |
#else |
554 |
#define InMemoryBlock(ptr1,ptr2) (1) |
555 |
#endif |
556 |
/**< |
557 |
* Query whether one memory block is contained within another. |
558 |
* Returns non-zero if ptr2 is in the memory block starting at |
559 |
* address ptr1; otherwise returns 0. If MALLOC_DEBUG is not |
560 |
* defined, always returns 1. |
561 |
*/ |
562 |
|
563 |
ASC_DLLSPEC int InMemoryBlockF(CONST VOIDPTR ptr1, CONST VOIDPTR ptr2); |
564 |
/**< |
565 |
* Implementation function for InMemoryBlock() when MALLOC_DEBUG |
566 |
* is defined. Do not call this function directly - define |
567 |
* MALLOC_DEBUG and use InMemoryBlock() instead. |
568 |
*/ |
569 |
|
570 |
#define ascbfill(dest,length) memset((char *)(dest), 255, (length)) |
571 |
/**< |
572 |
* Sets length bytes of memory at dest to 255. There is |
573 |
* no difference in implementation whether MALLOC_DEBUG is |
574 |
* defined or not. |
575 |
* |
576 |
* @see ascbcopy(), ascbzero() |
577 |
* @param dest Pointer to memory block to be set. |
578 |
* @param length size_t, number of bytes to set to 255. |
579 |
* @return A (void *) to dest. |
580 |
*/ |
581 |
|
582 |
#if defined(MALLOC_DEBUG) && defined(ALLOCATED_TESTS) |
583 |
# define AssertAllocatedMemory(ptr,size) \ |
584 |
asc_assert(AllocatedMemoryF((VOIDPTR)(ptr), (size_t)(AT_LEAST_1(size)))==2) |
585 |
#else |
586 |
# define AssertAllocatedMemory(ptr,size) |
587 |
#endif |
588 |
/**< |
589 |
* Assertion that a memory block is allocated with specified size. |
590 |
* This assertion is only active if both MALLOC_DEBUG |
591 |
* and ALLOCATED_TESTS are defined. |
592 |
* |
593 |
* @param ptr Pointer to memory block to evaluate. |
594 |
* @param size size_t, size of memory block to evaluate. |
595 |
*/ |
596 |
|
597 |
#if defined(MALLOC_DEBUG) && defined(ALLOCATED_TESTS) |
598 |
# define AssertMemory(ptr) \ |
599 |
asc_assert(AllocatedMemoryF((VOIDPTR)(ptr), 0)) |
600 |
#else |
601 |
# define AssertMemory(ptr) |
602 |
#endif |
603 |
/**< |
604 |
* Assertion that ptr points to (or into) an allocated memory |
605 |
* block. This assertion is only active if both MALLOC_DEBUG |
606 |
* and ALLOCATED_TESTS are defined. |
607 |
* |
608 |
* @param ptr Pointer to memory block to evaluate. |
609 |
*/ |
610 |
|
611 |
#if defined(MALLOC_DEBUG) && defined(ALLOCATED_TESTS) |
612 |
# define AssertContainedMemory(ptr,size) \ |
613 |
asc_assert(AllocatedMemoryF((VOIDPTR)(ptr),(size_t)(size))>0) |
614 |
#else |
615 |
# define AssertContainedMemory(ptr,size) |
616 |
#endif |
617 |
/**< |
618 |
* Assertion that a memory block is wholly or partially |
619 |
* contained in an allocated block. |
620 |
* This assertion is only active if both MALLOC_DEBUG |
621 |
* and ALLOCATED_TESTS are defined. |
622 |
* |
623 |
* @param ptr Pointer to memory block to evaluate. |
624 |
* @param size size_t, size of memory block to evaluate. |
625 |
*/ |
626 |
|
627 |
#if defined(MALLOC_DEBUG) && defined(ALLOCATED_TESTS) |
628 |
# define AssertContainedIn(ptr1,ptr2) \ |
629 |
asc_assert(InMemoryBlockF((VOIDPTR)(ptr1),(VOIDPTR)(ptr2))) |
630 |
#else |
631 |
# define AssertContainedIn(ptr,ptr2) |
632 |
#endif |
633 |
/**< |
634 |
* Assertion that memory block ptr2 is contained in the block |
635 |
* starting at ptr1. This assertion is only active if both |
636 |
* MALLOC_DEBUG and ALLOCATED_TESTS are defined. |
637 |
*/ |
638 |
|
639 |
#endif /* ASC_WITH_DMALLOC */ |
640 |
|
641 |
#endif /* ASC_ASCMALLOC_H */ |
642 |
|