/[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 600 - (show annotations) (download) (as text)
Fri May 12 14:30:18 2006 UTC (17 years ago) by johnpye
File MIME type: text/x-chdr
File size: 19795 byte(s)
Added some missing export symbols. Unfortunately this seems to have caused a segfaul in the CUnit tests.
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 These functions provide tracking of memory events and assist
22 finding and debugging memory errors. Memory tracking options are
23 selected using the macros MALLOC_DEBUG and ALLOCATED_TESTS discussed
24 below. This allows the enhanced functionality to be used or turned
25 off as desired. This functionality adds considerable run-time overhead,
26 and so should generally be used for debugging purposes only. There are
27 also routines for reporting on the status of memory blocks as well as
28 for the memory manager itself.<br><br>
29
30 To use the memory tracking features, you need to use the provided
31 allocation and deallocation functions (ascmalloc(), asccalloc(),
32 ascrealloc(), ascfree()). Direct calls to the corresponding system
33 routines will by-pass the memory manager and not be tracked. Memory
34 allocations which return NULL are not tracked or recorded.<br><br>
35
36 This module also standardizes critical implementation-specific features
37 such as behavior when an allocation of zero bytes is requested
38 (see MOD_ASCMALLOC), and the behavior of realloc() under purify
39 (see MOD_REALLOC).<br><br>
40
41 The following macros affect the compilation and run-time behavior
42 of Ascend memory management.
43
44 <pre>
45 MOD_ASCMALLOC Forces the memory allocation functions to always
46 allocate at least 1 byte and return a non-NULL
47 pointer. This macro should be defined if your
48 allocator returns NULL when a zero-sized block is
49 requested (e.g. alpha or rs6000; Borland and Watcom
50 on Windows). It need not be defined if your
51 allocator returns a non-NULL pointer to a zero-length
52 block, saving you a few bytes of memory.
53
54 MALLOC_DEBUG Causes all calls to memory allocation routines
55 to be tracked and logged to an output file.
56 This really slows down the memory management
57 system, and so should be used for debugging only.
58
59 ALLOCATED_TESTS Forces a lot of extra assertions when defined
60 along with MALLOC_DEBUG.
61
62 MOD_REALLOC If defined, ascreallocPURE() uses a homegrown
63 realloc() that behaves properly with purify.
64 This is more expensive, and should be used
65 for debugging only.
66
67 Requires:
68 #include "utilities/ascConfig.h"
69 #include "utilities/ascPanic.h"
70 </pre>
71 *//*
72 by Tom Epperly
73 Created: 2/6/90
74 Version: $Revision: 1.2 $
75 Version control file: $RCSfile: ascMalloc.h,v $
76 Date last modified: $Date: 1997/07/18 11:44:50 $
77 Last modified by: $Author: mthomas $
78 */
79
80 #ifndef ASC_ASCMALLOC_H
81 #define ASC_ASCMALLOC_H
82
83 /* MALLOC_DEBUG may be defined in config.h... */
84 #include <utilities/config.h>
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 ASC_DLLSPEC(char *) ascstrdupf(CONST 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(CONST 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 ASC_DLLSPEC(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 ASC_DLLSPEC(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 ASC_DLLSPEC(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 ASC_DLLSPEC(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 ASC_DLLSPEC(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 ASC_DLLSPEC(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 ASC_DLLSPEC(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 ASC_DLLSPEC(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 ASC_DLLSPEC(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 an 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 ASC_DLLSPEC(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 ASC_DLLSPEC(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