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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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