/[ascend]/trunk/base/generic/utilities/ascMalloc.h
ViewVC logotype

Contents of /trunk/base/generic/utilities/ascMalloc.h

Parent Directory Parent Directory | Revision Log Revision Log


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

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22