Actual source code: bss_malloc.c

  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 petsc.h
 24: #if defined(PETSC_HAVE_STDLIB_H)
 25: #include <stdlib.h>
 26: #endif
 27: #if defined(PETSC_HAVE_MALLOC_H)
 28: #include <malloc.h>
 29: #endif


 32:  #include const.h
 33:  #include types.h
 34:  #include error.h
 35: #include "bss_malloc.h"
 36:  #include comm.h

 38: /* mission critical */
 39: /* number of bytes given to malloc */
 40: #ifdef MYMALLOC
 41: #define PERM_MALLOC_BUF  65536 /* 16777216 8388608 4194304 31072 16384 */
 42: #define BSS_MALLOC_BUF   65536 /* 524288  1048576 4194304 65536 */
 43: #endif

 45: /* malloc stats and space for bss and perm flavors */
 46: static int    perm_req       = 0;
 47: static int    num_perm_req   = 0;
 48: static int    num_perm_frees = 0;
 49: #ifdef MYMALLOC
 50: static double perm_buf[PERM_MALLOC_BUF/sizeof(double)];
 51: static double *perm_top = perm_buf;
 52: #endif

 54: static int    bss_req        = 0;
 55: static int    num_bss_req    = 0;
 56: static int    num_bss_frees  = 0;
 57: #ifdef MYMALLOC
 58: static double bss_buf[BSS_MALLOC_BUF/sizeof(double)];
 59: static double *bss_top = bss_buf;
 60: #endif



 64: /********************************bss_malloc.c**********************************
 65: Function: perm_init()

 67: Input : 
 68: Output: 
 69: Return: 
 70: Description: 

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

 74: Space to be passed later should be double aligned!!!
 75: *********************************bss_malloc.c*********************************/
 76: void 
 77: perm_init(void)
 78: {
 79:   perm_req = 0;
 80:   num_perm_req = 0;
 81:   num_perm_frees = 0;

 83: #ifdef MYMALLOC
 84:   perm_top = perm_buf;
 85: #endif
 86: }



 90: /********************************bss_malloc.c**********************************
 91: Function: perm_malloc()

 93: Input : 
 94: Output: 
 95: Return: 
 96: Description: 
 97: *********************************bss_malloc.c*********************************/
 98: void *
 99: perm_malloc(size_t size)
100: {
101:   void *tmp;
102: #ifdef MYMALLOC  
103:   double *space;
104:   int num_blocks;
105: #endif


108:   if (!size)
109:     {
110: #ifdef DEBUG
111:       error_msg_warning("perm_malloc() :: size=0!\n");
112: #endif
113:       return(NULL);
114:     }

116: #if defined MYMALLOC
117:   if (size%sizeof(double))
118:     {num_blocks = size/sizeof(double) + 1;}
119:   else
120:     {num_blocks = size/sizeof(double);}
121: 
122:   if (num_blocks < (PERM_MALLOC_BUF/sizeof(double) - (perm_top - perm_buf)))
123:     {
124:       space = perm_top;
125:       perm_top += num_blocks;
126:       perm_req+=size;
127:       num_perm_req++;
128:       return(space);
129:     }

131: #else 
132:   if ((tmp = (void*) malloc(size)))
133:     {
134:       perm_req+=size;
135:       num_perm_req++;
136:       return(tmp);
137:     }
138: #endif

140:   error_msg_fatal("perm_malloc() :: can't satisfy %D byte request",size);
141:   return(NULL);
142: }



146: /********************************bss_malloc.c**********************************
147: Function: perm_free()

149: Input : 
150: Output: 
151: Return: 
152: Description: 
153: *********************************bss_malloc.c*********************************/
154: void 
155: perm_free(void *ptr)
156: {
157:   if (ptr)
158:     {
159:       num_perm_frees--;

161: #ifdef MYMALLOC
162:       return;
163: #else
164:       free((void*) ptr);
165: #endif
166:     }
167:   else
168:     {error_msg_warning("perm_free() :: nothing to free!!!");}
169: }



