IFPACK  Development
 All Classes Namespaces Files Functions Variables Enumerations Friends Pages
Mem_dh.c
1 /*@HEADER
2 // ***********************************************************************
3 //
4 // Ifpack: Object-Oriented Algebraic Preconditioner Package
5 // Copyright (2002) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 //@HEADER
41 */
42 
43 #include "Parser_dh.h"
44 #include "Mem_dh.h"
45 
46 /* TODO: error checking is not complete; memRecord_dh need to
47  be done in Mem_dhMalloc() and Mem_dhFree()l
48 */
49 
50 
51  /* a memRecord_dh is pre and post-pended to every
52  * piece of memory obtained by calling MALLOC_DH
53  */
54 typedef struct
55 {
56  double size;
57  double cookie;
58 } memRecord_dh;
59 
60 struct _mem_dh
61 {
62  double maxMem; /* max allocated at any point in time */
63  double curMem; /* total currently allocated */
64  double totalMem; /* total cumulative malloced */
65  double mallocCount; /* number of times mem_dh->malloc has been called. */
66  double freeCount; /* number of times mem_dh->free has been called. */
67 };
68 
69 
70 #undef __FUNC__
71 #define __FUNC__ "Mem_dhCreate"
72 void
73 Mem_dhCreate (Mem_dh * m)
74 {
75  START_FUNC_DH
76  struct _mem_dh *tmp =
77  (struct _mem_dh *) PRIVATE_MALLOC (sizeof (struct _mem_dh));
78  CHECK_V_ERROR;
79  *m = tmp;
80  tmp->maxMem = 0.0;
81  tmp->curMem = 0.0;
82  tmp->totalMem = 0.0;
83  tmp->mallocCount = 0.0;
84  tmp->freeCount = 0.0;
85 END_FUNC_DH}
86 
87 
88 #undef __FUNC__
89 #define __FUNC__ "Mem_dhDestroy"
90 void
91 Mem_dhDestroy (Mem_dh m)
92 {
93  START_FUNC_DH if (Parser_dhHasSwitch (parser_dh, "-eu_mem"))
94  {
95  Mem_dhPrint (m, stdout, false);
96  CHECK_V_ERROR;
97  }
98 
99  PRIVATE_FREE (m);
100 END_FUNC_DH}
101 
102 
103 #undef __FUNC__
104 #define __FUNC__ "Mem_dhMalloc"
105 void *
106 Mem_dhMalloc (Mem_dh m, size_t size)
107 {
108  START_FUNC_DH_2 void *retval;
109  memRecord_dh *tmp;
110  size_t s = size + 2 * sizeof (memRecord_dh);
111  void *address;
112 
113  address = PRIVATE_MALLOC (s);
114 
115  if (address == NULL)
116  {
117  sprintf (msgBuf_dh,
118  "PRIVATE_MALLOC failed; totalMem = %g; requested additional = %i",
119  m->totalMem, (int) s);
120  SET_ERROR (NULL, msgBuf_dh);
121  }
122 
123  retval = (char *) address + sizeof (memRecord_dh);
124 
125  /* we prepend and postpend a private record to the
126  * requested chunk of memory; this permits tracking the
127  * sizes of freed memory, along with other rudimentary
128  * error checking. This is modeled after the PETSc code.
129  */
130  tmp = (memRecord_dh *) address;
131  tmp->size = (double) s;
132 
133  m->mallocCount += 1;
134  m->totalMem += (double) s;
135  m->curMem += (double) s;
136  m->maxMem = MAX (m->maxMem, m->curMem);
137 
138 END_FUNC_VAL_2 (retval)}
139 
140 
141 #undef __FUNC__
142 #define __FUNC__ "Mem_dhFree"
143 void
144 Mem_dhFree (Mem_dh m, void *ptr)
145 {
146  START_FUNC_DH_2 double size;
147  char *tmp = (char *) ptr;
148  memRecord_dh *rec;
149  tmp -= sizeof (memRecord_dh);
150  rec = (memRecord_dh *) tmp;
151  size = rec->size;
152 
153  mem_dh->curMem -= size;
154  mem_dh->freeCount += 1;
155 
156  PRIVATE_FREE (tmp);
157 END_FUNC_DH_2}
158 
159 
160 #undef __FUNC__
161 #define __FUNC__ "Mem_dhPrint"
162 void
163 Mem_dhPrint (Mem_dh m, FILE * fp, bool allPrint)
164 {
165  START_FUNC_DH_2 if (fp == NULL)
166  SET_V_ERROR ("fp == NULL");
167  if (myid_dh == 0 || allPrint)
168  {
169  double tmp;
170  fprintf (fp, "---------------------- Euclid memory report (start)\n");
171  fprintf (fp, "malloc calls = %g\n", m->mallocCount);
172  fprintf (fp, "free calls = %g\n", m->freeCount);
173  fprintf (fp, "curMem = %g Mbytes (should be zero)\n",
174  m->curMem / 1000000);
175  tmp = m->totalMem / 1000000;
176  fprintf (fp, "total allocated = %g Mbytes\n", tmp);
177  fprintf (fp,
178  "max malloc = %g Mbytes (max allocated at any point in time)\n",
179  m->maxMem / 1000000);
180  fprintf (fp, "\n");
181  fprintf (fp, "---------------------- Euclid memory report (end)\n");
182  }
183 END_FUNC_DH_2}
Definition: Mem_dh.c:60