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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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, see <http://www.gnu.org/licenses/>.
16 *//*
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 #include <stdio.h>
24 #include <limits.h>
25 /* if threading, need to make some macros to use the _r functions of time. */
26 #include <time.h>
27 #include <stdlib.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #ifndef __WIN32__
32 # include <unistd.h>
33 #else
34 # include <io.h> /* _open() declared here in MSVC */
35 #endif
36 #include "panic.h"
37 #include "ascMalloc.h"
38
39 /*
40 * The "non-debug" version of ascstrdupf -
41 * all memory calls should be to the system versions.
42 */
43 char *ascstrdupf(CONST char *s){
44 char *result;
45
46 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 return result;
56 }
57
58 /*------------------------------------------------------------------------------
59 ASCEND 'MALLOC' IMPLEMENTATION
60
61 if 'dmalloc' is being used, we don't need *any* of this stuff
62 */
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 /*
78 * Here's the debug version of ASC_STRDUP -
79 * all memory calls should be to the local debug versions.
80 */
81 char *ascstrdupf_dbg(CONST char *s){
82 char *result;
83
84 if (NULL == s) {
85 return NULL;
86 }
87 result = (char *)ascmallocf(strlen(s) + 1, __FILE__, __LINE__);
88 if (NULL != result) {
89 strcpy(result, s);
90 }
91 return result;
92 }
93
94 char *asc_memcpy(char *to, char *from, size_t size){
95 /* 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 asc_assert((size == 0) || ((NULL != to) && (NULL != from)));
102 if (from < to) {
103 fill = (to + size) - 1;
104 from += (size - 1);
105 while (size-- > 0) {
106 *fill-- = *from--;
107 }
108 }else{
109 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 /*
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 {
125 /* shrink */
126 if (newbytes > 0 && newbytes <= oldbytes) return ptr;
127 /* release */
128 if (!newbytes) {
129 free(ptr);
130 return NULL;
131 }
132 /* create */
133 if (!oldbytes) {
134 if (ptr!=NULL) free(ptr); /* some OS allocate 0 bytes, god help us */
135 return (char *)malloc(newbytes);
136 }else{
137 /* expand */
138 char *ret;
139 ret = malloc(newbytes);
140 if (ret==NULL) return NULL;
141 if (oldbytes%sizeof(long) == 0 && ((asc_intptr_t)ptr)%sizeof(long) == 0) {
142 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 free(ptr);
151 return ret;
152 }
153 }
154
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 }else{
173 /* expand */
174 char *ret;
175 ret = ascmallocf(newbytes, __FILE__, __LINE__);
176 if (ret==NULL) return NULL;
177 if (oldbytes%sizeof(long) == 0 && ((asc_intptr_t)ptr)%sizeof(long) == 0) {
178 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 struct memory_rec{
192 CONST VOIDPTR ptr;
193 size_t size;
194 };
195
196 #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
205 unsigned long ascmeminusef(void)
206 {
207 return f_memory_allocated;
208 }
209
210 static CONST VOIDPTR MinMemory(void)
211 {
212 int c;
213 CONST VOIDPTR minm=(VOIDPTR)ULONG_MAX;
214 for(c=0;c<f_memory_length;c++)
215 if (f_mem_rec[c].ptr < minm) minm = f_mem_rec[c].ptr;
216 return minm;
217 }
218
219 static CONST VOIDPTR MaxMemory(void)
220 {
221 int c;
222 CONST VOIDPTR maxm=0;
223 for(c=0;c<f_memory_length;c++)
224 if (((CONST char *)f_mem_rec[c].ptr + f_mem_rec[c].size - 1)
225 > (CONST char *)maxm)
226 maxm = (CONST VOIDPTR)((CONST char *)f_mem_rec[c].ptr + f_mem_rec[c].size - 1);
227 return maxm;
228 }
229
230 #define NONZERO(x) ((0 != (x)) ? (x) : 1)
231
232 static CONST VOIDPTR MemoryMean(void)
233 {
234 int c;
235 size_t size;
236 double sum=0.0, bytes=0.0;
237 for(c=0 ; c<f_memory_length ; c++){
238 size = f_mem_rec[c].size;
239 if (0 != size){
240 bytes += (double)size;
241 sum += (double)((size * (size-1))/2)
242 + ((double)size) * ((double)(asc_intptr_t)f_mem_rec[c].ptr);
243 }
244 }
245 return (VOIDPTR)(asc_intptr_t)(sum/NONZERO(bytes));
246 }
247
248 /*
249 * Creates a temporary file for logging memory events.
250 * The file is opened and header information is written to it.
251 * Thereafter, the FILE* is available to other routines in
252 * f_memory_log_file, which should append to the file as needed.
253 * This function may be called more than once - the file will only be
254 * created and header info written the first time it is called, or
255 * after ascshutdown() has been called.
256 */
257 static void OpenLogFile(void)
258 {
259 time_t t;
260 int handle;
261
262 if (NULL == f_memory_log_file) {
263
264 #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 ASC_PANIC("Unable to create a unique memory log filename.\n");
269 }
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 (NULL == (f_memory_log_file = fdopen(handle,"w")))) {
275 ASC_PANIC("Unable to open memory log file.\n");
276 }
277 #else
278 char temp_filename[] = TEMPFILE_TEMPLATE;
279 handle = mkstemp(temp_filename);
280 if ((-1 == handle) ||
281 (NULL == (f_memory_log_file = fdopen(handle,"r+")))) {
282 ASC_PANIC("Unable to open memory log file.\n");
283 }
284 #endif /* __WIN32__ */
285
286 t = time((time_t *)NULL);
287 FPRINTF(f_memory_log_file,"Ascend memory log file opened %s",
288 asctime(localtime(&t)));
289 FPRINTF(f_memory_log_file,"%16s %13s %16s %13s %6s %s",
290 "Alloc Range",
291 "Size",
292 "Dealloc Range",
293 "Size",
294 "Line#",
295 "Source File\n");
296 fflush(f_memory_log_file);
297 }
298 }
299
300 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 }
324
325 static void WriteMemoryRecords(FILE *f, CONST char *msg)
326 {
327 int c;
328 ASC_FPRINTF(f,"%s\nAllocation record count: %d\n", msg, f_memory_length);
329 for (c=0 ; c<f_memory_length ; ++c) {
330 ASC_FPRINTF(f,"%5d %p->%p %9zu\n",
331 c,
332 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 }
336 }
337
338 void ascstatusf(CONST char *msg)
339 {
340 OpenLogFile();
341 if (NULL != f_memory_log_file) {
342 WriteMemoryStatus(f_memory_log_file, msg);
343 fflush(f_memory_log_file);
344 }
345 WriteMemoryStatus(ASCINF, msg);
346 }
347
348 void ascstatus_detailf(CONST char *msg)
349 {
350 OpenLogFile();
351 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 }
356 WriteMemoryStatus(ASCINF, msg);
357 WriteMemoryRecords(ASCINF, "\nDetail Report of Currently Allocated Blocks");
358 }
359
360 void ascshutdownf(CONST char *msg){
361 OpenLogFile();
362 if(NULL != f_memory_log_file) {
363 //CONSOLE_DEBUG("got a memory log file %p",f_memory_log_file);
364 WriteMemoryStatus(f_memory_log_file,msg);
365 if(f_memory_length){
366 WriteMemoryRecords(f_memory_log_file, "\n!!! SHUTDOWN ALERT -- POINTERS STILL ALLOCATED !!!");
367 ASC_FPRINTF(f_memory_log_file, "!!! END OF SHUTDOWN MESSAGE !!!\n");
368 } else {
369 ASC_FPRINTF(f_memory_log_file, "NO POINTERS STILL ALLOCATED :-)\n");
370 }
371 fflush(f_memory_log_file);
372 #ifdef __WIN32__
373 CONSOLE_DEBUG("Memory log written to: %s", f_memlog_filename);
374 free(f_memlog_filename); /* free(), NOT ascfree() */
375 f_memlog_filename = NULL;
376 #else
377 CONSOLE_DEBUG("Memory log file written & closed.");
378 #endif
379 fclose(f_memory_log_file);
380 f_memory_log_file = NULL;
381 }
382 WriteMemoryStatus(ASCINF, msg);
383 if(f_memory_length){
384 WriteMemoryRecords(ASCINF, "\n!!! SHUTDOWN ALERT -- POINTERS STILL ALLOCATED !!!");
385 ASC_FPRINTF(ASCINF, "!!! END OF SHUTDOWN MESSAGE !!!\n");
386 } else {
387 ASC_FPRINTF(ASCINF, "NO POINTERS STILL ALLOCATED :-)\n");
388 }
389 }
390
391 static void WriteAllocation(CONST VOIDPTR adr, size_t size,
392 CONST char *file, int line)
393 {
394 if (NULL != f_memory_log_file) {
395 ASC_FPRINTF(f_memory_log_file,"%p->%p %9zu %31s%6d %s\n",
396 adr,
397 adr + size - 1,
398 size,
399 "",
400 line,
401 file);
402 fflush(f_memory_log_file);
403 }
404 else{
405 ASC_FPRINTF(ASCERR,"Unable to append to memory log file.\n");
406 ASC_FPRINTF(ASCERR,"%p->%p %9zu %31s%6d %s\n",
407 adr,
408 adr + size - 1,
409 size,
410 "",
411 line,
412 file);
413 }
414 }
415
416 static void WriteReAllocation(CONST VOIDPTR adr1, size_t size1,
417 CONST VOIDPTR adr2, size_t size2,
418 CONST char *file, int line)
419 {
420 if (NULL != f_memory_log_file) {
421 ASC_FPRINTF(f_memory_log_file,"%p->%p %9zu %p->%p %9zu %6d %s\n",
422 adr2,
423 adr2 + size2 - 1,
424 size2,
425 adr1,
426 adr1 + size1 - 1,
427 size1, line, file);
428 fflush(f_memory_log_file);
429 }
430 else{
431 ASC_FPRINTF(ASCERR,"Unable to append to memory log file.\n");
432 ASC_FPRINTF(ASCERR,"%p->%p %9zu %p->%p %9zu %6d %s\n",
433 adr2,
434 adr2 + size2 - 1,
435 size2,
436 adr1,
437 adr1 + size1 - 1,
438 size1, line, file);
439 }
440 }
441
442 static void WriteDeallocation(CONST VOIDPTR adr, size_t size,
443 CONST char *file, int line)
444 {
445 if (NULL != f_memory_log_file) {
446 ASC_FPRINTF(f_memory_log_file,"%31s%p->%p %9zu %6d %s\n","",
447 adr,
448 adr + size - 1,
449 size, line, file);
450 fflush(f_memory_log_file);
451 }
452 else{
453 ASC_FPRINTF(ASCERR,"Unable to append to memory log file.\n");
454 ASC_FPRINTF(ASCERR,"%31s%p->%p %9zu %6d %s\n","",
455 adr,
456 adr + size - 1,
457 size, line, file);
458 }
459 }
460
461 static void WriteError(CONST char *msg, CONST char *file, int line)
462 {
463 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 msg, file, line);
467 fflush(f_memory_log_file);
468 }
469 }
470
471 /*
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 * then f_memory_length is returned.
478 *
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 {
484 int c, lower, upper;
485 lower = 0;
486 upper = f_memory_length-1;
487 if (upper<lower) return -1;
488 while(lower<upper){
489 c = (lower+upper)/2;
490 if (f_mem_rec[c].ptr == ptr) return c;
491 if (f_mem_rec[c].ptr > ptr)
492 upper = c-1;
493 else
494 lower = c+1;
495 }
496 if (upper<lower) return lower;
497 if (lower>upper) return upper;
498 while(( lower < f_memory_length ) && ( f_mem_rec[lower].ptr < ptr )) lower++;
499 return lower;
500 }
501
502 int AllocatedMemoryF(CONST VOIDPTR ptr, size_t size)
503 {
504 int pos;
505
506 if (NULL == ptr) /* NULL ptr - by definition not allocated */
507 return 0;
508
509 pos = SearchForMemory(ptr);
510
511 if (pos < 0) /* no allocation records have been stored */
512 return 0;
513
514 /* if a matching pointer was found... */
515 if (( pos < f_memory_length ) &&
516 ( f_mem_rec[pos].ptr == ptr )) {
517 if ( f_mem_rec[pos].size == size )
518 return 2; /* the block matches an allocated block */
519 if ( f_mem_rec[pos].size > size )
520 return 1; /* the block is contained in an allocated block */
521 return -1; /* the block spans multiple allocated blocks */
522 }
523
524 /* if ptr block extends into the block above... */
525 else if (( pos < f_memory_length ) &&
526 ((CONST VOIDPTR)((CONST char *)ptr + size - 1) >= f_mem_rec[pos].ptr)) {
527 return -1; /* the block extends into the block above */
528 }
529
530 else if (pos > 0) {
531 if (ptr > ((CONST VOIDPTR)((CONST char *)f_mem_rec[pos-1].ptr + f_mem_rec[pos-1].size - 1)))
532 return 0; /* ptr not contained within the found block */
533
534 if ((CONST VOIDPTR)((CONST char *)ptr + size)
535 <= (CONST VOIDPTR)((CONST char *)f_mem_rec[pos-1].ptr + f_mem_rec[pos-1].size))
536 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 }
543
544 static void AddAllocatedMemory(CONST VOIDPTR ptr, size_t size,
545 CONST char *file, int line)
546 {
547 int pos,c;
548 pos = SearchForMemory(ptr);
549 if (( pos < 0 ) ||
550 ( pos == f_memory_length) ||
551 ( f_mem_rec[pos].ptr != ptr )) {
552 if ( pos < 0 ) pos = 0;
553 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 }
559 else {
560 /* make room for the new addition */
561 for(c=f_memory_length ; c>pos ; c--){
562 f_mem_rec[c] = f_mem_rec[c-1];
563 }
564 f_memory_length++;
565 f_mem_rec[pos].ptr = ptr;
566 f_mem_rec[pos].size = size;
567 }
568 }
569 else {
570 FPRINTF(ASCERR, "Pointer list filled up. Error messages may be unreliable.\n");
571 }
572 }
573 WriteAllocation(ptr,size,file,line);
574 }
575
576 static void DeallocateMemory(CONST VOIDPTR ptr, size_t size,
577 CONST char *file, int line)
578 {
579 int pos,c;
580 pos = SearchForMemory(ptr);
581 if (( pos >= 0 ) &&
582 ( pos < f_memory_length ) &&
583 ( f_mem_rec[pos].ptr == ptr )) {
584 /* a matching pointer was found */
585 asc_assert(f_mem_rec[pos].size == size);
586 /* copy all allocation records to the previous index, overwriting the current record */
587 for(c=pos+1 ; c<f_memory_length ; c++)
588 f_mem_rec[c-1] = f_mem_rec[c];
589 f_memory_length--;
590 }
591 WriteDeallocation(ptr,size,file,line);
592 }
593
594 static void ReallocateMemory(CONST VOIDPTR ptr1, size_t size1,
595 CONST VOIDPTR ptr2, size_t size2,
596 CONST char *file, int line)
597 {
598 int pos,c;
599 /* handle the deallocation first */
600 pos = SearchForMemory(ptr1);
601 if (( pos >= 0 ) &&
602 ( pos < f_memory_length ) &&
603 ( f_mem_rec[pos].ptr == ptr1 )) {
604 /* a matching pointer was found */
605 asc_assert(f_mem_rec[pos].size == size1);
606 /* copy all allocation records to the previous index, overwriting the current record */
607 for(c=pos+1 ; c<f_memory_length ; c++)
608 f_mem_rec[c-1] = f_mem_rec[c];
609 f_memory_length--;
610 }
611 /* then, handle the allocation if ptr2 is non-NULL */
612 pos = SearchForMemory(ptr2);
613 if (( NULL != ptr2 ) &&
614 (( pos < 0 ) ||
615 ( pos == f_memory_length) ||
616 ( f_mem_rec[pos].ptr != ptr2 ))) {
617 if ( pos < 0 ) pos = 0;
618 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 }
624 else {
625 /* make room for the new addition */
626 for(c=f_memory_length ; c>pos ; c--){
627 f_mem_rec[c] = f_mem_rec[c-1];
628 }
629 f_memory_length++;
630 f_mem_rec[pos].ptr = ptr2;
631 f_mem_rec[pos].size = size2;
632 }
633 }
634 else {
635 FPRINTF(ASCERR, "Pointer list filled up. Error messages may be unreliable.\n");
636 }
637 }
638 WriteReAllocation(ptr1,size1,ptr2,size2,file,line);
639 }
640
641 VOIDPTR asccallocf(size_t nelem, size_t elsize,
642 CONST char *file, int line)
643 {
644 VOIDPTR result;
645 OpenLogFile();
646 result = calloc(nelem,elsize);
647 if (NULL != result) {
648 /* adjust statistical variables */
649 f_memory_allocated += nelem*elsize;
650 if (f_memory_allocated > f_peak_memory_usage)
651 f_peak_memory_usage = f_memory_allocated;
652 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 }
658 return result;
659 }
660
661 VOIDPTR ascmallocf(size_t size, CONST char *file, int line)
662 {
663 VOIDPTR result;
664 OpenLogFile();
665 result = malloc(size);
666 if (NULL != result) {
667 f_memory_allocated += size;
668 if (f_memory_allocated > f_peak_memory_usage)
669 f_peak_memory_usage = f_memory_allocated;
670 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 }else{
676 ASC_FPRINTF(ASCERR,"ASCMALLOC FAILED TO ALLOCATE MEMORY OF SIZE %zu, result=%p\n",size,result);
677 }
678 return result;
679 }
680
681 static size_t FindMemorySize(CONST VOIDPTR ptr, int * CONST found)
682 {
683 int pos;
684 pos = SearchForMemory(ptr);
685 if (( pos >= 0 ) &&
686 ( pos < f_memory_length)) {
687 *found = 1;
688 if (f_mem_rec[pos].ptr==ptr) return f_mem_rec[pos].size;
689 }
690 *found = 0;
691 return 0;
692 }
693
694 VOIDPTR ascreallocf(VOIDPTR ptr, size_t size, CONST char *file, int line)
695 {
696 size_t old_size;
697 int found;
698 VOIDPTR result;
699 OpenLogFile();
700 if (AllocatedMemory(ptr,0)){
701 old_size = FindMemorySize(ptr,&found);
702 if (!found){
703 FPRINTF(ASCERR,"realloc'ing a piece of an allocated block.\n");
704 }
705 result = realloc(ptr,size);
706 }
707 else{
708 old_size = 0;
709 if (ptr == NULL) {
710 result = malloc(size);
711 } else {
712 WriteError("ascreallocf called on a deallocated piece of memory.",
713 file, line);
714 result = realloc(ptr,size);
715 }
716 }
717 if (NULL == result)
718 size = 0;
719 ReallocateMemory(ptr,old_size,result,size,file,line);
720 if (size >= old_size)
721 f_memory_allocated += (size-old_size);
722 else
723 f_memory_allocated -= (old_size-size);
724 if (f_memory_allocated > f_peak_memory_usage)
725 f_peak_memory_usage = f_memory_allocated;
726 return result;
727 }
728
729 void ascfreef(VOIDPTR ptr, CONST char *file, int line)
730 {
731 size_t size;
732 int found;
733
734 if (NULL == ptr)
735 return;
736
737 OpenLogFile();
738 if (0 != AllocatedMemory(ptr,0)) {
739 size = FindMemorySize(ptr,&found);
740 if (!found){ /* indicates a problem */
741 WriteError("Deallocating a piece of an allocated block.", file, line);
742 }
743 else
744 memset((char *)ptr, 0, size); /* clear the memory */
745 }
746 else {
747 WriteError("ascfreef called on a deallocated piece of memory.", file, line);
748 size = 0;
749 }
750 DeallocateMemory(ptr,size,file,line);
751 f_memory_allocated -= size;
752 free(ptr);
753 }
754
755 VOIDPTR ascbcopyf(CONST VOIDPTR src, VOIDPTR dest, size_t length,
756 CONST char *file, int line)
757 {
758 UNUSED_PARAMETER(file);
759 UNUSED_PARAMETER(line);
760 OpenLogFile();
761 return memcpy(dest, src, length);
762 }
763
764 VOIDPTR ascbzerof(VOIDPTR dest, size_t length, CONST char *file, int line)
765 {
766 UNUSED_PARAMETER(file);
767 UNUSED_PARAMETER(line);
768 OpenLogFile();
769 return memset((char *)dest, 0, length);
770 }
771
772 int InMemoryBlockF(CONST VOIDPTR ptr1, CONST VOIDPTR ptr2)
773 {
774 int pos;
775 pos = SearchForMemory(ptr1);
776 if (( pos >= 0 ) &&
777 ( pos < f_memory_length ) &&
778 ( f_mem_rec[pos].ptr == ptr1 ))
779 return (( ptr2 >= ptr1 ) &&
780 ( ptr2 < (CONST VOIDPTR)((CONST char *)ptr1 + f_mem_rec[pos].size)));
781 else
782 return 0;
783 }
784
785 #endif

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