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