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