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

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

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-csrc
File size: 23478 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.1 $
6 * Version control file: $RCSfile: ascMalloc.c,v $
7 * Date last modified: $Date: 1997/07/18 11:44:49 $
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
16 * as 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 #include <stdio.h>
31 #include <limits.h>
32 #include <time.h>
33 #include <malloc.h>
34 #include <stdlib.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include "utilities/ascConfig.h"
39 #ifndef __WIN32__
40 # include <unistd.h>
41 #else
42 # include <io.h> /* _open() declared here in MSVC */
43 #endif
44 #include "compiler/compiler.h"
45 #include "utilities/ascPanic.h"
46 #include "utilities/ascMalloc.h"
47
48 #define MAXPOINTERS 1000000
49
50 /* temporary file support */
51 #ifdef __WIN32__
52 # define LOGFILE "memlg"
53 #else
54 # define TEMPFILE_TEMPLATE "/tmp/ascmemlog_XXXXXX"
55 #endif
56
57 #ifndef lint
58 static CONST char AscendMemoryAllocRCSid[]="$Rev$";
59 #endif
60
61 /*
62 * The "non-debug" version of ascstrdupf -
63 * all memory calls should be to the system versions.
64 */
65 char *ascstrdupf(char *s)
66 {
67 char *result;
68
69 if (NULL == s) {
70 return NULL;
71 }
72 result = (char *)malloc(strlen(s) + 1);
73 if (NULL != result) {
74 strcpy(result, s);
75 }
76 return result;
77 }
78
79
80 /*
81 * Here's the debug version of ascstrdup -
82 * all memory calls should be to the local debug versions.
83 */
84 char *ascstrdupf_dbg(char *s)
85 {
86 char *result;
87
88 if (NULL == s) {
89 return NULL;
90 }
91 result = (char *)ascmallocf(strlen(s) + 1, __FILE__, __LINE__);
92 if (NULL != result) {
93 strcpy(result, s);
94 }
95 return result;
96 }
97
98 char *asc_memcpy(char *to, char *from, size_t size)
99 {
100 /* We really should be moving stuff a long at a time, but that mean
101 * handling the leading and trailing unaligned bytes separately.
102 * We also really should just be passing on to the vendor memcpy on
103 * those systems which do overlapping ranges right.
104 */
105 char *fill;
106 asc_assert((size == 0) || ((NULL != to) && (NULL != from)));
107 if (from < to) {
108 fill = (to + size) - 1;
109 from += (size - 1);
110 while (size-- > 0) {
111 *fill-- = *from--;
112 }
113 } else {
114 if (from > to) {
115 fill = to;
116 while (size-- > 0) {
117 *fill++ = *from++;
118 }
119 } /* else from == to, do nothing */
120 }
121 return to;
122 }
123
124 /*
125 * The "non-debug" version of ascreallocPURE -
126 * all memory calls should be to the system versions.
127 */
128 char *ascreallocPUREF(char *ptr, size_t oldbytes, size_t newbytes)
129 {
130 /* shrink */
131 if (newbytes > 0 && newbytes <= oldbytes) return ptr;
132 /* release */
133 if (!newbytes) {
134 free(ptr);
135 return NULL;
136 }
137 /* create */
138 if (!oldbytes) {
139 if (ptr!=NULL) free(ptr); /* some OS allocate 0 bytes, god help us */
140 return (char *)malloc(newbytes);
141 } else {
142 /* expand */
143 char *ret;
144 ret = malloc(newbytes);
145 if (ret==NULL) return NULL;
146 if (oldbytes%sizeof(long) == 0 && ((unsigned long)ptr)%sizeof(long) == 0) {
147 register unsigned long c,len, *src, *trg;
148 src = (unsigned long *)ptr;
149 trg = (unsigned long *)ret;
150 len = oldbytes/sizeof(long);
151 for (c=0;c < len;c++) trg[c]=src[c]; /* copy data as longs */
152 } else {
153 memcpy(ret,ptr,oldbytes);
154 }
155 free(ptr);
156 return ret;
157 }
158 }
159
160 /*
161 * Here's the debug version of ascreallocPURE -
162 * all memory calls should be to the local debug versions.
163 */
164 char *ascreallocPUREF_dbg(char *ptr, size_t oldbytes, size_t newbytes)
165 {
166 /* shrink */
167 if (newbytes > 0 && newbytes <= oldbytes) return ptr;
168 /* release */
169 if (!newbytes) {
170 ascfreef(ptr, __FILE__, __LINE__);
171 return NULL;
172 }
173 /* create */
174 if (!oldbytes) {
175 if (ptr!=NULL) ascfreef(ptr, __FILE__, __LINE__); /* some OS allocate 0 bytes, god help us */
176 return (char *)ascmallocf(newbytes, __FILE__, __LINE__);
177 } else {
178 /* expand */
179 char *ret;
180 ret = ascmallocf(newbytes, __FILE__, __LINE__);
181 if (ret==NULL) return NULL;
182 if (oldbytes%sizeof(long) == 0 && ((unsigned long)ptr)%sizeof(long) == 0) {
183 register unsigned long c,len, *src, *trg;
184 src = (unsigned long *)ptr;
185 trg = (unsigned long *)ret;
186 len = oldbytes/sizeof(long);
187 for (c=0;c < len;c++) trg[c]=src[c]; /* copy data as longs */
188 } else {
189 memcpy(ret,ptr,oldbytes);
190 }
191 ascfreef(ptr, __FILE__, __LINE__);
192 return ret;
193 }
194 }
195
196 struct memory_rec{
197 CONST VOIDPTR ptr;
198 size_t size;
199 };
200
201 #ifdef __WIN32__
202 static char *f_memlog_filename = NULL;
203 #endif
204 static FILE *f_memory_log_file = NULL;
205 static int f_memory_length = 0;
206 static unsigned long f_memory_allocated = 0L;
207 static unsigned long f_peak_memory_usage = 0L;
208 static struct memory_rec f_mem_rec[MAXPOINTERS];
209
210 unsigned long ascmeminusef(void)
211 {
212 return f_memory_allocated;
213 }
214
215 #ifdef THIS_IS_AN_UNUSED_FUNCTION
216 /*@unused@*/
217 static int SortedList(void)
218 {
219 int c;
220 for(c=1;c<f_memory_length;c++)
221 if (f_mem_rec[c-1].ptr>f_mem_rec[c].ptr) return 0;
222 return 1;
223 }
224 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
225
226 static CONST VOIDPTR MinMemory(void)
227 {
228 int c;
229 CONST VOIDPTR minm=(VOIDPTR)ULONG_MAX;
230 for(c=0;c<f_memory_length;c++)
231 if (f_mem_rec[c].ptr < minm) minm = f_mem_rec[c].ptr;
232 return minm;
233 }
234
235 static CONST VOIDPTR MaxMemory(void)
236 {
237 int c;
238 CONST VOIDPTR maxm=0;
239 for(c=0;c<f_memory_length;c++)
240 if (((CONST char *)f_mem_rec[c].ptr + f_mem_rec[c].size - 1)
241 > (CONST char *)maxm)
242 maxm = (CONST VOIDPTR)((CONST char *)f_mem_rec[c].ptr + f_mem_rec[c].size - 1);
243 return maxm;
244 }
245
246 #define NONZERO(x) ((0 != (x)) ? (x) : 1)
247
248 static CONST VOIDPTR MemoryMean(void)
249 {
250 int c;
251 size_t size;
252 double sum=0.0, bytes=0.0;
253 for(c=0 ; c<f_memory_length ; c++){
254 size = f_mem_rec[c].size;
255 if (0 != size){
256 bytes += (double)size;
257 sum += (double)((size * (size-1))/2)
258 + ((double)size) * ((double)(unsigned long)f_mem_rec[c].ptr);
259 }
260 }
261 return (VOIDPTR)(unsigned long)(sum/NONZERO(bytes));
262 }
263
264 /*
265 * Creates a temporary file for logging memory events.
266 * The file is opened and header information is written to it.
267 * Thereafter, the FILE* is available to other routines in
268 * f_memory_log_file, which should append to the file as needed.
269 * This function may be called more than once - the file will only be
270 * created and header info written the first time it is called, or
271 * after ascshutdown() has been called.
272 */
273 static void OpenLogFile(void)
274 {
275 time_t t;
276 int handle;
277
278 if (NULL == f_memory_log_file) {
279
280 #ifdef __WIN32__
281 /* Windows doesn't have mkstemp(), so need to use tempnam() */
282 f_memlog_filename = tempnam(NULL, LOGFILE);
283 if (NULL == f_memlog_filename) {
284 Asc_Panic(2, NULL, "Unable to create a unique memory log filename.\n");
285 }
286 handle = _open(f_memlog_filename,
287 O_WRONLY | O_CREAT | O_EXCL | O_TEXT,
288 _S_IREAD | _S_IWRITE);
289 if ((-1 == handle) ||
290 (NULL == (f_memory_log_file = fdopen(handle,"w")))) {
291 Asc_Panic(2, NULL, "Unable to open memory log file.\n");
292 }
293 #else
294 char temp_filename[] = TEMPFILE_TEMPLATE;
295 handle = mkstemp(temp_filename);
296 if ((-1 == handle) ||
297 (NULL == (f_memory_log_file = fdopen(handle,"r+")))) {
298 Asc_Panic(2, NULL, "Unable to open memory log file.\n");
299 }
300 #endif /* __WIN32__ */
301
302 t = time((time_t *)NULL);
303 FPRINTF(f_memory_log_file,"Ascend memory log file opened %s",
304 asctime(localtime(&t)));
305 FPRINTF(f_memory_log_file,"%16s %13s %16s %13s %6s %s",
306 "Alloc Range",
307 "Size",
308 "Dealloc Range",
309 "Size",
310 "Line#",
311 "Source File\n");
312 fflush(f_memory_log_file);
313 }
314 }
315
316 static void WriteMemoryStatus(FILE *f, CONST char *msg)
317 {
318 CONST VOIDPTR minm;
319 CONST VOIDPTR maxm;
320 minm = MinMemory();
321 maxm = MaxMemory();
322 FPRINTF(f,"%s\n"
323 "Current memory usage(byte allocated): %lu\n"
324 "Current number of blocks: %d\n"
325 "Peak memory usage(bytes allocated): %lu\n"
326 "Lowest address: %lx\n"
327 "Highest address: %lx\n"
328 "Memory density: %g\n"
329 "Memory mean: %lx\n",
330 msg,
331 f_memory_allocated,
332 f_memory_length,
333 f_peak_memory_usage,
334 (unsigned long)minm,
335 (unsigned long)maxm,
336 ((double)f_memory_allocated/(double)
337 NONZERO((CONST char *)maxm - (CONST char *)minm)),
338 (unsigned long)MemoryMean());
339 }
340
341 static void WriteMemoryRecords(FILE *f, CONST char *msg)
342 {
343 int c;
344 FPRINTF(f,"%s\nAllocation record count: %d\n", msg, f_memory_length);
345 for (c=0 ; c<f_memory_length ; ++c) {
346 FPRINTF(f,"%5d %9x->%9x %9u\n",
347 c,
348 f_mem_rec[c].ptr,
349 (CONST VOIDPTR)((CONST char *)f_mem_rec[c].ptr + f_mem_rec[c].size),
350 f_mem_rec[c].size);
351 }
352 }
353
354 void ascstatusf(CONST char *msg)
355 {
356 OpenLogFile();
357 if (NULL != f_memory_log_file) {
358 WriteMemoryStatus(f_memory_log_file, msg);
359 fflush(f_memory_log_file);
360 }
361 WriteMemoryStatus(ASCINF, msg);
362 }
363
364 void ascstatus_detailf(CONST char *msg)
365 {
366 OpenLogFile();
367 if (NULL != f_memory_log_file) {
368 WriteMemoryStatus(f_memory_log_file, msg);
369 WriteMemoryRecords(f_memory_log_file, "\nDetail Report of Currently Allocated Blocks");
370 fflush(f_memory_log_file);
371 }
372 WriteMemoryStatus(ASCINF, msg);
373 WriteMemoryRecords(ASCINF, "\nDetail Report of Currently Allocated Blocks");
374 }
375
376 void ascshutdownf(CONST char *msg)
377 {
378 OpenLogFile();
379 if (NULL != f_memory_log_file) {
380 WriteMemoryStatus(f_memory_log_file,msg);
381 if (f_memory_length) {
382 WriteMemoryRecords(f_memory_log_file, "\n!!! SHUTDOWN ALERT -- POINTERS STILL ALLOCATED !!!");
383 FPRINTF(f_memory_log_file, "!!! END OF SHUTDOWN MESSAGE !!!\n");
384 } else {
385 FPRINTF(f_memory_log_file, "NO POINTERS STILL ALLOCATED :-)\n");
386 }
387 fflush(f_memory_log_file);
388 #ifdef __WIN32__
389 FPRINTF(ASCINF, "Memory log written to: %s\n", f_memlog_filename);
390 free(f_memlog_filename); /* free(), NOT ascfree() */
391 f_memlog_filename = NULL;
392 #else
393 FPRINTF(ASCINF, "Memory log file written & closed.\n");
394 #endif
395 fclose(f_memory_log_file);
396 f_memory_log_file = NULL;
397 }
398 WriteMemoryStatus(ASCINF, msg);
399 if (f_memory_length) {
400 WriteMemoryRecords(ASCINF, "\n!!! SHUTDOWN ALERT -- POINTERS STILL ALLOCATED !!!");
401 FPRINTF(ASCINF, "!!! END OF SHUTDOWN MESSAGE !!!\n");
402 } else {
403 FPRINTF(ASCINF, "NO POINTERS STILL ALLOCATED :-)\n");
404 }
405 }
406
407 static void WriteAllocation(CONST VOIDPTR adr, size_t size,
408 CONST char *file, int line)
409 {
410 if (NULL != f_memory_log_file) {
411 FPRINTF(f_memory_log_file,"%9lx->%9x %9u %31s%6d %s\n",
412 (unsigned long)adr,
413 (unsigned long)adr + size - 1,
414 size,
415 "",
416 line,
417 file);
418 fflush(f_memory_log_file);
419 }
420 else{
421 FPRINTF(ASCERR,"Unable to append to memory log file.\n");
422 FPRINTF(ASCERR,"%9lx->%9x %9u %31s%6d %s\n",
423 (unsigned long)adr,
424 (unsigned long)adr + size - 1,
425 size,
426 "",
427 line,
428 file);
429 }
430 }
431
432 static void WriteReAllocation(CONST VOIDPTR adr1, size_t size1,
433 CONST VOIDPTR adr2, size_t size2,
434 CONST char *file, int line)
435 {
436 if (NULL != f_memory_log_file) {
437 FPRINTF(f_memory_log_file,"%9lx->%9x %9u %9lx->%9x %9u %6d %s\n",
438 (unsigned long)adr2,
439 (unsigned long)adr2 + size2 - 1,
440 size2,
441 (unsigned long)adr1,
442 (unsigned long)adr1 + size1 - 1,
443 size1, line, file);
444 fflush(f_memory_log_file);
445 }
446 else{
447 FPRINTF(ASCERR,"Unable to append to memory log file.\n");
448 FPRINTF(ASCERR,"%9lx->%9x %9u %9lx->%9x %9u %6d %s\n",
449 (unsigned long)adr2,
450 (unsigned long)adr2 + size2 - 1,
451 size2,
452 (unsigned long)adr1,
453 (unsigned long)adr1 + size1 - 1,
454 size1, line, file);
455 }
456 }
457
458 static void WriteDeallocation(CONST VOIDPTR adr, size_t size,
459 CONST char *file, int line)
460 {
461 if (NULL != f_memory_log_file) {
462 FPRINTF(f_memory_log_file,"%31s%9x->%9x %9u %6d %s\n","",
463 (unsigned long)adr,
464 (unsigned long)adr + size - 1,
465 size, line, file);
466 fflush(f_memory_log_file);
467 }
468 else{
469 FPRINTF(ASCERR,"Unable to append to memory log file.\n");
470 FPRINTF(ASCERR,"%31s%9x->%9x %9u %6d %s\n","",
471 (unsigned long)adr,
472 (unsigned long)adr + size - 1,
473 size, line, file);
474 }
475 }
476
477 static void WriteError(CONST char *msg, CONST char *file, int line)
478 {
479 FPRINTF(ASCERR,"%s\nCalled from file: %s on line %d.\n", msg, file, line);
480 if (NULL != f_memory_log_file) {
481 FPRINTF(f_memory_log_file,"%s\nCalled from file: %s on line %d.\n",
482 msg, file, line);
483 fflush(f_memory_log_file);
484 }
485 }
486
487 /*
488 * Searches the array of allocation records for ptr.
489 * Returns -1 if no memory records have been recorded.
490 * Otherwise, returns the index of the memory record for
491 * which the stored pointer is greater than or equal to
492 * ptr. If ptr is higher than any of the stored pointers,
493 * then f_memory_length is returned.
494 *
495 * This routine assumes that the memory record array is sorted
496 * by pointer address ascending.
497 */
498 static int SearchForMemory(CONST VOIDPTR ptr)
499 {
500 int c, lower, upper;
501 lower = 0;
502 upper = f_memory_length-1;
503 if (upper<lower) return -1;
504 while(lower<upper){
505 c = (lower+upper)/2;
506 if (f_mem_rec[c].ptr == ptr) return c;
507 if (f_mem_rec[c].ptr > ptr)
508 upper = c-1;
509 else
510 lower = c+1;
511 }
512 if (upper<lower) return lower;
513 if (lower>upper) return upper;
514 while(( lower < f_memory_length ) && ( f_mem_rec[lower].ptr < ptr )) lower++;
515 return lower;
516 }
517
518 int AllocatedMemoryF(CONST VOIDPTR ptr, size_t size)
519 {
520 int pos;
521
522 if (NULL == ptr) /* NULL ptr - by definition not allocated */
523 return 0;
524
525 pos = SearchForMemory(ptr);
526
527 if (pos < 0) /* no allocation records have been stored */
528 return 0;
529
530 /* if a matching pointer was found... */
531 if (( pos < f_memory_length ) &&
532 ( f_mem_rec[pos].ptr == ptr )) {
533 if ( f_mem_rec[pos].size == size )
534 return 2; /* the block matches an allocated block */
535 if ( f_mem_rec[pos].size > size )
536 return 1; /* the block is contained in an allocated block */
537 return -1; /* the block spans multiple allocated blocks */
538 }
539
540 /* if ptr block extends into the block above... */
541 else if (( pos < f_memory_length ) &&
542 ((CONST VOIDPTR)((CONST char *)ptr + size - 1) >= f_mem_rec[pos].ptr)) {
543 return -1; /* the block extends into the block above */
544 }
545
546 else if (pos > 0) {
547 if (ptr > ((CONST VOIDPTR)((CONST char *)f_mem_rec[pos-1].ptr + f_mem_rec[pos-1].size - 1)))
548 return 0; /* ptr not contained within the found block */
549
550 if ((CONST VOIDPTR)((CONST char *)ptr + size)
551 <= (CONST VOIDPTR)((CONST char *)f_mem_rec[pos-1].ptr + f_mem_rec[pos-1].size))
552 return 1; /* the block is contained in an allocated block */
553 else
554 return -1; /* the block spans multiple allocated blocks */
555 }
556
557 return 0;
558 }
559
560 static void AddAllocatedMemory(CONST VOIDPTR ptr, size_t size,
561 CONST char *file, int line)
562 {
563 int pos,c;
564 pos = SearchForMemory(ptr);
565 if (( pos < 0 ) ||
566 ( pos == f_memory_length) ||
567 ( f_mem_rec[pos].ptr != ptr )) {
568 if ( pos < 0 ) pos = 0;
569 if ( (f_memory_length + 1) < MAXPOINTERS ) {
570 if ( pos == f_memory_length ) {
571 f_memory_length++;
572 f_mem_rec[pos].ptr = ptr;
573 f_mem_rec[pos].size = size;
574 }
575 else {
576 /* make room for the new addition */
577 for(c=f_memory_length ; c>pos ; c--){
578 f_mem_rec[c] = f_mem_rec[c-1];
579 }
580 f_memory_length++;
581 f_mem_rec[pos].ptr = ptr;
582 f_mem_rec[pos].size = size;
583 }
584 }
585 else {
586 FPRINTF(ASCERR, "Pointer list filled up. Error messages may be unreliable.\n");
587 }
588 }
589 WriteAllocation(ptr,size,file,line);
590 }
591
592 static void DeallocateMemory(CONST VOIDPTR ptr, size_t size,
593 CONST char *file, int line)
594 {
595 int pos,c;
596 pos = SearchForMemory(ptr);
597 if (( pos >= 0 ) &&
598 ( pos < f_memory_length ) &&
599 ( f_mem_rec[pos].ptr == ptr )) {
600 /* a matching pointer was found */
601 asc_assert(f_mem_rec[pos].size == size);
602 /* copy all allocation records to the previous index, overwriting the current record */
603 for(c=pos+1 ; c<f_memory_length ; c++)
604 f_mem_rec[c-1] = f_mem_rec[c];
605 f_memory_length--;
606 }
607 WriteDeallocation(ptr,size,file,line);
608 }
609
610 static void ReallocateMemory(CONST VOIDPTR ptr1, size_t size1,
611 CONST VOIDPTR ptr2, size_t size2,
612 CONST char *file, int line)
613 {
614 int pos,c;
615 /* handle the deallocation first */
616 pos = SearchForMemory(ptr1);
617 if (( pos >= 0 ) &&
618 ( pos < f_memory_length ) &&
619 ( f_mem_rec[pos].ptr == ptr1 )) {
620 /* a matching pointer was found */
621 asc_assert(f_mem_rec[pos].size == size1);
622 /* copy all allocation records to the previous index, overwriting the current record */
623 for(c=pos+1 ; c<f_memory_length ; c++)
624 f_mem_rec[c-1] = f_mem_rec[c];
625 f_memory_length--;
626 }
627 /* then, handle the allocation if ptr2 is non-NULL */
628 pos = SearchForMemory(ptr2);
629 if (( NULL != ptr2 ) &&
630 (( pos < 0 ) ||
631 ( pos == f_memory_length) ||
632 ( f_mem_rec[pos].ptr != ptr2 ))) {
633 if ( pos < 0 ) pos = 0;
634 if ( (f_memory_length + 1) < MAXPOINTERS ) {
635 if ( pos == f_memory_length ) {
636 f_memory_length++;
637 f_mem_rec[pos].ptr = ptr2;
638 f_mem_rec[pos].size = size2;
639 }
640 else {
641 /* make room for the new addition */
642 for(c=f_memory_length ; c>pos ; c--){
643 f_mem_rec[c] = f_mem_rec[c-1];
644 }
645 f_memory_length++;
646 f_mem_rec[pos].ptr = ptr2;
647 f_mem_rec[pos].size = size2;
648 }
649 }
650 else {
651 FPRINTF(ASCERR, "Pointer list filled up. Error messages may be unreliable.\n");
652 }
653 }
654 WriteReAllocation(ptr1,size1,ptr2,size2,file,line);
655 }
656
657 VOIDPTR asccallocf(size_t nelem, size_t elsize,
658 CONST char *file, int line)
659 {
660 VOIDPTR result;
661 OpenLogFile();
662 result = calloc(nelem,elsize);
663 if (NULL != result) {
664 /* adjust statistical variables */
665 f_memory_allocated += nelem*elsize;
666 if (f_memory_allocated > f_peak_memory_usage)
667 f_peak_memory_usage = f_memory_allocated;
668 if (AllocatedMemory(result,nelem*elsize)){
669 WriteError("calloc returned a piece of memory that is already being used.",
670 file,line);
671 }
672 AddAllocatedMemory(result,nelem*elsize,file,line);
673 }
674 return result;
675 }
676
677 VOIDPTR ascmallocf(size_t size, CONST char *file, int line)
678 {
679 VOIDPTR result;
680 OpenLogFile();
681 result = malloc(size);
682 if (NULL != result) {
683 f_memory_allocated += size;
684 if (f_memory_allocated > f_peak_memory_usage)
685 f_peak_memory_usage = f_memory_allocated;
686 if (AllocatedMemory(result,size)){
687 WriteError("malloc returned a piece of memory that is already being used.",
688 file,line);
689 }
690 AddAllocatedMemory(result,size,file,line);
691 }else{
692 FPRINTF(ASCERR,"ASCMALLOC FAILED TO ALLOCATE MEMORY OF SIZE %d, result=%p\n",size,result);
693 }
694 return result;
695 }
696
697 static size_t FindMemorySize(CONST VOIDPTR ptr, int * CONST found)
698 {
699 int pos;
700 pos = SearchForMemory(ptr);
701 if (( pos >= 0 ) &&
702 ( pos < f_memory_length)) {
703 *found = 1;
704 if (f_mem_rec[pos].ptr==ptr) return f_mem_rec[pos].size;
705 }
706 *found = 0;
707 return 0;
708 }
709
710 VOIDPTR ascreallocf(VOIDPTR ptr, size_t size, CONST char *file, int line)
711 {
712 size_t old_size;
713 int found;
714 VOIDPTR result;
715 OpenLogFile();
716 if (AllocatedMemory(ptr,0)){
717 old_size = FindMemorySize(ptr,&found);
718 if (!found){
719 FPRINTF(ASCERR,"realloc'ing a piece of an allocated block.\n");
720 }
721 result = realloc(ptr,size);
722 }
723 else{
724 old_size = 0;
725 if (ptr == NULL) {
726 result = malloc(size);
727 } else {
728 WriteError("ascreallocf called on a deallocated piece of memory.",
729 file, line);
730 result = realloc(ptr,size);
731 }
732 }
733 if (NULL == result)
734 size = 0;
735 ReallocateMemory(ptr,old_size,result,size,file,line);
736 if (size >= old_size)
737 f_memory_allocated += (size-old_size);
738 else
739 f_memory_allocated -= (old_size-size);
740 if (f_memory_allocated > f_peak_memory_usage)
741 f_peak_memory_usage = f_memory_allocated;
742 return result;
743 }
744
745 void ascfreef(VOIDPTR ptr, CONST char *file, int line)
746 {
747 size_t size;
748 int found;
749
750 if (NULL == ptr)
751 return;
752
753 OpenLogFile();
754 if (0 != AllocatedMemory(ptr,0)) {
755 size = FindMemorySize(ptr,&found);
756 if (!found){ /* indicates a problem */
757 WriteError("Deallocating a piece of an allocated block.", file, line);
758 }
759 else
760 memset((char *)ptr, 0, size); /* clear the memory */
761 }
762 else {
763 WriteError("ascfreef called on a deallocated piece of memory.", file, line);
764 size = 0;
765 }
766 DeallocateMemory(ptr,size,file,line);
767 f_memory_allocated -= size;
768 free(ptr);
769 }
770
771 VOIDPTR ascbcopyf(CONST VOIDPTR src, VOIDPTR dest, size_t length,
772 CONST char *file, int line)
773 {
774 UNUSED_PARAMETER(file);
775 UNUSED_PARAMETER(line);
776 OpenLogFile();
777 return memcpy(dest, src, length);
778 }
779
780 VOIDPTR ascbzerof(VOIDPTR dest, size_t length, CONST char *file, int line)
781 {
782 UNUSED_PARAMETER(file);
783 UNUSED_PARAMETER(line);
784 OpenLogFile();
785 return memset((char *)dest, 0, length);
786 }
787
788 int InMemoryBlockF(CONST VOIDPTR ptr1, CONST VOIDPTR ptr2)
789 {
790 int pos;
791 pos = SearchForMemory(ptr1);
792 if (( pos >= 0 ) &&
793 ( pos < f_memory_length ) &&
794 ( f_mem_rec[pos].ptr == ptr1 ))
795 return (( ptr2 >= ptr1 ) &&
796 ( ptr2 < (CONST VOIDPTR)((CONST char *)ptr1 + f_mem_rec[pos].size)));
797 else
798 return 0;
799 }

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