Actual source code: bss_malloc.c

  1: /*$Id: bss_malloc.c,v 1.5 2001/04/12 21:04:14 balay Exp $*/
  2: /********************************bss_malloc.c**********************************
  3: SPARSE GATHER-SCATTER PACKAGE: bss_malloc bss_malloc ivec error comm gs queue

  5: Author: Henry M. Tufo III

  7: e-mail: hmt@cs.brown.edu

  9: snail-mail:
 10: Division of Applied Mathematics
 11: Brown University
 12: Providence, RI 02912

 14: Last Modification: 
 15: 11.21.97
 16: *********************************bss_malloc.c*********************************/

 18: /********************************bss_malloc.c**********************************
 19: File Description:
 20: -----------------

 22: *********************************bss_malloc.c*********************************/
 23: #include <stdio.h>

 25: #if   defined NXSRC
 26: #ifndef DELTA
 27: #include <nx.h>
 28: #endif

 30: #elif defined MPISRC
 31: #include <mpi.h>
 32: #endif

 34: #include "petscconf.h"
 35: #if defined(PETSC_HAVE_STDLIB_H)
 36: #include <stdlib.h>
 37: #endif
 38: #if defined(PETSC_HAVE_MALLOC_H)
 39: #include <malloc.h>
 40: #endif


 43:  #include const.h
 44:  #include types.h
 45:  #include error.h
 46: #include "bss_malloc.h"


 49: #ifdef NXLIB
 50: #include <nxmalloc.h>
 51: #endif

 53: #if   defined NXSRC
 54: #ifndef DELTA
 55: #include <nx.h>
 56: #endif
 57:  #include comm.h

 59: #elif defined MPISRC
 60: #include <mpi.h>
 61:  #include comm.h

 63: #else
 64: static int my_id=0;


 67: #endif


 70: /* mission critical */
 71: /* number of bytes given to malloc */
 72: #ifdef MYMALLOC
 73: #define PERM_MALLOC_BUF  65536 /* 16777216 8388608 4194304 31072 16384 */
 74: #define BSS_MALLOC_BUF   65536 /* 524288  1048576 4194304 65536 */
 75: #endif

 77: /* malloc stats and space for bss and perm flavors */
 78: static int    perm_req       = 0;
 79: static int    num_perm_req   = 0;
 80: static int    num_perm_frees = 0;
 81: #ifdef MYMALLOC
 82: static double perm_buf[PERM_MALLOC_BUF/sizeof(double)];
 83: static double *perm_top = perm_buf;
 84: #endif

 86: static int    bss_req        = 0;
 87: static int    num_bss_req    = 0;
 88: static int    num_bss_frees  = 0;
 89: #ifdef MYMALLOC
 90: static double bss_buf[BSS_MALLOC_BUF/sizeof(double)];
 91: static double *bss_top = bss_buf;
 92: #endif



 96: /********************************bss_malloc.c**********************************
 97: Function: perm_init()

 99: Input : 
100: Output: 
101: Return: 
102: Description: 

104: Add ability to pass in later ... for Fortran interface

106: Space to be passed later should be double aligned!!!
107: *********************************bss_malloc.c*********************************/
108: void 
109: perm_init(void)
110: {
111:   perm_req = 0;
112:   num_perm_req = 0;
113:   num_perm_frees = 0;

115: #ifdef MYMALLOC
116:   perm_top = perm_buf;
117: #endif
118: }



122: /********************************bss_malloc.c**********************************
123: Function: perm_malloc()

125: Input : 
126: Output: 
127: Return: 
128: Description: 
129: *********************************bss_malloc.c*********************************/
130: void *
131: perm_malloc(size_t size)
132: {
133:   void *tmp;
134: #ifdef MYMALLOC  
135:   double *space;
136:   int num_blocks;
137: #endif


140:   if (!size)
141:     {
142: #ifdef DEBUG
143:       error_msg_warning("perm_malloc() :: size=0!\n");
144: #endif
145:       return(NULL);
146:     }

148: #if defined MYMALLOC
149:   if (size%sizeof(double))
150:     {num_blocks = size/sizeof(double) + 1;}
151:   else
152:     {num_blocks = size/sizeof(double);}
153: 
154:   if (num_blocks < (PERM_MALLOC_BUF/sizeof(double) - (perm_top - perm_buf)))
155:     {
156:       space = perm_top;
157:       perm_top += num_blocks;
158:       perm_req+=size;
159:       num_perm_req++;
160:       return(space);
161:     }

163: #else 
164:   if ((tmp = (void *) malloc(size)))
165:     {
166:       perm_req+=size;
167:       num_perm_req++;
168:       return(tmp);
169:     }
170: #endif

172:   error_msg_fatal("perm_malloc() :: can't satisfy %d byte request",size);
173:   return(NULL);
174: }



