Actual source code: mal.c
1: /*$Id: mal.c,v 1.57 2001/08/07 03:02:00 balay Exp $*/
2: /*
3: Code that allows a user to dictate what malloc() PETSc uses.
4: */
5: #include petsc.h
6: #if defined(PETSC_HAVE_STDLIB_H)
7: #include <stdlib.h>
8: #endif
9: #if defined(PETSC_HAVE_MALLOC_H)
10: #include <malloc.h>
11: #endif
12: #include "petscfix.h"
15: /*
16: We want to make sure that all mallocs of double or complex numbers are complex aligned.
17: 1) on systems with memalign() we call that routine to get an aligned memory location
18: 2) on systems without memalign() we
19: - allocate one sizeof(PetscScalar) extra space
20: - we shift the pointer up slightly if needed to get PetscScalar aligned
21: - if shifted we store at ptr[-1] the amount of shift (plus a cookie)
22: */
23: #define SHIFT_COOKIE 456123
25: /* need to use 16 and 8 below instead of sizeof() cause #if cannot handle sizeof() */
26: #if !defined(PETSC_MEMALIGN)
27: # if defined(PETSC_USE_COMPLEX)
28: # define PETSC_MEMALIGN 16
29: # else
30: # define PETSC_MEMALIGN 8
31: # endif
32: #endif
34: int PetscMallocAlign(int mem,int line,char *func,char *file,char *dir,void** result)
35: {
36: #if defined(PETSC_HAVE_DOUBLE_ALIGN_MALLOC) && (PETSC_MEMALIGN == 8)
37: *result = malloc(mem);
38: #elif defined(PETSC_HAVE_MEMALIGN)
39: *result = memalign(PETSC_MEMALIGN,mem);
40: #else
41: {
42: int *ptr,shift;
43: /*
44: malloc space for two extra chunks and shift ptr 1 + enough to get it PetscScalar aligned
45: */
46: ptr = (int*)malloc(mem + 2*PETSC_MEMALIGN);
47: if (ptr) {
48: shift = (int)(((unsigned long) ptr) % PETSC_MEMALIGN);
49: shift = (2*PETSC_MEMALIGN - shift)/sizeof(int);
50: ptr += shift;
51: ptr[-1] = shift + SHIFT_COOKIE ;
52: *result = (void*)ptr;
53: } else {
54: *result = 0;
55: }
56: }
57: #endif
58: if (!*result) SETERRQ1(PETSC_ERR_MEM,"Memory requested %d",mem);
59: return 0;
60: }
62: int PetscFreeAlign(void *ptr,int line,char *func,char *file,char *dir)
63: {
64: int 0;
66: #if (!(defined(PETSC_HAVE_DOUBLE_ALIGN_MALLOC) && (PETSC_MEMALIGN == 8)) && !defined(PETSC_HAVE_MEMALIGN))
67: int shift;
68: /*
69: Previous int tells us how many ints the pointer has been shifted from
70: the original address provided by the system malloc().
71: */
72: shift = ((int *)ptr)[-1] - SHIFT_COOKIE;
73: if (shift > PETSC_MEMALIGN-1) return PetscError(line,func,file,dir,1,1,"Likely memory corruption in heap");
74: ptr = (void*)(((int*)ptr) - shift);
75: #endif
77: #if defined(PETSC_HAVE_FREE_RETURN_INT)
78: free(ptr);
79: if (ierr) {
80: return PetscError(line,func,file,dir,1,1,"System free returned error %dn",ierr);
81: }
82: #else
83: free(ptr);
84: #endif
85: return ierr;
86: }
88: /*
89: We never use the system free directly because on many machines it
90: does not return an error code.
91: */
92: int PetscFreeDefault(void *ptr,int line,char *func,char *file,char *dir)
93: {
94: #if defined(PETSC_HAVE_FREE_RETURN_INT)
95: int free(ptr);
96: if (ierr) {
97: return PetscError(line,func,file,dir,1,1,"System free returned error %dn",ierr);
98: }
99: #else
100: free(ptr);
101: #endif
102: return 0;
103: }
105: int (*PetscTrMalloc)(int,int,char*,char*,char*,void**) = PetscMallocAlign;
106: int (*PetscTrFree)(void *,int,char*,char *,char*) = PetscFreeAlign;
108: PetscTruth petscsetmallocvisited = PETSC_FALSE;
110: /*@C
111: PetscSetMalloc - Sets the routines used to do mallocs and frees.
112: This routine MUST be called before PetscInitialize() and may be
113: called only once.
115: Not Collective
117: Input Parameters:
118: + malloc - the malloc routine
119: - free - the free routine
121: Level: developer
123: Concepts: malloc
124: Concepts: memory^allocation
126: @*/
127: int PetscSetMalloc(int (*imalloc)(int,int,char*,char*,char*,void**),
128: int (*ifree)(void*,int,char*,char*,char*))
129: {
131: if (petscsetmallocvisited) SETERRQ(PETSC_ERR_SUP,"cannot call multiple times");
132: PetscTrMalloc = imalloc;
133: PetscTrFree = ifree;
134: petscsetmallocvisited = PETSC_TRUE;
135: return(0);
136: }
138: /*@C
139: PetscClearMalloc - Resets the routines used to do mallocs and frees to the
140: defaults.
142: Not Collective
144: Level: developer
146: Notes:
147: In general one should never run a PETSc program with different malloc() and
148: free() settings for different parts; this is because one NEVER wants to
149: free() an address that was malloced by a different memory management system
151: @*/
152: int PetscClearMalloc(void)
153: {
155: PetscTrMalloc = PetscMallocAlign;
156: PetscTrFree = PetscFreeAlign;
157: petscsetmallocvisited = PETSC_FALSE;
158: return(0);
159: }