173: /********************************bss_malloc.c**********************************
174: Function: perm_stats()

176: Input : 
177: Output: 
178: Return: 
179: Description: 
180: *********************************bss_malloc.c*********************************/
181: void 
182: perm_stats(void)
183: {
184:   int min, max, ave, work;
185: 

187:   min = max = ave = perm_req;
188:   MPI_Allreduce (&ave, &work, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
189:   ave = work/num_nodes;

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

195:   /* Maybe needs a synchronization here to ensure work is not corrupted */
196:   MPI_Allreduce (&max, &work, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
197:   max = work;
198: #if 0
199:   if (!my_id)
200:     {
201:       printf("%d :: perm_malloc stats:\n",my_id);
202:       printf("%d :: perm_req min = %D\n",my_id,min);
203:       printf("%d :: perm_req ave = %D\n",my_id,ave);
204:       printf("%d :: perm_req max = %D\n",my_id,max);
205:     }
206: #endif

208:   /* check to make sure that malloc and free calls are balanced */
209: #ifdef DEBUG
210:   if (num_perm_frees+num_perm_req)
211:     {
212:       printf("%d :: perm # frees = %D\n",my_id,-1*num_perm_frees);
213:       printf("%d :: perm # calls = %D\n",my_id,num_perm_req);
214:     }
215: #endif


218: #ifdef DEBUG
219:   fflush(stdout);
220: #endif
221: }



225: /********************************bss_malloc.c**********************************
226: Function: perm_frees()

228: Input : 
229: Output: 
230: Return: 
231: Description: 
232: *********************************bss_malloc.c*********************************/
233: int
234: perm_frees(void)
235: {
236:   return(-num_perm_frees);
237: }



241: /********************************bss_malloc.c**********************************
242: Function: perm_calls()

244: Input : 
245: Output: 
246: Return: 
247: Description: 
248: *********************************bss_malloc.c*********************************/
249: int
250: perm_calls(void)
251: {
252:   return(num_perm_req);
253: }



257: /********************************bss_malloc.c**********************************
258: Function: bss_init()

260: Input : 
261: Output: 
262: Return: 
263: Description: 

265: Add ability to pass in later ...

267: Space to be passed later should be double aligned!!!
268: *********************************bss_malloc.c*********************************/
269: void 
270: bss_init(void)
271: {
272:   bss_req = 0;
273:   num_bss_req = 0;
274:   num_bss_frees = 0;

276: #ifdef MYMALLOC
277:   bss_top = bss_buf;
278: #endif
279: }



283: /********************************bss_malloc.c**********************************
284: Function: bss_malloc()

286: Input : 
287: Output: 
288: Return: 
289: Description: 
290: *********************************bss_malloc.c*********************************/
291: void *
292: bss_malloc(size_t size)
293: {
294:   void *tmp;
295: #ifdef MYMALLOC  
296:   double *space;
297:   int num_blocks;
298: #endif


301:   if (!size)
302:     {
303: #ifdef DEBUG
304:       error_msg_warning("bss_malloc() :: size=0!\n");
305: #endif
306:       return(NULL);
307:     }

309: #ifdef MYMALLOC
310:   if (size%sizeof(double))
311:     {num_blocks = size/sizeof(double) + 1;}
312:   else
313:     {num_blocks = size/sizeof(double);}

315:   if (num_blocks < (BSS_MALLOC_BUF/sizeof(double) - (bss_top - bss_buf)))
316:     {
317:       space = bss_top;
318:       bss_top += num_blocks;
319:       bss_req+=size;
320:       num_bss_req++;
321:       return(space);
322:     }

324: #else
325:   if ((tmp = (void*) malloc(size)))
326:     {
327:       bss_req+=size;
328:       num_bss_req++;
329:       return(tmp);
330:     }
331: #endif

333:   error_msg_fatal("bss_malloc() :: can't satisfy %D request",size);
334:   return(NULL);
335: }



339: /********************************bss_malloc.c**********************************
340: Function: bss_free()

342: Input : 
343: Output: 
344: Return: 
345: Description: 
346: *********************************bss_malloc.c*********************************/
347: void 
348: bss_free(void *ptr)
349: {
350:   if (ptr)
351:     {
352:       num_bss_frees--;

354: #ifdef MYMALLOC
355:       return;
356: #else
357:       free((void*) ptr);
358: #endif
359:     }
360:   else
361:     {error_msg_warning("bss_free() :: nothing to free!!!");}
362: }



366: /********************************bss_malloc.c**********************************
367: Function: bss_stats()

369: Input : 
370: Output: 
371: Return: 
372: Description: 
373: *********************************bss_malloc.c*********************************/
374: void 
375: bss_stats(void)
376: {
377:   int min, max, ave, work;


380:   min = max = ave = bss_req;
381:   MPI_Allreduce (&ave, &work, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
382:   ave = work/num_nodes;

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

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

392: #if 0
393:   if (!my_id)
394:     {
395:       printf("%d :: bss_malloc stats:\n",my_id);
396:       printf("%d :: bss_req min   = %D\n",my_id,min);
397:       printf("%d :: bss_req ave   = %D\n",my_id,ave);
398:       printf("%d :: bss_req max   = %D\n",my_id,max);
399:     }
400: #endif

402: #ifdef DEBUG
403:   if (num_bss_frees+num_bss_req)
404:     {
405:       printf("%d :: bss # frees   = %D\n",my_id,-1*num_bss_frees);
406:       printf("%d :: bss # calls   = %D\n",my_id,num_bss_req);
407:     }
408: #endif

410: #ifdef DEBUG
411:   fflush(stdout);
412: #endif
413: }



417: /********************************bss_malloc.c**********************************
418: Function: bss_frees()

420: Input : 
421: Output: 
422: Return: 
423: Description: 
424: *********************************bss_malloc.c*********************************/
425: int
426: bss_frees(void)
427: {
428:   return(-num_bss_frees);
429: }



433: /********************************bss_malloc.c**********************************
434: Function: bss_calls()

436: Input : 
437: Output: 
438: Return: 
439: Description: 
440: *********************************bss_malloc.c*********************************/
441: int
442: bss_calls(void)
443: {
444:   return(num_bss_req);
445: }