1 static char rcsid[] = "$Id: mem.c 155282 2014-12-12 19:42:54Z twu $";
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5
6 #include "mem.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "assert.h"
10 #include "except.h"
11 #include "bool.h"
12
13 #ifdef HAVE_PTHREAD
14 #include <pthread.h>
15 #endif
16
17 /* Prints out memory usage at each alloc/free */
18 /* #define DEBUG_STACK 1 */
19 #ifdef DEBUG_STACK
20 #define debug_stack(x) x
21 #else
22 #define debug_stack(x)
23 #endif
24
25 /* #define DEBUG_HEAP 1 */
26 #ifdef DEBUG_HEAP
27 #define debug_heap(x) x
28 #else
29 #define debug_heap(x)
30 #endif
31
32
33 /* #define TRAP 1 */
34 #ifdef TRAP
35 static void *trap_contents;
36 static void **trap_location;
37 static int startp = 0;
38
39 void
Mem_trap_start(void ** location,const char * file,int line)40 Mem_trap_start (void **location, const char *file, int line) {
41 if (startp == 0) {
42 trap_location = location;
43 trap_contents = * (void **) location;
44 startp = 1;
45 printf("Initial value at location %p is %p from %s:%d\n",
46 trap_location,trap_contents,file,line);
47 fflush(stdout);
48 }
49 return;
50 }
51
52 void
Mem_trap_check(const char * file,int line)53 Mem_trap_check (const char *file, int line) {
54 if (startp > 0 && *trap_location != trap_contents) {
55 printf("Value changed at location %p. Old value was %p. New value is %p. Observed during check at %s:%d\n",
56 trap_location,trap_contents,*trap_location,file,line);
57 fflush(stdout);
58 trap_contents = * (void **) trap_location;
59 }
60 return;
61 }
62 #endif
63
64
65 #ifdef MEMUSAGE
66
67 struct sizelist {
68 long int size;
69 struct sizelist *rest;
70 };
71
72 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
73 static pthread_mutex_t memusage_mutex = PTHREAD_MUTEX_INITIALIZER;
74 static pthread_key_t key_memusage_std_stack; /* Standard pool: Memory that is used by a thread within a query */
75 static pthread_key_t key_memusage_std_sizelist;
76 static pthread_key_t key_memusage_std_stack_max;
77 static pthread_key_t key_memusage_std_heap;
78 static pthread_key_t key_memusage_std_heap_max;
79 static pthread_key_t key_memusage_keep; /* Keep pool: Memory that is kept by a thread between queries */
80 static pthread_key_t key_threadname;
81 #else
82 static char *threadname = "program";
83 static long int memusage_std_stack = 0;
84 static struct sizelist *memusage_std_sizelist = NULL;
85 static long int memusage_std_stack_max = 0;
86 static long int memusage_std_heap = 0;
87 static long int memusage_std_heap_max = 0;
88 static long int memusage_keep = 0;
89 #endif
90
91 static long int memusage_in = 0; /* Input pool: Memory from inbuffer to threads */
92 static long int memusage_out = 0; /* Output pool: Memory from threads to outbuffer */
93
94 void
Mem_usage_init()95 Mem_usage_init () {
96 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
97 pthread_key_create(&key_memusage_std_stack,NULL);
98 pthread_key_create(&key_memusage_std_sizelist,NULL);
99 pthread_key_create(&key_memusage_std_stack_max,NULL);
100 pthread_key_create(&key_memusage_std_heap,NULL);
101 pthread_key_create(&key_memusage_std_heap_max,NULL);
102 pthread_key_create(&key_memusage_keep,NULL);
103 pthread_key_create(&key_threadname,NULL);
104
105 pthread_setspecific(key_memusage_std_stack,(void *) 0);
106 pthread_setspecific(key_memusage_std_stack_max,(void *) 0);
107 pthread_setspecific(key_memusage_std_heap,(void *) 0);
108 pthread_setspecific(key_memusage_std_heap_max,(void *) 0);
109 #else
110 memusage_std_stack = 0;
111 memusage_std_sizelist = NULL;
112 memusage_std_stack_max = 0;
113 memusage_std_heap = 0;
114 memusage_std_heap_max = 0;
115 memusage_keep = 0;
116 #endif
117
118 memusage_in = 0;
119 memusage_out = 0;
120 return;
121 }
122
123
124 void
Mem_usage_set_threadname(char * threadname_in)125 Mem_usage_set_threadname (char *threadname_in) {
126 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
127 pthread_setspecific(key_threadname,(void *) threadname_in);
128 #else
129 threadname = threadname_in;
130 #endif
131 return;
132 }
133
134 void
Mem_usage_reset_heap_baseline(long int x)135 Mem_usage_reset_heap_baseline (long int x) {
136 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
137 long int memusage_std_heap;
138
139 #ifdef DEBUG_HEAP
140 char *threadname;
141 threadname = (char *) pthread_getspecific(key_threadname);
142 #endif
143
144 memusage_std_heap = (long int) pthread_getspecific(key_memusage_std_heap);
145 debug_heap(printf("%ld %s: Reset memusage_std_heap to %ld\n",memusage_std_heap,threadname,x));
146 pthread_setspecific(key_memusage_std_heap,(void *) x);
147 #else
148 debug_heap(printf("%ld: Reset memusage_std_heap to %ld\n",memusage_std_heap,x));
149 memusage_std_heap = x;
150 #endif
151 }
152
153 void
Mem_usage_reset_stack_max()154 Mem_usage_reset_stack_max () {
155 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
156 long int memusage_std_stack_max;
157
158 memusage_std_stack_max = (long int) pthread_getspecific(key_memusage_std_stack_max);
159 pthread_setspecific(key_memusage_std_stack_max,(void *) 0);
160 #else
161 memusage_std_stack_max = 0;
162 #endif
163 }
164
165 void
Mem_usage_reset_heap_max()166 Mem_usage_reset_heap_max () {
167 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
168 long int memusage_std_heap_max;
169
170 memusage_std_heap_max = (long int) pthread_getspecific(key_memusage_std_heap_max);
171 pthread_setspecific(key_memusage_std_heap_max,(void *) 0);
172 #else
173 memusage_std_heap_max = 0;
174 #endif
175 }
176
177
178 void
Mem_usage_std_stack_add(long int x,const char * file,int line)179 Mem_usage_std_stack_add (long int x, const char *file, int line) {
180 struct sizelist *new;
181
182 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
183 long int memusage_std_stack, memusage_std_stack_max;
184
185 #ifdef DEBUG_STACK
186 char *threadname;
187 threadname = (char *) pthread_getspecific(key_threadname);
188 #endif
189
190 memusage_std_stack = (long int) pthread_getspecific(key_memusage_std_stack);
191 memusage_std_stack += x;
192 debug_stack(printf("%ld %s: ",memusage_std_stack,threadname));
193 pthread_setspecific(key_memusage_std_stack,(void *) memusage_std_stack);
194
195 memusage_std_stack_max = (long int) pthread_getspecific(key_memusage_std_stack_max);
196 if (memusage_std_stack > memusage_std_stack_max) {
197 pthread_setspecific(key_memusage_std_stack_max,(void *) memusage_std_stack);
198 }
199
200 new = (struct sizelist *) malloc(sizeof(struct sizelist));
201 new->size = x;
202 new->rest = (struct sizelist *) pthread_getspecific(key_memusage_std_sizelist);
203 pthread_setspecific(key_memusage_std_sizelist,(void *) new);
204
205 debug_stack(printf("Reset memusage_std_stack to %ld at %s:%d\n",memusage_std_stack,file,line));
206
207 #else
208 memusage_std_stack += x;
209 debug_stack(printf("%ld: ",memusage_std_stack));
210
211 if (memusage_std_stack > memusage_std_stack_max) {
212 memusage_std_stack_max = memusage_std_stack;
213 }
214
215 new = (struct sizelist *) malloc(sizeof(struct sizelist));
216 new->size = x;
217 new->rest = memusage_std_sizelist;
218 memusage_std_sizelist = new;
219
220 debug_stack(printf("Reset memusage_std_stack to %ld at %s:%d\n",memusage_std_stack,file,line));
221 #endif
222
223 return;
224 }
225
226 void
Mem_usage_std_stack_subtract(const char * file,int line)227 Mem_usage_std_stack_subtract (const char *file, int line) {
228 long int x;
229 struct sizelist *head;
230
231 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
232 long int memusage_std_stack;
233 struct sizelist *memusage_std_sizelist;
234
235 #ifdef DEBUG_STACK
236 char *threadname;
237 threadname = (char *) pthread_getspecific(key_threadname);
238 #endif
239
240 memusage_std_sizelist = (struct sizelist *) pthread_getspecific(key_memusage_std_sizelist);
241 x = memusage_std_sizelist->size;
242 head = memusage_std_sizelist->rest;
243 free(memusage_std_sizelist);
244 pthread_setspecific(key_memusage_std_sizelist,(void *) head);
245
246 memusage_std_stack = (long int) pthread_getspecific(key_memusage_std_stack);
247 memusage_std_stack -= x;
248 debug_stack(printf("%ld %s: ",memusage_std_stack,threadname));
249 pthread_setspecific(key_memusage_std_stack,(void *) memusage_std_stack);
250
251 debug_stack(printf("Reset memusage_std_stack to %ld at %s:%d\n",memusage_std_stack,file,line));
252
253 #else
254 x = memusage_std_sizelist->size;
255 head = memusage_std_sizelist->rest;
256 free(memusage_std_sizelist);
257 memusage_std_sizelist = head;
258
259 memusage_std_stack -= x;
260 debug_stack(printf("%ld: ",memusage_std_stack));
261
262 debug_stack(printf("Reset memusage_std_stack to %ld at %s:%d\n",memusage_std_stack,file,line));
263 #endif
264
265 return;
266 }
267
268
269 void
Mem_usage_std_heap_add(long int x)270 Mem_usage_std_heap_add (long int x) {
271 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
272 long int memusage_std_heap;
273
274 #ifdef DEBUG_HEAP
275 char *threadname;
276 threadname = (char *) pthread_getspecific(key_threadname);
277 #endif
278
279 memusage_std_heap = (long int) pthread_getspecific(key_memusage_std_heap);
280 memusage_std_heap += x;
281 debug_heap(printf("%ld %s: ",memusage_std_heap,threadname));
282 pthread_setspecific(key_memusage_std_heap,(void *) memusage_std_heap);
283 debug_heap(printf("Reset memusage_std_heap to %ld\n",memusage_std_heap));
284 #else
285 memusage_std_heap += x;
286 debug_heap(printf("%ld: ",memusage_std_heap));
287 debug_heap(printf("Reset memusage_std_heap to %ld\n",memusage_std_heap));
288 #endif
289 }
290
291 long int
Mem_usage_report_std_stack()292 Mem_usage_report_std_stack () {
293 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
294 return (long int) pthread_getspecific(key_memusage_std_stack);
295 #else
296 return memusage_std_stack;
297 #endif
298 }
299
300 long int
Mem_usage_report_std_heap()301 Mem_usage_report_std_heap () {
302 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
303 return (long int) pthread_getspecific(key_memusage_std_heap);
304 #else
305 return memusage_std_heap;
306 #endif
307 }
308
309 long int
Mem_usage_report_keep()310 Mem_usage_report_keep () {
311 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
312 return (long int) pthread_getspecific(key_memusage_keep);
313 #else
314 return memusage_keep;
315 #endif
316 }
317
318 long int
Mem_usage_report_std_stack_max()319 Mem_usage_report_std_stack_max () {
320 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
321 return (long int) pthread_getspecific(key_memusage_std_stack_max);
322 #else
323 return memusage_std_stack_max;
324 #endif
325 }
326
327 long int
Mem_usage_report_std_heap_max()328 Mem_usage_report_std_heap_max () {
329 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
330 return (long int) pthread_getspecific(key_memusage_std_heap_max);
331 #else
332 return memusage_std_heap_max;
333 #endif
334 }
335
336 long int
Mem_usage_report_in()337 Mem_usage_report_in () {
338 return memusage_in;
339 }
340
341 long int
Mem_usage_report_out()342 Mem_usage_report_out () {
343 return memusage_out;
344 }
345
346
347 #define hash(p, t) (((unsigned long)(p)>>3) & (sizeof (t)/sizeof ((t)[0])-1))
348 struct descriptor {
349 struct descriptor *link;
350 const void *ptr;
351 long size;
352 };
353 static struct descriptor *htab[2048000];
354
355 /* Also removes element from linked list */
356 static struct descriptor *
find(const void * ptr)357 find (const void *ptr) {
358 struct descriptor *bp, **pp;
359
360 pp = &(htab[hash(ptr, htab)]);
361 while (*pp && (*pp)->ptr != ptr) {
362 pp = &(*pp)->link;
363 }
364 if (*pp) {
365 bp = *pp;
366 *pp = bp->link;
367 return bp;
368 } else {
369 return NULL;
370 }
371 }
372 #endif
373
374
375
376 const Except_T Mem_Leak = { "Memory Leak" };
377 const Except_T Mem_Failed = { "Allocation Failed" };
378
379
380 void *
Mem_alloc(size_t nbytes,const char * file,int line)381 Mem_alloc (size_t nbytes, const char *file, int line) {
382 void *ptr;
383 #ifdef MEMUSAGE
384 static struct descriptor *bp;
385 unsigned h;
386
387 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
388 pthread_mutex_lock(&memusage_mutex);
389 long int memusage_std_heap, memusage_std_heap_max;
390 char *threadname;
391 #endif
392 #endif
393
394 assert(nbytes > 0);
395 ptr = malloc(nbytes);
396
397 #ifdef MEMUSAGE
398 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
399 threadname = (char *) pthread_getspecific(key_threadname);
400 memusage_std_heap = (long int) pthread_getspecific(key_memusage_std_heap);
401 memusage_std_heap += nbytes;
402 pthread_setspecific(key_memusage_std_heap,(void *) memusage_std_heap);
403
404 memusage_std_heap_max = (long int) pthread_getspecific(key_memusage_std_heap_max);
405 if (memusage_std_heap > memusage_std_heap_max) {
406 pthread_setspecific(key_memusage_std_heap_max,(void *) memusage_std_heap);
407 }
408 #else
409 memusage_std_heap += nbytes;
410 if (memusage_std_heap > memusage_std_heap_max) {
411 memusage_std_heap_max = memusage_std_heap;
412 }
413 #endif
414 h = hash(ptr,htab);
415 bp = malloc(sizeof(*bp));
416 bp->link = htab[h];
417 bp->ptr = ptr;
418 bp->size = nbytes;
419 htab[h] = bp;
420 #endif
421
422 #ifdef MEMUSAGE
423 debug_heap(printf("%ld %s: Allocating %p to %p -- Malloc of %zu bytes in standard pool requested from %s:%d\n",
424 memusage_std_heap,threadname,ptr,(char *) ptr + nbytes-1,nbytes,file,line));
425 #else
426 debug_heap(printf("Allocating %p to %p -- Malloc of %zu bytes in standard pool requested from %s:%d\n",
427 ptr,(char *) ptr + nbytes-1,nbytes,file,line));
428 #endif
429
430
431 #ifdef TRAP
432 if (ptr == trap_location) {
433 printf("Trap: Alloc of location %p by %s:%d\n",ptr,file,line);
434 }
435 if (startp > 0 && *trap_location != trap_contents) {
436 printf("Value changed at location %p. Old value was %p. New value is %p. Observed during malloc at %s:%d\n",
437 trap_location,trap_contents,*trap_location,file,line);
438 fflush(stdout);
439 trap_contents = * (void **) trap_location;
440 }
441 #endif
442
443 if (ptr == NULL) {
444 fprintf(stderr,"Failed attempt to alloc %zu bytes\n",nbytes);
445 if (file == NULL) {
446 RAISE(Mem_Failed);
447 } else {
448 Except_raise(&Mem_Failed, file, line);
449 }
450 }
451
452 #ifdef MEMUSAGE
453 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
454 pthread_mutex_unlock(&memusage_mutex);
455 #endif
456 #endif
457
458 return ptr;
459 }
460
461
462
463 void *
Mem_alloc_keep(size_t nbytes,const char * file,int line)464 Mem_alloc_keep (size_t nbytes, const char *file, int line) {
465 void *ptr;
466 #ifdef MEMUSAGE
467 static struct descriptor *bp;
468 unsigned h;
469
470 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
471 pthread_mutex_lock(&memusage_mutex);
472 long int memusage_keep;
473 char *threadname;
474 #endif
475 #endif
476
477 assert(nbytes > 0);
478 ptr = malloc(nbytes);
479
480 #ifdef MEMUSAGE
481 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
482 threadname = (char *) pthread_getspecific(key_threadname);
483 memusage_keep = (long int) pthread_getspecific(key_memusage_keep);
484 memusage_keep += nbytes;
485 pthread_setspecific(key_memusage_keep,(void *) memusage_keep);
486 #else
487 memusage_keep += nbytes;
488 #endif
489 h = hash(ptr,htab);
490 bp = malloc(sizeof(*bp));
491 bp->link = htab[h];
492 bp->ptr = ptr;
493 bp->size = nbytes;
494 htab[h] = bp;
495 #endif
496
497 #ifdef MEMUSAGE
498 debug_heap(printf("%ld %s-keep: Allocating %p to %p -- Malloc of %zu bytes in keep pool requested from %s:%d\n",
499 memusage_keep,threadname,ptr,(char *) ptr + nbytes-1,nbytes,file,line));
500 #else
501 debug_heap(printf("Allocating %p to %p -- Malloc of %zu bytes in keep pool requested from %s:%d\n",
502 ptr,(char *) ptr + nbytes-1,nbytes,file,line));
503 #endif
504
505
506 #ifdef TRAP
507 if (ptr == trap_location) {
508 printf("Trap: Alloc of location %p by %s:%d\n",ptr,file,line);
509 }
510 if (startp > 0 && *trap_location != trap_contents) {
511 printf("Value changed at location %p. Old value was %p. New value is %p. Observed during malloc at %s:%d\n",
512 trap_location,trap_contents,*trap_location,file,line);
513 fflush(stdout);
514 trap_contents = * (void **) trap_location;
515 }
516 #endif
517
518 if (ptr == NULL) {
519 fprintf(stderr,"Failed attempt to alloc %zu bytes\n",nbytes);
520 if (file == NULL) {
521 RAISE(Mem_Failed);
522 } else {
523 Except_raise(&Mem_Failed, file, line);
524 }
525 }
526
527 #ifdef MEMUSAGE
528 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
529 pthread_mutex_unlock(&memusage_mutex);
530 #endif
531 #endif
532
533 return ptr;
534 }
535
536 void *
Mem_alloc_in(size_t nbytes,const char * file,int line)537 Mem_alloc_in (size_t nbytes, const char *file, int line) {
538 void *ptr;
539 #ifdef MEMUSAGE
540 static struct descriptor *bp;
541 unsigned h;
542
543 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
544 pthread_mutex_lock(&memusage_mutex);
545 #endif
546 #endif
547
548 assert(nbytes > 0);
549 ptr = malloc(nbytes);
550
551 #ifdef MEMUSAGE
552 memusage_in += nbytes;
553 h = hash(ptr,htab);
554 bp = malloc(sizeof(*bp));
555 bp->link = htab[h];
556 bp->ptr = ptr;
557 bp->size = nbytes;
558 htab[h] = bp;
559 #endif
560
561 #ifdef MEMUSAGE
562 debug_heap(printf("%ld IN: Allocating %p to %p -- Malloc of %zu bytes in input pool requested from %s:%d\n",
563 memusage_in,ptr,(char *) ptr + nbytes-1,nbytes,file,line));
564 #else
565 debug_heap(printf("Allocating %p to %p -- Malloc of %zu bytes in input pool requested from %s:%d\n",
566 ptr,(char *) ptr + nbytes-1,nbytes,file,line));
567 #endif
568
569
570 #ifdef TRAP
571 if (ptr == trap_location) {
572 printf("Trap: Alloc of location %p by %s:%d\n",ptr,file,line);
573 }
574 if (startp > 0 && *trap_location != trap_contents) {
575 printf("Value changed at location %p. Old value was %p. New value is %p. Observed during malloc at %s:%d\n",
576 trap_location,trap_contents,*trap_location,file,line);
577 fflush(stdout);
578 trap_contents = * (void **) trap_location;
579 }
580 #endif
581
582 if (ptr == NULL) {
583 fprintf(stderr,"Failed attempt to alloc %zu bytes\n",nbytes);
584 if (file == NULL) {
585 RAISE(Mem_Failed);
586 } else {
587 Except_raise(&Mem_Failed, file, line);
588 }
589 }
590
591 #ifdef MEMUSAGE
592 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
593 pthread_mutex_unlock(&memusage_mutex);
594 #endif
595 #endif
596
597 return ptr;
598 }
599
600 void *
Mem_alloc_out(size_t nbytes,const char * file,int line)601 Mem_alloc_out (size_t nbytes, const char *file, int line) {
602 void *ptr;
603 #ifdef MEMUSAGE
604 static struct descriptor *bp;
605 unsigned h;
606
607 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
608 pthread_mutex_lock(&memusage_mutex);
609 #endif
610 #endif
611
612 assert(nbytes > 0);
613 ptr = malloc(nbytes);
614
615 #ifdef MEMUSAGE
616 memusage_out += nbytes;
617 h = hash(ptr,htab);
618 bp = malloc(sizeof(*bp));
619 bp->link = htab[h];
620 bp->ptr = ptr;
621 bp->size = nbytes;
622 htab[h] = bp;
623 #endif
624
625 #ifdef MEMUSAGE
626 debug_heap(printf("%ld OUT: Allocating %p to %p -- Malloc of %zu bytes in output pool requested from %s:%d\n",
627 memusage_out,ptr,(char *) ptr + nbytes-1,nbytes,file,line));
628 #else
629 debug_heap(printf("Allocating %p to %p -- Malloc of %zu bytes in output pool requested from %s:%d\n",
630 ptr,(char *) ptr + nbytes-1,nbytes,file,line));
631 #endif
632
633
634 #ifdef TRAP
635 if (ptr == trap_location) {
636 printf("Trap: Alloc of location %p by %s:%d\n",ptr,file,line);
637 }
638 if (startp > 0 && *trap_location != trap_contents) {
639 printf("Value changed at location %p. Old value was %p. New value is %p. Observed during malloc at %s:%d\n",
640 trap_location,trap_contents,*trap_location,file,line);
641 fflush(stdout);
642 trap_contents = * (void **) trap_location;
643 }
644 #endif
645
646 if (ptr == NULL) {
647 fprintf(stderr,"Failed attempt to alloc %zu bytes\n",nbytes);
648 if (file == NULL) {
649 RAISE(Mem_Failed);
650 } else {
651 Except_raise(&Mem_Failed, file, line);
652 }
653 }
654
655 #ifdef MEMUSAGE
656 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
657 pthread_mutex_unlock(&memusage_mutex);
658 #endif
659 #endif
660
661 return ptr;
662 }
663
664 void *
Mem_alloc_no_exception(size_t nbytes,const char * file,int line)665 Mem_alloc_no_exception (size_t nbytes, const char *file, int line) {
666 void *ptr;
667 assert(nbytes > 0);
668 ptr = malloc(nbytes);
669 return ptr;
670 }
671
672 void *
Mem_calloc(size_t count,size_t nbytes,const char * file,int line)673 Mem_calloc (size_t count, size_t nbytes, const char *file, int line) {
674 void *ptr;
675 #ifdef MEMUSAGE
676 static struct descriptor *bp;
677 unsigned h;
678
679 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
680 pthread_mutex_lock(&memusage_mutex);
681 long int memusage_std_heap, memusage_std_heap_max;
682 char *threadname;
683 #endif
684 #endif
685
686 if (count <= 0) {
687 fprintf(stderr,"Failed attempt to calloc %zu x %zu bytes\n",count,nbytes);
688 if (file == NULL) {
689 RAISE(Mem_Failed);
690 } else {
691 Except_raise(&Mem_Failed, file, line);
692 }
693 }
694 assert(nbytes > 0);
695
696 ptr = calloc(count,nbytes);
697
698 #ifdef TRAP
699 if (ptr == trap_location) {
700 printf("Trap: Calloc of location %p by %s:%d\n",ptr,file,line);
701 }
702
703 if (startp > 0 && *trap_location != trap_contents) {
704 printf("Value changed at location %p. Old value is %p. New value is %p. Observed during calloc at %s:%d\n",
705 trap_location,trap_contents,*trap_location,file,line);
706 fflush(stdout);
707 trap_contents = * (void **) trap_location;
708 }
709 #endif
710
711 #ifdef MEMUSAGE
712 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
713 threadname = (char *) pthread_getspecific(key_threadname);
714 memusage_std_heap = (long int) pthread_getspecific(key_memusage_std_heap);
715 memusage_std_heap += count*nbytes;
716 pthread_setspecific(key_memusage_std_heap,(void *) memusage_std_heap);
717
718 memusage_std_heap_max = (long int) pthread_getspecific(key_memusage_std_heap_max);
719 if (memusage_std_heap > memusage_std_heap_max) {
720 pthread_setspecific(key_memusage_std_heap_max,(void *) memusage_std_heap);
721 }
722 #else
723 memusage_std_heap += count*nbytes;
724 if (memusage_std_heap > memusage_std_heap_max) {
725 memusage_std_heap_max = memusage_std_heap;
726 }
727 #endif
728 h = hash(ptr,htab);
729 bp = malloc(sizeof(*bp));
730 bp->link = htab[h];
731 bp->ptr = ptr;
732 bp->size = count*nbytes;
733 htab[h] = bp;
734 #endif
735
736 #ifdef MEMUSAGE
737 debug_heap(printf("%ld %s: Allocating %p to %p -- Calloc of %zu x %zu = %zu bytes in standard pool requested from %s:%d\n",
738 memusage_std_heap,threadname,ptr,(char *) ptr + count*nbytes-1,count,nbytes,count*nbytes,file,line));
739 #else
740 debug_heap(printf("Allocating %p to %p -- Calloc of %zu x %zu = %zu bytes in standard pool requested from %s:%d\n",
741 ptr,(char *) ptr + count*nbytes-1,count,nbytes,count*nbytes,file,line));
742 #endif
743
744 if (ptr == NULL) {
745 fprintf(stderr,"Failed attempt to calloc %zu x %zu bytes\n",count,nbytes);
746 if (file == NULL) {
747 RAISE(Mem_Failed);
748 } else {
749 Except_raise(&Mem_Failed, file, line);
750 }
751 }
752
753 #ifdef MEMUSAGE
754 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
755 pthread_mutex_unlock(&memusage_mutex);
756 #endif
757 #endif
758
759 return ptr;
760 }
761
762
763 void *
Mem_calloc_keep(size_t count,size_t nbytes,const char * file,int line)764 Mem_calloc_keep (size_t count, size_t nbytes, const char *file, int line) {
765 void *ptr;
766 #ifdef MEMUSAGE
767 static struct descriptor *bp;
768 unsigned h;
769
770 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
771 pthread_mutex_lock(&memusage_mutex);
772 long int memusage_keep;
773 char *threadname;
774 #endif
775 #endif
776
777 if (count <= 0) {
778 fprintf(stderr,"Failed attempt to calloc %zu x %zu bytes\n",count,nbytes);
779 if (file == NULL) {
780 RAISE(Mem_Failed);
781 } else {
782 Except_raise(&Mem_Failed, file, line);
783 }
784 }
785 assert(nbytes > 0);
786
787 ptr = calloc(count,nbytes);
788
789 #ifdef TRAP
790 if (ptr == trap_location) {
791 printf("Trap: Calloc of location %p by %s:%d\n",ptr,file,line);
792 }
793
794 if (startp > 0 && *trap_location != trap_contents) {
795 printf("Value changed at location %p. Old value is %p. New value is %p. Observed during calloc at %s:%d\n",
796 trap_location,trap_contents,*trap_location,file,line);
797 fflush(stdout);
798 trap_contents = * (void **) trap_location;
799 }
800 #endif
801
802 #ifdef MEMUSAGE
803 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
804 threadname = (char *) pthread_getspecific(key_threadname);
805 memusage_keep = (long int) pthread_getspecific(key_memusage_keep);
806 memusage_keep += count*nbytes;
807 pthread_setspecific(key_memusage_keep,(void *) memusage_keep);
808 #else
809 memusage_keep += count*nbytes;
810 #endif
811 h = hash(ptr,htab);
812 bp = malloc(sizeof(*bp));
813 bp->link = htab[h];
814 bp->ptr = ptr;
815 bp->size = count*nbytes;
816 htab[h] = bp;
817 #endif
818
819 #ifdef MEMUSAGE
820 debug_heap(printf("%ld %s-keep: Allocating %p to %p -- Calloc of %zu x %zu = %zu bytes in keep pool requested from %s:%d\n",
821 memusage_keep,threadname,ptr,(char *) ptr + count*nbytes-1,count,nbytes,count*nbytes,file,line));
822 #else
823 debug_heap(printf("Allocating %p to %p -- Calloc of %zu x %zu = %zu bytes in keep pool requested from %s:%d\n",
824 ptr,(char *) ptr + count*nbytes-1,count,nbytes,count*nbytes,file,line));
825 #endif
826
827 if (ptr == NULL) {
828 fprintf(stderr,"Failed attempt to calloc %zu x %zu bytes\n",count,nbytes);
829 if (file == NULL) {
830 RAISE(Mem_Failed);
831 } else {
832 Except_raise(&Mem_Failed, file, line);
833 }
834 }
835
836 #ifdef MEMUSAGE
837 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
838 pthread_mutex_unlock(&memusage_mutex);
839 #endif
840 #endif
841
842 return ptr;
843 }
844
845
846 void *
Mem_calloc_in(size_t count,size_t nbytes,const char * file,int line)847 Mem_calloc_in (size_t count, size_t nbytes, const char *file, int line) {
848 void *ptr;
849 #ifdef MEMUSAGE
850 static struct descriptor *bp;
851 unsigned h;
852
853 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
854 pthread_mutex_lock(&memusage_mutex);
855 #endif
856 #endif
857
858 if (count <= 0) {
859 fprintf(stderr,"Failed attempt to calloc %zu x %zu bytes\n",count,nbytes);
860 if (file == NULL) {
861 RAISE(Mem_Failed);
862 } else {
863 Except_raise(&Mem_Failed, file, line);
864 }
865 }
866 assert(nbytes > 0);
867
868 ptr = calloc(count,nbytes);
869
870 #ifdef TRAP
871 if (ptr == trap_location) {
872 printf("Trap: Calloc of location %p by %s:%d\n",ptr,file,line);
873 }
874
875 if (startp > 0 && *trap_location != trap_contents) {
876 printf("Value changed at location %p. Old value is %p. New value is %p. Observed during calloc at %s:%d\n",
877 trap_location,trap_contents,*trap_location,file,line);
878 fflush(stdout);
879 trap_contents = * (void **) trap_location;
880 }
881 #endif
882
883 #ifdef MEMUSAGE
884 memusage_in += count*nbytes;
885 h = hash(ptr,htab);
886 bp = malloc(sizeof(*bp));
887 bp->link = htab[h];
888 bp->ptr = ptr;
889 bp->size = count*nbytes;
890 htab[h] = bp;
891 #endif
892
893 #ifdef MEMUSAGE
894 debug_heap(printf("%ld IN: Allocating %p to %p -- Calloc of %zu x %zu = %zu bytes in input pool requested from %s:%d\n",
895 memusage_in,ptr,(char *) ptr + count*nbytes-1,count,nbytes,count*nbytes,file,line));
896 #else
897 debug_heap(printf("Allocating %p to %p -- Calloc of %zu x %zu = %zu bytes in input pool requested from %s:%d\n",
898 ptr,(char *) ptr + count*nbytes-1,count,nbytes,count*nbytes,file,line));
899 #endif
900
901 if (ptr == NULL) {
902 fprintf(stderr,"Failed attempt to calloc %zu x %zu bytes\n",count,nbytes);
903 if (file == NULL) {
904 RAISE(Mem_Failed);
905 } else {
906 Except_raise(&Mem_Failed, file, line);
907 }
908 }
909
910 #ifdef MEMUSAGE
911 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
912 pthread_mutex_unlock(&memusage_mutex);
913 #endif
914 #endif
915
916 return ptr;
917 }
918
919 void *
Mem_calloc_out(size_t count,size_t nbytes,const char * file,int line)920 Mem_calloc_out (size_t count, size_t nbytes, const char *file, int line) {
921 void *ptr;
922 #ifdef MEMUSAGE
923 static struct descriptor *bp;
924 unsigned h;
925
926 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
927 pthread_mutex_lock(&memusage_mutex);
928 #endif
929 #endif
930
931 if (count <= 0) {
932 fprintf(stderr,"Failed attempt to calloc %zu x %zu bytes\n",count,nbytes);
933 if (file == NULL) {
934 RAISE(Mem_Failed);
935 } else {
936 Except_raise(&Mem_Failed, file, line);
937 }
938 }
939 assert(nbytes > 0);
940
941 ptr = calloc(count,nbytes);
942
943 #ifdef TRAP
944 if (ptr == trap_location) {
945 printf("Trap: Calloc of location %p by %s:%d\n",ptr,file,line);
946 }
947
948 if (startp > 0 && *trap_location != trap_contents) {
949 printf("Value changed at location %p. Old value is %p. New value is %p. Observed during calloc at %s:%d\n",
950 trap_location,trap_contents,*trap_location,file,line);
951 fflush(stdout);
952 trap_contents = * (void **) trap_location;
953 }
954 #endif
955
956 #ifdef MEMUSAGE
957 memusage_out += count*nbytes;
958 h = hash(ptr,htab);
959 bp = malloc(sizeof(*bp));
960 bp->link = htab[h];
961 bp->ptr = ptr;
962 bp->size = count*nbytes;
963 htab[h] = bp;
964 #endif
965
966 #ifdef MEMUSAGE
967 debug_heap(printf("%ld OUT: Allocating %p to %p -- Calloc of %zu x %zu = %zu bytes in output pool requested from %s:%d\n",
968 memusage_out,ptr,(char *) ptr + count*nbytes-1,count,nbytes,count*nbytes,file,line));
969 #else
970 debug_heap(printf("Allocating %p to %p -- Calloc of %zu x %zu = %zu bytes in output pool requested from %s:%d\n",
971 ptr,(char *) ptr + count*nbytes-1,count,nbytes,count*nbytes,file,line));
972 #endif
973
974 if (ptr == NULL) {
975 fprintf(stderr,"Failed attempt to calloc %zu x %zu bytes\n",count,nbytes);
976 if (file == NULL) {
977 RAISE(Mem_Failed);
978 } else {
979 Except_raise(&Mem_Failed, file, line);
980 }
981 }
982
983 #ifdef MEMUSAGE
984 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
985 pthread_mutex_unlock(&memusage_mutex);
986 #endif
987 #endif
988
989 return ptr;
990 }
991
992 void *
Mem_calloc_no_exception(size_t count,size_t nbytes,const char * file,int line)993 Mem_calloc_no_exception (size_t count, size_t nbytes, const char *file, int line) {
994 void *ptr;
995 #ifdef MEMUSAGE
996 static struct descriptor *bp;
997 unsigned h;
998
999 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1000 pthread_mutex_lock(&memusage_mutex);
1001 long int memusage_std_heap;
1002 char *threadname;
1003 #endif
1004 #endif
1005
1006 if (count <= 0) {
1007 fprintf(stderr,"Failed attempt to allocate %zu x %zu bytes\n",count,nbytes);
1008 if (file == NULL) {
1009 RAISE(Mem_Failed);
1010 } else {
1011 Except_raise(&Mem_Failed, file, line);
1012 }
1013 }
1014 assert(nbytes > 0);
1015
1016 ptr = calloc(count, nbytes);
1017
1018 #ifdef MEMUSAGE
1019 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1020 threadname = (char *) pthread_getspecific(key_threadname);
1021 memusage_std_heap = (long int) pthread_getspecific(key_memusage_std_heap);
1022 memusage_std_heap += count*nbytes;
1023 pthread_setspecific(key_memusage_std_heap,(void *) memusage_std_heap);
1024 #else
1025 memusage_std_heap += count*nbytes;
1026 #endif
1027 h = hash(ptr,htab);
1028 bp = malloc(sizeof(*bp));
1029 bp->link = htab[h];
1030 bp->ptr = ptr;
1031 bp->size = count*nbytes;
1032 htab[h] = bp;
1033 #endif
1034
1035 #ifdef MEMUSAGE
1036 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1037 pthread_mutex_unlock(&memusage_mutex);
1038 #endif
1039 #endif
1040
1041 return ptr;
1042 }
1043
1044 void
Mem_free(void * ptr,const char * file,int line)1045 Mem_free (void *ptr, const char *file, int line) {
1046 #ifdef MEMUSAGE
1047 struct descriptor *bp;
1048 size_t nbytes;
1049
1050 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1051 pthread_mutex_lock(&memusage_mutex);
1052 long int memusage_std_heap;
1053 char *threadname;
1054 #endif
1055 #endif
1056
1057 #ifdef TRAP
1058 if (ptr == trap_location) {
1059 printf("Trap: Location %p freed at %s:%d\n",ptr,file,line);
1060 }
1061 #endif
1062
1063 if (ptr) {
1064 #ifdef MEMUSAGE
1065 if ((bp = find(ptr)) == NULL) {
1066 Except_raise(&Mem_Failed, file, line);
1067 } else {
1068 nbytes = bp->size;
1069 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1070 threadname = (char *) pthread_getspecific(key_threadname);
1071 memusage_std_heap = (long int) pthread_getspecific(key_memusage_std_heap);
1072 memusage_std_heap -= nbytes;
1073 pthread_setspecific(key_memusage_std_heap,(void *) memusage_std_heap);
1074 #else
1075 memusage_std_heap -= nbytes;
1076 #endif
1077 free(bp);
1078 }
1079 #endif
1080
1081 #ifdef MEMUSAGE
1082 debug_heap(printf("%ld %s: Freeing %p in standard pool at %s:%d (%ld bytes)\n",
1083 memusage_std_heap,threadname,ptr,file,line,nbytes));
1084 #else
1085 debug_heap(printf("Freeing %p in standard pool at %s:%d\n",ptr,file,line));
1086 #endif
1087 free(ptr);
1088 }
1089
1090 #ifdef TRAP
1091 if (startp > 0 && *trap_location != trap_contents) {
1092 printf("Value changed at location %p. Old value was %p. New value is %p. Observed during free at %s:%d\n",
1093 trap_location,trap_contents,*trap_location,file,line);
1094 fflush(stdout);
1095 trap_contents = * (void **) trap_location;
1096 }
1097 #endif
1098
1099 #ifdef MEMUSAGE
1100 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1101 pthread_mutex_unlock(&memusage_mutex);
1102 #endif
1103 #endif
1104
1105 return;
1106 }
1107
1108
1109 void
Mem_free_keep(void * ptr,const char * file,int line)1110 Mem_free_keep (void *ptr, const char *file, int line) {
1111 #ifdef MEMUSAGE
1112 struct descriptor *bp;
1113 size_t nbytes;
1114
1115 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1116 pthread_mutex_lock(&memusage_mutex);
1117 long int memusage_keep;
1118 char *threadname;
1119 #endif
1120 #endif
1121
1122 #ifdef TRAP
1123 if (ptr == trap_location) {
1124 printf("Trap: Location %p freed at %s:%d\n",ptr,file,line);
1125 }
1126 #endif
1127
1128 if (ptr) {
1129 #ifdef MEMUSAGE
1130 if ((bp = find(ptr)) == NULL) {
1131 Except_raise(&Mem_Failed, file, line);
1132 } else {
1133 nbytes = bp->size;
1134 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1135 threadname = (char *) pthread_getspecific(key_threadname);
1136 memusage_keep = (long int) pthread_getspecific(key_memusage_keep);
1137 memusage_keep -= nbytes;
1138 pthread_setspecific(key_memusage_keep,(void *) memusage_keep);
1139 #else
1140 memusage_keep -= nbytes;
1141 #endif
1142 free(bp);
1143 }
1144 #endif
1145
1146 #ifdef MEMUSAGE
1147 debug_heap(printf("%ld %s-keep: Freeing %p in keep pool at %s:%d (%ld bytes)\n",
1148 memusage_keep,threadname,ptr,file,line,nbytes));
1149 #else
1150 debug_heap(printf("Freeing %p in keep pool at %s:%d\n",ptr,file,line));
1151 #endif
1152 free(ptr);
1153 }
1154
1155 #ifdef TRAP
1156 if (startp > 0 && *trap_location != trap_contents) {
1157 printf("Value changed at location %p. Old value was %p. New value is %p. Observed during free at %s:%d\n",
1158 trap_location,trap_contents,*trap_location,file,line);
1159 fflush(stdout);
1160 trap_contents = * (void **) trap_location;
1161 }
1162 #endif
1163
1164 #ifdef MEMUSAGE
1165 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1166 pthread_mutex_unlock(&memusage_mutex);
1167 #endif
1168 #endif
1169
1170 return;
1171 }
1172
1173
1174 void
Mem_free_in(void * ptr,const char * file,int line)1175 Mem_free_in (void *ptr, const char *file, int line) {
1176 #ifdef MEMUSAGE
1177 struct descriptor *bp;
1178 size_t nbytes;
1179
1180 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1181 pthread_mutex_lock(&memusage_mutex);
1182 #endif
1183 #endif
1184
1185 #ifdef TRAP
1186 if (ptr == trap_location) {
1187 printf("Trap: Location %p freed at %s:%d\n",ptr,file,line);
1188 }
1189 #endif
1190
1191 if (ptr) {
1192 #ifdef MEMUSAGE
1193 if ((bp = find(ptr)) == NULL) {
1194 Except_raise(&Mem_Failed, file, line);
1195 } else {
1196 nbytes = bp->size;
1197 memusage_in -= nbytes;
1198 free(bp);
1199 }
1200 #endif
1201
1202 #ifdef MEMUSAGE
1203 debug_heap(printf("%ld IN: Freeing %p in input pool at %s:%d (%ld bytes)\n",
1204 memusage_in,ptr,file,line,nbytes));
1205 #else
1206 debug_heap(printf("Freeing %p in input pool at %s:%d\n",ptr,file,line));
1207 #endif
1208 free(ptr);
1209 }
1210
1211 #ifdef TRAP
1212 if (startp > 0 && *trap_location != trap_contents) {
1213 printf("Value changed at location %p. Old value was %p. New value is %p. Observed during free at %s:%d\n",
1214 trap_location,trap_contents,*trap_location,file,line);
1215 fflush(stdout);
1216 trap_contents = * (void **) trap_location;
1217 }
1218 #endif
1219
1220 #ifdef MEMUSAGE
1221 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1222 pthread_mutex_unlock(&memusage_mutex);
1223 #endif
1224 #endif
1225
1226 return;
1227 }
1228
1229 void
Mem_free_out(void * ptr,const char * file,int line)1230 Mem_free_out (void *ptr, const char *file, int line) {
1231 #ifdef MEMUSAGE
1232 struct descriptor *bp;
1233 size_t nbytes;
1234
1235 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1236 pthread_mutex_lock(&memusage_mutex);
1237 #endif
1238 #endif
1239
1240 #ifdef TRAP
1241 if (ptr == trap_location) {
1242 printf("Trap: Location %p freed at %s:%d\n",ptr,file,line);
1243 }
1244 #endif
1245
1246 if (ptr) {
1247 #ifdef MEMUSAGE
1248 if ((bp = find(ptr)) == NULL) {
1249 Except_raise(&Mem_Failed, file, line);
1250 } else {
1251 nbytes = bp->size;
1252 memusage_out -= nbytes;
1253 free(bp);
1254 }
1255 #endif
1256
1257 #ifdef MEMUSAGE
1258 debug_heap(printf("%ld OUT: Freeing %p in output pool at %s:%d (%ld bytes)\n",
1259 memusage_out,ptr,file,line,nbytes));
1260 #else
1261 debug_heap(printf("Freeing %p in output pool at %s:%d\n",ptr,file,line));
1262 #endif
1263 free(ptr);
1264 }
1265
1266 #ifdef TRAP
1267 if (startp > 0 && *trap_location != trap_contents) {
1268 printf("Value changed at location %p. Old value was %p. New value is %p. Observed during free at %s:%d\n",
1269 trap_location,trap_contents,*trap_location,file,line);
1270 fflush(stdout);
1271 trap_contents = * (void **) trap_location;
1272 }
1273 #endif
1274
1275 #ifdef MEMUSAGE
1276 #if !defined(USE_MPI) && defined(HAVE_PTHREAD)
1277 pthread_mutex_unlock(&memusage_mutex);
1278 #endif
1279 #endif
1280
1281 return;
1282 }
1283
1284
1285 void *
Mem_resize(void * ptr,size_t nbytes,const char * file,int line)1286 Mem_resize (void *ptr, size_t nbytes, const char *file, int line) {
1287 assert(ptr);
1288 assert(nbytes > 0);
1289 ptr = realloc(ptr, nbytes);
1290 if (ptr == NULL) {
1291 fprintf(stderr,"Failed attempt to realloc %zu bytes\n",nbytes);
1292 if (file == NULL) {
1293 RAISE(Mem_Failed);
1294 } else {
1295 Except_raise(&Mem_Failed, file, line);
1296 }
1297 }
1298 return ptr;
1299 }
1300