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: }