/[ascend]/branches/relerrorlist/ascend/general/ascMalloc.c
ViewVC logotype

Annotation of /branches/relerrorlist/ascend/general/ascMalloc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3215 - (hide annotations) (download) (as text)
Sat Oct 28 06:14:06 2017 UTC (4 years, 9 months ago) by jpye
File MIME type: text/x-csrc
File size: 22706 byte(s)
fixing printf warnings from gcc 7.2.0

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

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