178: /********************************bss_malloc.c**********************************
179: Function: perm_free()

181: Input : 
182: Output: 
183: Return: 
184: Description: 
185: *********************************bss_malloc.c*********************************/
186: void 
187: perm_free(void *ptr)
188: {
189:   if (ptr)
190:     {
191:       num_perm_frees--;

193: #ifdef MYMALLOC
194:       return;
195: #else
196:       free((void *) ptr);
197: #endif
198:     }
199:   else
200:     {error_msg_warning("perm_free() :: nothing to free!!!");}
201: }



205: /********************************bss_malloc.c**********************************
206: Function: perm_stats()

208: Input : 
209: Output: 
210: Return: 
211: Description: 
212: *********************************bss_malloc.c*********************************/
213: void 
214: perm_stats(void)
215: {
216: #if defined NXSRC
217:   long min, max, ave, work;
218: 

220:   min = max = ave = perm_req;
221:   gisum(&ave,1,&work);
222:   ave /= num_nodes;

224:   gilow(&min,1,&work);
225:   gihigh(&max,1,&work);

227:   if (!my_id)
228:     {
229:       printf("%d :: perm_malloc stats:\n",my_id);
230:       printf("%d :: perm_req min = %d\n",my_id,(int)min);
231:       printf("%d :: perm_req ave = %d\n",my_id,(int)ave);
232:       printf("%d :: perm_req max = %d\n",my_id,(int)max);
233:     }

235: #elif defined MPISRC
236:   int min, max, ave, work;
237: 

239:   min = max = ave = perm_req;
240:   MPI_Allreduce (&ave, &work, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
241:   ave = work/num_nodes;

243:   /* Maybe needs a synchronization here to ensure work is not corrupted */
244:   MPI_Allreduce (&min, &work, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
245:   min = work;

247:   /* Maybe needs a synchronization here to ensure work is not corrupted */
248:   MPI_Allreduce (&max, &work, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
249:   max = work;
250: #if 0
251:   if (!my_id)
252:     {
253:       printf("%d :: perm_malloc stats:\n",my_id);
254:       printf("%d :: perm_req min = %d\n",my_id,min);
255:       printf("%d :: perm_req ave = %d\n",my_id,ave);
256:       printf("%d :: perm_req max = %d\n",my_id,max);
257:     }
258: #endif
259: #else
260:   if (!my_id)
261:     {
262:       printf("%d :: perm_malloc stats:\n",my_id);
263:       printf("%d :: perm_req     = %d\n",my_id,perm_req);
264:     }
265: #endif

267:   /* check to make sure that malloc and free calls are balanced */
268: #ifdef DEBUG
269:   if (num_perm_frees+num_perm_req)
270:     {
271:       printf("%d :: perm # frees = %d\n",my_id,-1*num_perm_frees);
272:       printf("%d :: perm # calls = %d\n",my_id,num_perm_req);
273:     }
274: #endif


277: #ifdef DEBUG
278:   fflush(stdout);
279: #endif
280: }



284: /********************************bss_malloc.c**********************************
285: Function: perm_frees()

287: Input : 
288: Output: 
289: Return: 
290: Description: 
291: *********************************bss_malloc.c*********************************/
292: int
293: perm_frees(void)
294: {
295:   return(-num_perm_frees);
296: }



300: /********************************bss_malloc.c**********************************
301: Function: perm_calls()

303: Input : 
304: Output: 
305: Return: 
306: Description: 
307: *********************************bss_malloc.c*********************************/
308: int
309: perm_calls(void)
310: {
311:   return(num_perm_req);
312: }



316: /********************************bss_malloc.c**********************************
317: Function: bss_init()

319: Input : 
320: Output: 
321: Return: 
322: Description: 

324: Add ability to pass in later ...

326: Space to be passed later should be double aligned!!!
327: *********************************bss_malloc.c*********************************/
328: void 
329: bss_init(void)
330: {
331:   bss_req = 0;
332:   num_bss_req = 0;
333:   num_bss_frees = 0;

335: #ifdef MYMALLOC
336:   bss_top = bss_buf;
337: #endif
338: }



342: /********************************bss_malloc.c**********************************
343: Function: bss_malloc()

345: Input : 
346: Output: 
347: Return: 
348: Description: 
349: *********************************bss_malloc.c*********************************/
350: void *
351: bss_malloc(size_t size)
352: {
353:   void *tmp;
354: #ifdef MYMALLOC  
355:   double *space;
356:   int num_blocks;
357: #endif


360:   if (!size)
361:     {
362: #ifdef DEBUG
363:       error_msg_warning("bss_malloc() :: size=0!\n");
364: #endif
365:       return(NULL);
366:     }

368: #ifdef MYMALLOC
369:   if (size%sizeof(double))
370:     {num_blocks = size/sizeof(double) + 1;}
371:   else
372:     {num_blocks = size/sizeof(double);}

374:   if (num_blocks < (BSS_MALLOC_BUF/sizeof(double) - (bss_top - bss_buf)))
375:     {
376:       space = bss_top;
377:       bss_top += num_blocks;
378:       bss_req+=size;
379:       num_bss_req++;
380:       return(space);
381:     }

383: #else
384:   if ((tmp = (void *) malloc(size)))
385:     {
386:       bss_req+=size;
387:       num_bss_req++;
388:       return(tmp);
389:     }
390: #endif

392:   error_msg_fatal("bss_malloc() :: can't satisfy %d request",size);
393:   return(NULL);
394: }



398: /********************************bss_malloc.c**********************************
399: Function: bss_free()

401: Input : 
402: Output: 
403: Return: 
404: Description: 
405: *********************************bss_malloc.c*********************************/
406: void 
407: bss_free(void *ptr)
408: {
409:   if (ptr)
410:     {
411:       num_bss_frees--;

413: #ifdef MYMALLOC
414:       return;
415: #else
416:       free((void *) ptr);
417: #endif
418:     }
419:   else
420:     {error_msg_warning("bss_free() :: nothing to free!!!");}
421: }



425: /********************************bss_malloc.c**********************************
426: Function: bss_stats()

428: Input : 
429: Output: 
430: Return: 
431: Description: 
432: *********************************bss_malloc.c*********************************/
433: void 
434: bss_stats(void)
435: {
436: #if defined NXSRC
437:   long min, max, ave, work;


440:   min = max = ave = bss_req;
441:   gisum(&ave,1,&work);
442:   ave /= num_nodes;
443:   gilow(&min,1,&work);
444:   gihigh(&max,1,&work);

446:   if (!my_id)
447:     {
448:       printf("%d :: bss_malloc stats:\n",my_id);
449:       printf("%d :: bss_req min   = %d\n",my_id,(int)min);
450:       printf("%d :: bss_req ave   = %d\n",my_id,(int)ave);
451:       printf("%d :: bss_req max   = %d\n",my_id,(int)max);
452:     }

454: #elif defined MPISRC
455:   int min, max, ave, work;


458:   min = max = ave = bss_req;
459:   MPI_Allreduce (&ave, &work, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
460:   ave = work/num_nodes;

462:   /* Maybe needs a synchronization here to ensure work is not corrupted */
463:   MPI_Allreduce (&min, &work, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
464:   min = work;

466:   /* Maybe needs a synchronization here to ensure work is not corrupted */
467:   MPI_Allreduce (&max, &work, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
468:   max = work;

470: #if 0
471:   if (!my_id)
472:     {
473:       printf("%d :: bss_malloc stats:\n",my_id);
474:       printf("%d :: bss_req min   = %d\n",my_id,min);
475:       printf("%d :: bss_req ave   = %d\n",my_id,ave);
476:       printf("%d :: bss_req max   = %d\n",my_id,max);
477:     }
478: #endif

480: #else
481:   if (!my_id)
482:     {
483:       printf("%d :: bss_malloc stats:\n",my_id);
484:       printf("%d :: bss_req       = %d\n",my_id,bss_req);
485:     }

487: #endif  

489: #ifdef DEBUG
490:   if (num_bss_frees+num_bss_req)
491:     {
492:       printf("%d :: bss # frees   = %d\n",my_id,-1*num_bss_frees);
493:       printf("%d :: bss # calls   = %d\n",my_id,num_bss_req);
494:     }
495: #endif

497: #ifdef DEBUG
498:   fflush(stdout);
499: #endif
500: }



504: /********************************bss_malloc.c**********************************
505: Function: bss_frees()

507: Input : 
508: Output: 
509: Return: 
510: Description: 
511: *********************************bss_malloc.c*********************************/
512: int
513: bss_frees(void)
514: {
515:   return(-num_bss_frees);
516: }



520: /********************************bss_malloc.c**********************************
521: Function: bss_calls()

523: Input : 
524: Output: 
525: Return: 
526: Description: 
527: *********************************bss_malloc.c*********************************/
528: int
529: bss_calls(void)
530: {
531:   return(num_bss_req);
532: }